1<?php 2/** 3 * Federated Login for DokuWiki - provider list class 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @link http://www.dokuwiki.org/plugin:fedauth 7 * @author Aoi Karasu <aoikarasu@gmail.com> 8 */ 9 10if(!defined('FA_PROVLIST_INC')) define('FA_PROVLIST_INC', __FILE__); 11 12define('PROV_LARGE', 2); 13define('PROV_SMALL', 1); 14 15/** 16 * The provider list class stores all the authorization providers information 17 * and the configuration of display and usage. 18 * 19 * REMARKS: 20 * Most of the methods in this class assumes that the arrays responsible for 21 * the providers display order are normalized. Any outside denormalization will 22 * cause an unexpected behaviour and possible unhandled exceptions. 23 * 24 * On-load normalization is planned in the nearest future. 25 * 26 * @author Aoi Karasu <aoikarasu@gmail.com> 27 */ 28class fa_providerlist { 29 30 /** 31 * All configured providers. 32 * 33 * @var array 34 * @access private 35 */ 36 var $providers = array(); 37 38 /** 39 * Display order of the large provider buttons. 40 * 41 * @var array 42 * @access private 43 */ 44 var $orderLarge = array(); 45 46 /** 47 * Display order of the small provider buttons. 48 * 49 * @var array 50 * @access private 51 */ 52 var $orderSmall = array(); 53 54 /** 55 * Name of the configuration file. 56 * 57 * @var string 58 * @access private 59 */ 60 var $cfgFile = ''; 61 62 /** 63 * Creates an instance of fa_providerlist class using specified configuration file. 64 * 65 * @param string $cfg name of the configuration file 66 * @return object fa_providerlist class instance 67 */ 68 public static function create($cfg) { 69 $instance = new self(); 70 $instance->loadFrom($cfg); 71 return $instance; 72 } 73 74 /** 75 * Loads and parses a configuration file to build the list of athorization providers. 76 * 77 * @param string $cfg name of the configuration file 78 */ 79 protected function loadFrom($cfg) { 80 $this->cfgFile = $cfg; 81 82 if (file_exists($this->cfgFile)) { 83 $fa_providers = array(); 84 $fa_order_large = array(); 85 $fa_order_small = array(); 86 87 include($this->cfgFile); 88 $this->order_large = $fa_order_large; 89 $this->order_small = $fa_order_small; 90 // TODO: normalize the order arrays (most of the methods assumes they are) 91 foreach ($fa_providers as $id => $data) { 92 $provider = fa_provider::create($id, $data); 93 $this->providers[$id] = $provider; 94 // if a provider entry is not in any of sort arrays, add it to small 95 if (!in_array($id, $this->order_large) && !in_array($id, $this->order_small)) { 96 array_push($this->order_small, $id); 97 } 98 } 99 } 100 } 101 102 /** 103 * Adds a custom authorization provider to the provider list. 104 * 105 * Note: provider id must be unique or else addition fails. 106 * 107 * @param string $id provider identifier 108 * @param string $name name of the provider 109 * @param string $url URL to the provider's authorization service 110 * @param string $large wikilink to large image 111 * @param string $small wikilink to small image 112 */ 113 public function addCustom($id, $name, $url, $large, $small) { 114 if (array_key_exists($id, $this->providers)) return 0; 115 $provider = fa_provider::createCustom($id, $name, $url, $large, $small); 116 $this->providers[$id] = $provider; 117 array_push($this->order_small, $id); 118 return $this->providers[$id]; 119 } 120 121 /** 122 * Returns the number of all configured providers. 123 * 124 * @return int number of providers 125 */ 126 public function count() { 127 return count($this->providers); 128 } 129 130 /** 131 * Returns the number of all providers set to be displayed as large buttons. 132 * 133 * @return int number of providers 134 */ 135 public function countLarge() { 136 return count($this->order_large); 137 } 138 139 /** 140 * Returns the number of all providers set to be displayed as small buttons. 141 * 142 * @return int number of providers 143 */ 144 public function countSmall() { 145 return count($this->order_small); 146 } 147 148 /** 149 * Returns the requested authorization provider object. 150 * 151 * @param string $id provider identifier 152 * @return object configured authorization provider 153 */ 154 public function get($id) { 155 return $this->providers[$id]; 156 } 157 158 /** 159 * Returns an array of all configured authorization providers. 160 * 161 * @return array all configured providers 162 */ 163 public function getAll() { 164 // NOTE: consider returning normalized array 165 return $this->providers; 166 } 167 168 /** 169 * Returns an array of the providers set to be displayed as large buttons. 170 * 171 * @return array providers to be shown as large buttons 172 */ 173 public function getLarge() { 174 $ret = array(); 175 foreach($this->order_large as $key => $val) { 176 $ret[$val] = $this->providers[$val]; 177 } 178 return $ret; 179 } 180 181 /** 182 * Returns an array of the providers set to be displayed as small buttons. 183 * 184 * @return array providers to be shown as small buttons 185 */ 186 public function getSmall() { 187 $ret = array(); 188 foreach($this->order_small as $key => $val) { 189 $ret[$val] = $this->providers[$val]; 190 } 191 return $ret; 192 } 193 194 /** 195 * Returns the XHTML of provider image choosing automatically 196 * whether it should be small or large. 197 * 198 * @param string $id provider identifier 199 * @param string $class (optional) a CSS class to use 200 * @return string rendered image XHTML 201 */ 202 public function getImageXHTML($id, $class='') { 203 $size = in_array($id, $this->order_large) ? PROV_LARGE : PROV_SMALL; 204 return $this->providers[$id]->getImageXHTML($size, $class); 205 } 206 207 /** 208 * Indicates whether a provider is first on its order list. 209 * 210 * @param string $id provider identifier 211 * @throws ErrorException provider not found in any of the order arrays 212 * @return bool true, if the provider is the first one 213 */ 214 public function isFirst($id) { 215 $src =& $this->_getOrderFor($id); 216 if (src == null) throw new ErrorException("isFirst() - item not found in any of the order arrays"); 217 $first = reset($src); 218 return $first == $id; 219 } 220 221 /** 222 * Indicates whether a provider is the last one on its order list. 223 * 224 * @param string $id provider identifier 225 * @throws ErrorException provider not found in any of the order arrays 226 * @return bool true, if the provider is the last one 227 */ 228 public function isLast($id) { 229 $src =& $this->_getOrderFor($id); 230 if (src == null) throw new ErrorException("isLast() - item not found in any of the order arrays"); 231 $last = end($src); 232 return $last == $id; 233 } 234 235 /** 236 * Moves a provider one step up in its order array. 237 * 238 * @return true, if move succeded 239 */ 240 public function moveDown($id) { 241 $src =& $this->_getOrderFor($id); 242 if (src == null) return false; 243 244 // get the position (key is integer), assumed normalized array 245 $index = array_search($id, $src); 246 247 // do movedown 248 if(count($src) > $index) { 249 array_splice($src, $index+2, 0, $src[$index]); 250 array_splice($src, $index, 1); 251 return true; 252 } 253 return false; 254 } 255 256 /** 257 * Moves a provider one step down in its order array. 258 * 259 * @return true, if move succeded 260 */ 261 public function moveUp($id) { 262 $src =& $this->_getOrderFor($id); 263 if (src == null) return false; 264 265 // get the position (key is integer), assumed normalized array 266 $index = array_search($id, $src); 267 268 // do moveup 269 if ((count($src) > $index) && ($index>0)) { 270 array_splice($src, $index-1, 0, $src[$index]); 271 array_splice($src, $index+1, 1); 272 return true; 273 } 274 return false; 275 } 276 277 /** 278 * Removes a custom authorization provider from the provider list. 279 * 280 * @param string $id provider identifier 281 */ 282 public function removeCustom($id) { 283 if (!array_key_exists($id, $this->providers)) return false; 284 if (!$this->providers[$id]->isRemovable()) return false; 285 286 unset($this->providers[$id]); 287 288 // remove entry from order array 289 $ord =& $this->_getOrderFor($id); 290 if ($ord != null) { 291 $index = array_search($id, $ord); 292 array_splice($ord, $index, 1); 293 } 294 return 1; 295 } 296 297 /** 298 * Save the authorization providers configuration back to the file it was loaded from 299 * or to a new file, if fname is supplied. 300 * 301 * @param string $user username of the user performing the save 302 */ 303 public function save($user) { 304 // create header 305 $date = date('r'); 306 $cfg = '<?php' . "\n/**\n * Federated Login Plugin - configuration file\n" 307 . " * This is an automatically generated file. Do not edit.\n" 308 . " * Run for user: $user\n * Date: $date\n */\n\n"; 309 // serialize order 310 if ($this->countLarge()) { 311 $cfg .= "\$fa_order_large = array('" . implode("','", $this->order_large) . "');\n"; 312 } 313 if ($this->countSmall()) { 314 $cfg .= "\$fa_order_small = array('" . implode("','", $this->order_small) . "');\n"; 315 } 316 $cfg .= "\n"; 317 // serialize providers 318 foreach ($this->providers as $id => $provider) { 319 $cfg .= $provider->getSerialized(); 320 } 321 file_put_contents($this->cfgFile, $cfg); 322 } 323 324 /** 325 * Changes the target configuration file the configuration is beeing saved to. 326 * 327 * @param string fname name of the new config file 328 */ 329 public function setConfigFile($fname) { 330 $this->cfgFile = $fname; 331 } 332 333 /** 334 * Toggles the size of a provider button (moves a provider id between order arrays). 335 * 336 * @param string $id provider identifier 337 * @return mixed provider button size code or false on failure 338 */ 339 public function toggleSize($id) { 340 if (in_array($id, $this->order_large)) { 341 $index = array_search($id, $this->order_large); 342 array_splice($this->order_large, $index, 1); 343 array_push($this->order_small, $id); 344 return PROV_SMALL; 345 } 346 if (in_array($id, $this->order_small)) { 347 $index = array_search($id, $this->order_small); 348 array_splice($this->order_small, $index, 1); 349 array_push($this->order_large, $id); 350 return PROV_LARGE; 351 } 352 return false; 353 } 354 355 /** 356 * Null reference helper. 357 */ 358 var $nullGuard = null; 359 360 /** 361 * Returns the reference to an order array that contains specified provider id. 362 * 363 * @param string $id provider identifier 364 * @return arrayref reference to one of the order arrays or null 365 */ 366 private function &_getOrderFor($id) { 367 if (in_array($id, $this->order_small)) { 368 return $this->order_small; 369 } 370 if (in_array($id, $this->order_large)) { 371 return $this->order_large; 372 } 373 return $this->nullGuard; 374 } 375 376} /* fa_providerlist */ 377 378/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 379