1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8class Services_Category_Controller 9{ 10 function setUp() 11 { 12 global $prefs; 13 14 if ($prefs['feature_categories'] != 'y') { 15 throw new Services_Exception_Disabled('feature_categories'); 16 } 17 } 18 19 function action_list_categories($input) 20 { 21 global $prefs; 22 23 $parentId = $input->parentId->int(); 24 $descends = $input->descends->int(); 25 26 if (! $parentId) { 27 throw new Services_Exception_MissingValue('parentId'); 28 } 29 30 $categlib = TikiLib::lib('categ'); 31 return $categlib->getCategories(['identifier' => $parentId, 'type' => $descends ? 'descendants' : 'children']); 32 } 33 34 function action_categorize($input) 35 { 36 $categId = $input->categId->int(); 37 $objects = (array) $input->objects->none(); 38 39 $perms = Perms::get('category', $categId); 40 41 if (! $perms->add_objects) { 42 throw new Services_Exception(tr('Permission denied'), 403); 43 } 44 45 $filteredObjects = $originalObjects = $this->convertObjects($objects); 46 $util =new Services_Utilities(); 47 if (count($originalObjects) && $util->isActionPost()) { 48 //first determine if objects are already in the category 49 $categlib = TikiLib::lib('categ'); 50 $inCategory = []; 51 foreach ($originalObjects as $key => $object) { 52 $objCategories = $categlib->get_object_categories($object['type'], $object['id']); 53 if (in_array($categId, $objCategories)) { 54 $inCategory[] = $object; 55 unset($filteredObjects[$key]); 56 } 57 } 58 //provide appropriate feedback for objects already in category 59 if ($inCount = count($inCategory)) { 60 $msg = $inCount === 1 ? tr('No change made for one object already in the category') 61 : tr('No change made for %0 objects already in the category', $inCount); 62 Feedback::note($msg); 63 } 64 //now add objects to the category 65 if (count($filteredObjects)) { 66 $return = $this->processObjects('doCategorize', $categId, $filteredObjects); 67 $count = isset($return['objects']) ? count($return['objects']) : 0; 68 if ($count) { 69 $msg = $count === 1 ? tr('One object added to category') 70 : tr('%0 objects added to category', $count); 71 Feedback::success($msg); 72 } else { 73 Feedback::error(tr('No objects added to category')); 74 } 75 return $return; 76 } else { 77 //this code is reached when all objects selected were already in the category 78 return [ 79 'categId' => $categId, 80 'objects' => $objects, 81 'count' => 'unchanged' 82 ]; 83 } 84 } else { 85 return [ 86 'categId' => $categId, 87 'objects' => $objects, 88 ]; 89 } 90 } 91 92 function action_uncategorize($input) 93 { 94 $categId = $input->categId->digits(); 95 $objects = (array) $input->objects->none(); 96 97 $perms = Perms::get('category', $categId); 98 99 if (! $perms->remove_objects) { 100 throw new Services_Exception(tr('Permission denied'), 403); 101 } 102 103 $filteredObjects = $originalObjects = $this->convertObjects($objects); 104 $util =new Services_Utilities(); 105 if (count($originalObjects) && $util->isActionPost()) { 106 //first determine if objects are already not in the category 107 $categlib = TikiLib::lib('categ'); 108 $notInCategory = []; 109 foreach ($originalObjects as $key => $object) { 110 $objCategories = $categlib->get_object_categories($object['type'], $object['id']); 111 if (! in_array($categId, $objCategories)) { 112 $notInCategory[] = $object; 113 unset($filteredObjects[$key]); 114 } 115 } 116 //provide appropriate feedback for objects already not in category 117 if ($notCount = count($notInCategory)) { 118 $msg = $notCount === 1 ? tr('No change made for one object not in the category') 119 : tr('No change made for %0 objects not in the category', $notCount); 120 Feedback::note($msg); 121 } 122 //now uncategorize objects that are in the category 123 if (count($filteredObjects)) { 124 $return = $this->processObjects('doUncategorize', $categId, $filteredObjects); 125 $count = isset($return['objects']) ? count($return['objects']) : 0; 126 if ($count) { 127 $msg = $count === 1 ? tr('One object removed from category') 128 : tr('%0 objects removed from category', $count); 129 Feedback::success($msg); 130 } else { 131 Feedback::error(tr('No objects removed from category')); 132 } 133 return $return; 134 } else { 135 //this code is reached when all objects selected were already not in the category 136 return [ 137 'categId' => $categId, 138 'objects' => $objects, 139 'count' => 'unchanged' 140 ]; 141 } 142 } else { 143 return [ 144 'categId' => $categId, 145 'objects' => $objects, 146 ]; 147 } 148 } 149 150 function action_select($input) 151 { 152 $categlib = TikiLib::lib('categ'); 153 $objectlib = TikiLib::lib('object'); 154 $smarty = TikiLib::lib('smarty'); 155 156 $type = $input->type->text(); 157 $object = $input->object->text(); 158 159 $perms = Perms::get($type, $object); 160 if (! $perms->modify_object_categories) { 161 throw new Services_Exception_Denied('Not allowed to modify categories'); 162 } 163 164 $input->replaceFilter('subset', 'int'); 165 $subset = $input->asArray('subset', ','); 166 167 if ($_SERVER['REQUEST_METHOD'] == 'POST') { 168 $smarty->loadPlugin('smarty_modifier_sefurl'); 169 $name = $objectlib->get_title($type, $object); 170 $url = smarty_modifier_sefurl($object, $type); 171 $targetCategories = (array) $input->categories->int(); 172 $count = $categlib->update_object_categories($targetCategories, $object, $type, '', $name, $url, $subset, false); 173 } 174 175 $categories = $categlib->get_object_categories($type, $object); 176 return [ 177 'subset' => implode(',', $subset), 178 'categories' => array_combine( 179 $subset, 180 array_map( 181 function ($categId) use ($categories) { 182 return [ 183 'name' => TikiLib::lib('object')->get_title('category', $categId), 184 'selected' => in_array($categId, $categories), 185 ]; 186 }, 187 $subset 188 ) 189 ), 190 ]; 191 } 192 193 private function processObjects($function, $categId, $objects) 194 { 195 $tx = TikiDb::get()->begin(); 196 197 foreach ($objects as & $object) { 198 $type = $object['type']; 199 $id = $object['id']; 200 201 $object['catObjectId'] = $this->$function($categId, $type, $id); 202 } 203 204 $tx->commit(); 205 206 $categlib = TikiLib::lib('categ'); 207 $category = $categlib->get_category((int) $categId); 208 209 return [ 210 'categId' => $categId, 211 'count' => $category['objects'], 212 'objects' => $objects, 213 ]; 214 } 215 216 private function doCategorize($categId, $type, $id) 217 { 218 $categlib = TikiLib::lib('categ'); 219 return $categlib->categorize_any($type, $id, $categId); 220 } 221 222 private function doUncategorize($categId, $type, $id) 223 { 224 $categlib = TikiLib::lib('categ'); 225 if ($oId = $categlib->is_categorized($type, $id)) { 226 $result = $categlib->uncategorize($oId, $categId); 227 return $oId; 228 } 229 return 0; 230 } 231 232 private function convertObjects($objects) 233 { 234 $out = []; 235 foreach ($objects as $object) { 236 $object = explode(':', $object, 2); 237 238 if (count($object) == 2) { 239 list($type, $id) = $object; 240 $objectPerms = Perms::get($type, $id); 241 242 if ($objectPerms->modify_object_categories) { 243 $out[] = ['type' => $type, 'id' => $id]; 244 } 245 } 246 } 247 248 return $out; 249 } 250} 251