Source for file IsAuthorizedCache.class.php

Documentation is available at IsAuthorizedCache.class.php

  1. <?php
  2. /**
  3. * @since 12/20/05
  4. * @package harmoni.osid_v2.authorization
  5. *
  6. * @copyright Copyright &copy; 2005, Middlebury College
  7. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  8. *
  9. * @version $Id: IsAuthorizedCache.class.php,v 1.8 2007/09/04 20:25:38 adamfranco Exp $
  10. */
  11.  
  12. /**
  13. * The IsAuthorizedCache maintains a per-session cache of the boolean
  14. * responces to the methods isAuthorized($agent, $function, $qualifier) and
  15. * isUserAuthorized($function, $qualifier). As these are
  16. * the most common Authorization functions called, expediacy is of the
  17. * utmost importance, in which this cache plays an integral part.
  18. *
  19. * The IsAuthorizedCache is a singleton and should be accessed ONLY via:
  20. * IsAuthorizedCache::instance();
  21. *
  22. * Usage
  23. * -----
  24. * The usage of this cache falls into 2 parts:
  25. * - Queuing nodes for all-at-once AZ loading.
  26. * - Querying as to isUserAuthorized()?
  27. *
  28. * Queuing Methodology
  29. * ------------------
  30. * Ideally, all of the nodes at which AZs will be checked during a page-load will
  31. * be added to the checking queue so that only one AZ query is needed to fetch them
  32. * all. In practice the nodes needed may be queued in several chunks. The initial
  33. * implementation of this caching system will have the NodeIterator adding its
  34. * member Ids to the queue on its first member access.
  35. *
  36. * Querying Methodology
  37. * --------------------
  38. * When a call to isUserAuthorized() is made the cache is checked.
  39. * Cache Hit:
  40. * On a cache it, the result is returned.
  41. * Cache Miss:
  42. * On a cache miss the queue is checked. If the Id is in the queue, it is added to
  43. * the queue. The entire queue is then loaded and the [now cached] result is returned.
  44. *
  45. * Cache Synchronization Methodology
  46. * ---------------------------------
  47. * A table, az_node_changed, is maintained containing a timestamped list of all
  48. * nodes at which AZs may have changed. When node parentage is changed or an
  49. * Authorization is added or removed from a node, that nodeId and its descendent's
  50. * Ids are added to that table with the current timestamp.
  51. *
  52. * On page-loading, a SELECT query is made of the node_changed field where the
  53. * timestamp is greater than the cache-update time. Any nodes found have their
  54. * caches cleared and the cache-update time is set to now.
  55. *
  56. * Cache Structure
  57. * ---------------
  58. * The cache is a two-dimensional array with the outer elements being keyed by
  59. * nodeId and the inner elements being keyed by FunctionId.
  60. *
  61. * A cache hit is is made when a nodeId exists in the cache.
  62. * Only TRUE booleans should be considered positive authorization. NULL, FALSE,
  63. * and non-existant function values in a node array should be considered
  64. * unauthorized.
  65. *
  66. * @since 12/20/05
  67. * @package harmoni.osid_v2.authorization
  68. *
  69. * @copyright Copyright &copy; 2005, Middlebury College
  70. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  71. *
  72. * @version $Id: IsAuthorizedCache.class.php,v 1.8 2007/09/04 20:25:38 adamfranco Exp $
  73. */
  74. class IsAuthorizedCache {
  75. /*******************************************************
  76. * Class Methods - Instance-Creation/Singlton
  77. *********************************************************/
  78.  
  79.  
  80. /**
  81. * Get the instance of the IsAuthorizedCache.
  82. * The IsAuthorizedCache class implements the Singleton pattern. There
  83. * is only ever one instance of the IsAuthorizedCache object and it is
  84. * accessed only via the IsAuthorizedCache::instance() method.
  85. *
  86. * @return object Harmoni
  87. * @access public
  88. * @since 5/26/05
  89. * @static
  90. */
  91. function instance () {
  92. if (!defined("IsAuthorizedCache_INSTANTIATED")) {
  93. $GLOBALS['__isAuthorizedCacheInstance'] = new IsAuthorizedCache();
  94. define("IsAuthorizedCache_INSTANTIATED", true);
  95. }
  96. return $GLOBALS['__isAuthorizedCacheInstance'];
  97. }
  98.  
  99. /*******************************************************
  100. * Instance Variables
  101. *********************************************************/
  102.  
  103. /**
  104. * @var array $_agentIdStrings;
  105. * @access private
  106. * @since 12/20/05
  107. */
  108. var $_agentIdStrings;
  109. /**
  110. * An array of string Ids of nodes which should next have AZs loaded
  111. *
  112. * @var array $_queue;
  113. * @access private
  114. * @since 12/20/05
  115. */
  116. var $_queue;
  117. /**
  118. * The configuration, taken from the AuthorizationManager
  119. *
  120. * @var object ConfigurationProperties $_configuration;
  121. * @access private
  122. * @since 12/20/05
  123. */
  124. var $_configuration;
  125. /**
  126. * This is the AuthorizationCache used by the AuthorizationManager
  127. * that holds the Authorization objects. It is needed as a parameter
  128. * for the explicit Authorization constructor.
  129. *
  130. * @var object AuthorizationCache $_authorizationManagerObjectCache;
  131. * @access private
  132. * @since 12/20/05
  133. */
  134. var $_authorizationManagerObjectCache;
  135.  
  136.  
  137. /*******************************************************
  138. * Instance Methods - Instance Creation
  139. *********************************************************/
  140.  
  141. /**
  142. * The constructor, use IsAuthorizedCache::instance() to access the object.
  143. * @access public
  144. * @return void
  145. ***/
  146. function IsAuthorizedCache() {
  147. // Verify that there is only one instance of Harmoni.
  148. $backtrace = debug_backtrace();
  149. if (false && $GLOBALS['__isAuthorizedCache']
  150. || !(
  151. strtolower($backtrace[1]['class']) == 'isauthorizedcache'
  152. && $backtrace[1]['function'] == 'instance'
  153. // && $backtrace[1]['type'] == '::' // PHP 5.2.1 seems to get this wrong
  154. ))
  155. {
  156. die("\n<dl style='border: 1px solid #F00; padding: 10px;'>"
  157. ."\n\t<dt><strong>Invalid IsAuthorizedCache instantiation at...</strong></dt>"
  158. ."\n\t<dd> File: ".$backtrace[0]['file']
  159. ."\n\t\t<br/> Line: ".$backtrace[0]['line']
  160. ."\n\t</dd>"
  161. ."\n\t<dt><strong>Access IsAuthorizedCache with <em>IsAuthorizedCache::instance()</em></strong></dt>"
  162. ."\n\t<dt><strong>Backtrace:</strong></dt>"
  163. ."\n\t<dd>".printDebugBacktrace(debug_backtrace(), true)."</dd>"
  164. ."\n\t<dt><strong>PHP Version:</strong></dt>"
  165. ."\n\t<dd>".phpversion()."</dd>"
  166. ."\n</dl>");
  167. }
  168. // Initialize our paremeters
  169. $this->_queue = array();
  170. $this->_agentIdStrings = array();
  171. // get our configuration
  172. $azManager = Services::getService("AuthZ");
  173. $this->_configuration =$azManager->_configuration;
  174. $this->_authorizationManagerObjectCache =$azManager->_cache;
  175. // [Re]set up our cache if it doesn't exist or if we have a new user.
  176. if(!isset($_SESSION['__isAuthorizedCache']))
  177. $_SESSION['__isAuthorizedCache'] = array();
  178. if (!isset($_SESSION['__isAuthorizedCache']['USER'])
  179. || !isset($_SESSION['__isAuthorizedCacheAgents']['USER'])
  180. || !isset($_SESSION['__isAuthorizedCacheTime']['USER'])
  181. || $_SESSION['__isAuthorizedCacheAgents']['USER'] != implode(", ", $this->getAgentIdStringArray('USER')))
  182. {
  183. $_SESSION['__isAuthorizedCacheAgents']['USER'] = implode(", ", $this->getAgentIdStringArray('USER'));
  184. $_SESSION['__isAuthorizedCache']['USER'] = array();
  185. $_SESSION['__isAuthorizedCacheTime']['USER'] = DateAndTime::now();
  186. }
  187. // Unload any expired Node AZs
  188. $this->_synchronizeCache();
  189. }
  190. /*******************************************************
  191. * Instance Methods - Public
  192. *********************************************************/
  193.  
  194.  
  195. /**
  196. * Given a functionId and qualifierId returns true if the user is
  197. * authorized now to perform the Function with the Qualifier.
  198. *
  199. * @param object Id $functionId
  200. * @param object Id $qualifierId
  201. *
  202. * @return boolean
  203. *
  204. * @throws object AuthorizationException An exception with
  205. * one of the following messages defined in
  206. * org.osid.authorization.AuthorizationException may be thrown:
  207. * {@link }
  208. * org.osid.authorization.AuthorizationException#OPERATION_FAILED
  209. * OPERATION_FAILED}, {@link }
  210. * org.osid.authorization.AuthorizationException#PERMISSION_DENIED
  211. * PERMISSION_DENIED}, {@link }
  212. * org.osid.authorization.AuthorizationException#CONFIGURATION_ERROR
  213. * CONFIGURATION_ERROR}, {@link }
  214. * org.osid.authorization.AuthorizationException#UNIMPLEMENTED
  215. * UNIMPLEMENTED}, {@link }
  216. * org.osid.authorization.AuthorizationException#NULL_ARGUMENT
  217. * NULL_ARGUMENT}, {@link }
  218. * org.osid.authorization.AuthorizationException#UNKNOWN_ID
  219. * UNKNOWN_ID}
  220. *
  221. * @access public
  222. */
  223. function isUserAuthorized ( $functionId, $qualifierId ) {
  224. // Cache Misses will be determined in the queing methods
  225. $this->queueId($qualifierId);
  226. $this->_loadQueue('USER');
  227. // Cache hit or newly loaded cache
  228. if (isset($_SESSION['__isAuthorizedCache']
  229. ['USER']
  230. [$qualifierId->getIdString()]
  231. [$functionId->getIdString()])
  232. && true === $_SESSION['__isAuthorizedCache']
  233. ['USER']
  234. [$qualifierId->getIdString()]
  235. [$functionId->getIdString()])
  236. {
  237. return true;
  238. } else {
  239. return false;
  240. }
  241. }
  242. /**
  243. * Given an agentId, functionId, and qualifierId returns true if the agent is
  244. * authorized now to perform the Function with the Qualifier.
  245. *
  246. * @param object Id $agentId
  247. * @param object Id $functionId
  248. * @param object Id $qualifierId
  249. *
  250. * @return boolean
  251. *
  252. * @throws object AuthorizationException An exception with
  253. * one of the following messages defined in
  254. * org.osid.authorization.AuthorizationException may be thrown:
  255. * {@link }
  256. * org.osid.authorization.AuthorizationException#OPERATION_FAILED
  257. * OPERATION_FAILED}, {@link }
  258. * org.osid.authorization.AuthorizationException#PERMISSION_DENIED
  259. * PERMISSION_DENIED}, {@link }
  260. * org.osid.authorization.AuthorizationException#CONFIGURATION_ERROR
  261. * CONFIGURATION_ERROR}, {@link }
  262. * org.osid.authorization.AuthorizationException#UNIMPLEMENTED
  263. * UNIMPLEMENTED}, {@link }
  264. * org.osid.authorization.AuthorizationException#NULL_ARGUMENT
  265. * NULL_ARGUMENT}, {@link }
  266. * org.osid.authorization.AuthorizationException#UNKNOWN_ID
  267. * UNKNOWN_ID}
  268. *
  269. * @access public
  270. */
  271. function isAuthorized ($agentId, $functionId, $qualifierId ) {
  272. if (!isset($_SESSION['__isAuthorizedCache'][$agentId->getIdString()]))
  273. $_SESSION['__isAuthorizedCache'][$agentId->getIdString()] = array();
  274. // Cache Misses will be determined in the queing methods
  275. $this->queueId($qualifierId);
  276. $this->_loadQueue($agentId->getIdString());
  277. // Cache hit or newly loaded cache
  278. if (isset($_SESSION['__isAuthorizedCache']
  279. [$agentId->getIdString()]
  280. [$qualifierId->getIdString()]
  281. [$functionId->getIdString()])
  282. && true === $_SESSION['__isAuthorizedCache']
  283. [$agentId->getIdString()]
  284. [$qualifierId->getIdString()]
  285. [$functionId->getIdString()])
  286. {
  287. return true;
  288. } else {
  289. return false;
  290. }
  291. }
  292. /**
  293. * Add an Id to the Queue
  294. *
  295. * @param object Id $id
  296. * @return void
  297. * @access public
  298. * @since 12/20/05
  299. */
  300. function queueId ( $id ) {
  301. ArgumentValidator::validate($id, ExtendsValidatorRule::getRule("Id"));
  302. $this->queueIdString($id->getIdString());
  303. }
  304. /**
  305. * Add an id string to the Queue
  306. *
  307. * @param string $idString
  308. * @return void
  309. * @access public
  310. * @since 12/20/05
  311. */
  312. function queueIdString ( $idString ) {
  313. foreach (array_keys($_SESSION['__isAuthorizedCache']) as $agentKey) {
  314. if (!isset($this->_queue[$agentKey]))
  315. $this->_queue[$agentKey] = array();
  316. if ((!isset($_SESSION['__isAuthorizedCache'][$agentKey][$idString])
  317. || !isset($_SESSION['__isAuthorizedCache']
  318. [$agentKey]
  319. [$idString]
  320. ['__IMPLICIT_CACHED']))
  321. && !in_array($idString, $this->_queue[$agentKey]))
  322. {
  323. $this->_queue[$agentKey][] = $idString;
  324. }
  325. }
  326. }
  327. /**
  328. * Add an array of Ids to the Queue
  329. *
  330. * @param array $idArray An array of Id objects
  331. * @return void
  332. * @access public
  333. * @since 12/20/05
  334. */
  335. function queueIdArray ( $idArray ) {
  336. foreach (array_keys($idArray) as $key) {
  337. $this->queueId($idArray[$key]);
  338. }
  339. }
  340. /**
  341. * Add an array of id strings to the Queue
  342. *
  343. * @param array $idStringArray An array of string ids
  344. * @return void
  345. * @access public
  346. * @since 12/20/05
  347. */
  348. function queueIdStringArray ( $idStringArray ) {
  349. foreach ($idStringArray as $idString) {
  350. $this->queueIdString($idString);
  351. }
  352. }
  353. /**
  354. * Add an array of Assets to the Queue
  355. *
  356. * @param array $assetArray An array of Asset or Node objects
  357. * @return void
  358. * @access public
  359. * @since 12/20/05
  360. */
  361. function queueAssetArray ( $assetArray ) {
  362. foreach (array_keys($assetArray) as $key) {
  363. $this->queueId($assetArray[$key]->getId());
  364. }
  365. }
  366.  
  367. /*******************************************************
  368. * Instance Methods - Private
  369. *********************************************************/
  370.  
  371. /**
  372. * Answer an array of the Agent id strings that correspond to the
  373. * AgentKey passed. the agent key can be an agent id string or USER.
  374. *
  375. * @param string $agentKey
  376. * @return array
  377. * @access public
  378. * @since 5/25/06
  379. */
  380. function getAgentIdStringArray ($agentKey) {
  381. if (!isset($this->_agentIdStrings[$agentKey])) {
  382. $azManager = Services::getService("AuthZ");
  383. $idManager = Services::getService("Id");
  384. $this->_agentIdStrings[$agentKey] = array();
  385. if ($agentKey == 'USER') {
  386. // Store our current users
  387. $userIds =$azManager->_getUserIds();
  388. foreach (array_keys($userIds) as $key) {
  389. $userId =$userIds[$key];
  390. $this->_agentIdStrings['USER'][] = $userId->getIdString();
  391. $this->_agentIdStrings['USER'] = array_merge(
  392. $this->_agentIdStrings['USER'],
  393. $azManager->_getContainingGroupIdStrings($userId));
  394. }
  395. } else {
  396. $agentId =$idManager->getId($agentKey);
  397. $this->_agentIdStrings[$agentKey][] = $agentKey;
  398. $this->_agentIdStrings[$agentKey] = array_merge(
  399. $this->_agentIdStrings[$agentKey],
  400. $azManager->_getContainingGroupIdStrings($agentId));
  401. }
  402. }
  403. return $this->_agentIdStrings[$agentKey];
  404. }
  405. /**
  406. * Load all of the Authorizations for the user and cache them
  407. *
  408. * @return void
  409. * @access public
  410. * @since 11/10/05
  411. */
  412. function _loadQueue ($agentIdString) {
  413. if (!count($this->_queue[$agentIdString]))
  414. return;
  415. $dbHandler = Services::getService("DatabaseManager");
  416. $dbIndex = $this->_configuration->getProperty('database_index');
  417. $idManager = Services::getService("Id");
  418. $functions = array(); //used by Algorithm A
  419. // $timer = new Timer;
  420. // $timer->start();
  421. // $startingQueries = $dbHandler->getTotalNumberOfQueries();
  422. // Explicit AZs
  423. // Select and create all of the explicit AZs
  424. $query = new SelectQuery();
  425. $query->addColumn("*");
  426. $query->addTable("az_authorization");
  427. $agentIdStrings = $this->getAgentIdStringArray($agentIdString);
  428. foreach($agentIdStrings as $key => $val)
  429. $agentIdStrings[$key] = "'".addslashes($val)."'";
  430. $query->addWhere("fk_agent IN(".implode(", ", $agentIdStrings).")");
  431. $query->addWhere("(authorization_effective_date IS NULL OR authorization_effective_date < NOW())");
  432. $query->addWhere("(authorization_expiration_date IS NULL OR authorization_expiration_date > NOW())");
  433. // printpre(MySQL_SQLGenerator::generateSQLQuery($query));
  434. $result =$dbHandler->query(
  435. $query,
  436. $dbIndex);
  437. // Create the explicit AZs
  438. while ($result->hasMoreRows()) {
  439. $az = new HarmoniAuthorization(
  440. $result->field("authorization_id"),
  441. $idManager->getId($result->field("fk_agent")),
  442. $idManager->getId($result->field("fk_function")),
  443. $idManager->getId($result->field("fk_qualifier")),
  444. true,
  445. $this->_authorizationManagerObjectCache,
  446. $dbHandler->fromDBDate(
  447. $result->field("authorization_effective_date"),
  448. $dbIndex),
  449. $dbHandler->fromDBDate(
  450. $result->field("authorization_expiration_date"),
  451. $dbIndex));
  452. // cache in our explictAZ cache for referencing by implicit AZs
  453. $explicitAZs[$result->field("authorization_id")] =$az;
  454. // Build a list of functions for AlogrithmA to use when setting implicitAZs
  455. $functions[] = $result->field("fk_function");
  456. // Set a boolean for the AZ.
  457. if(!isset($_SESSION['__isAuthorizedCache'][$agentIdString][$result->field("fk_qualifier")]))
  458. $_SESSION['__isAuthorizedCache'][$agentIdString][$result->field("fk_qualifier")] = array();
  459. $_SESSION['__isAuthorizedCache']
  460. [$agentIdString]
  461. [$result->field("fk_qualifier")]
  462. [$result->field("fk_function")] = true;
  463. $result->advanceRow();
  464. }
  465. $result->free();
  466. /*********************************************************
  467. * Implicit AZs
  468. *********************************************************/
  469. // Algorithm A:
  470. // For this algorithm we will do a single traversal of the hierarchy
  471. // and set implicit authorization bits on the way down as we pass
  472. // explicit AZs.
  473. // $hierarchyManager = Services::getService("Hierarchy");
  474. // $hierarchies =$hierarchyManager->getHierarchies();
  475. // while ($hierarchies->hasNext()) {
  476. // $hierarchy =$hierarchies->next();
  477. // $rootNodes =$hierarchy->getRootNodes();
  478. // while ($rootNodes->hasNext()) {
  479. // $rootNode =$rootNodes->next();
  480. //
  481. // $rootNodeId =$rootNode->getId();
  482. // // print "\n<h1>Traversing from RootNode: ".$rootNodeId->getIdString()."</h1>";
  483. //
  484. // $timer2 = new Timer;
  485. // $timer2->start();
  486. // $traversal =$hierarchy->traverse(
  487. // $rootNode->getId(),
  488. // Hierarchy::TRAVERSE_MODE_DEPTH_FIRST(),
  489. // Hierarchy::TRAVERSE_DIRECTION_DOWN(),
  490. // Hierarchy::TRAVERSE_LEVELS_ALL());
  491. // $timer2->end();
  492. // printf("<br/>CacheAZ Traversal Time: %1.6f", $timer2->printTime());
  493. //
  494. // $explicitAZLevels = array();
  495. //
  496. // while ($traversal->hasNext()) {
  497. // $info =$traversal->next();
  498. // $id =$info->getNodeId();
  499. // $idString = $id->getIdString();
  500. // $level = $info->getLevel();
  501. // // printpre("<strong>$level\t$idString</strong>");
  502. //
  503. // foreach($functions as $functionId) {
  504. // if (!isset($explicitAZLevels[$functionId])) {
  505. // if (isset($_SESSION['__isAuthorizedCache'][$agentIdString][$idString][$functionId])) {
  506. // $explicitAZLevels[$functionId] = $level;
  507. // // printpre("\tFound Explicit $functionId at level $level");
  508. // }
  509. // } else {
  510. // if ($level <= $explicitAZLevels[$functionId]) {
  511. // unset($explicitAZLevels[$functionId]);
  512. // // printpre("\tUnsetting ExplicitAZ $functionId at $level");
  513. // } else {
  514. // $_SESSION['__isAuthorizedCache'][$agentIdString][$idString][$functionId] = true;
  515. // // printpre("\tSetting Implicit $functionId at level $level");
  516. // }
  517. // }
  518. // }
  519. // }
  520. // }
  521. // }
  522. // Algorithm B:
  523. // For this algorithm we want to join all of the explicit AZs to all
  524. // nodes who have the qulifier as an ancestor. These will be the implicit AZs
  525. $query = new SelectQuery();
  526. $query->addColumn("authorization_id");
  527. $query->addColumn("fk_node");
  528. $query->addTable("az_authorization");
  529. $query->addTable("node_ancestry", LEFT_JOIN, "fk_qualifier = fk_ancestor");
  530. $nodeIdStrings = $this->_queue[$agentIdString];
  531. foreach($nodeIdStrings as $key => $val)
  532. $nodeIdStrings[$key] = "'".addslashes($val)."'";
  533. $query->addWhere("fk_node IN(".implode(", ", $nodeIdStrings).")");
  534. $agentIdStrings = $this->getAgentIdStringArray($agentIdString);
  535. foreach($agentIdStrings as $key => $val)
  536. $agentIdStrings[$key] = "'".addslashes($val)."'";
  537. $query->addWhere("fk_agent IN(".implode(", ", $agentIdStrings).")");
  538. $query->addWhere("(authorization_effective_date IS NULL OR authorization_effective_date < NOW())");
  539. $query->addWhere("(authorization_expiration_date IS NULL OR authorization_expiration_date > NOW())");
  540. // printpre(MySQL_SQLGenerator::generateSQLQuery($query));
  541. $result =$dbHandler->query(
  542. $query,
  543. $this->_configuration->getProperty('database_index'));
  544. while ($result->hasMoreRows()) {
  545. $explicitAZ =$explicitAZs[$result->field("authorization_id")];
  546. $explicitFunction =$explicitAZ->getFunction();
  547. $explicitFunctionId =$explicitFunction->getId();
  548. // cache in our user AZ cache
  549. if(!isset($_SESSION['__isAuthorizedCache'][$agentIdString][$result->field("fk_node")]))
  550. $_SESSION['__isAuthorizedCache'][$agentIdString][$result->field("fk_node")] = array();
  551. $_SESSION['__isAuthorizedCache']
  552. [$agentIdString]
  553. [$result->field("fk_node")]
  554. [$explicitFunctionId->getIdString()] = true;
  555. $result->advanceRow();
  556. }
  557. $result->free();
  558. // Set flags that each Qualifier in the queue has had its implicit AZs cached.
  559. foreach ($this->_queue[$agentIdString] as $qualifierIdString) {
  560. $_SESSION['__isAuthorizedCache']
  561. [$agentIdString]
  562. [$qualifierIdString]
  563. ['__IMPLICIT_CACHED'] = true;
  564. }
  565. // $timer->end();
  566. // printf("<br/>CacheAZTime: %1.6f", $timer->printTime());
  567. // print "<br/>Num Queries: ".($dbHandler->getTotalNumberOfQueries() - $startingQueries);
  568. $this->_queue[$agentIdString] = array();
  569. // @$this->ticker++;
  570. // if ($this->ticker > 100) {
  571. // printpre($_SESSION['__isAuthorizedCache'][$agentIdString]);
  572. // exit;
  573. // }
  574. }
  575. /**
  576. * Sychronize the cache. Remove any nodes from the cache whose AZs may have
  577. * changed.
  578. *
  579. * @return void
  580. * @access public
  581. * @since 12/20/05
  582. */
  583. function _synchronizeCache () {
  584. $dbHandler = Services::getService("DBHandler");
  585. foreach (array_keys($_SESSION['__isAuthorizedCacheAgents']) as $agentIdString) {
  586. // Select the nodeIds who's authorization situation may have changed
  587. // since the cache was last synchronized. Clear these Ids from the cache.
  588. $query = new SelectQuery();
  589. $query->addTable("node");
  590. $query->setColumns(array("node_id"));
  591. $dbDate = $dbHandler->toDBDate(
  592. $_SESSION['__isAuthorizedCacheTime'][$agentIdString],
  593. $this->_configuration->getProperty('database_index'));
  594. $query->addWhere("az_node_changed > ".$dbDate);
  595. // printpre(MySQL_SQLGenerator::generateSQLQuery($query));
  596. $result =$dbHandler->query($query, $this->_configuration->getProperty('database_index'));
  597. while ($result->hasMoreRows()) {
  598. unset($_SESSION['__isAuthorizedCache'][$agentIdString][$result->field("node_id")]);
  599. $result->advanceRow();
  600. }
  601. $result->free();
  602. $_SESSION['__isAuthorizedCacheTime'][$agentIdString] = DateAndTime::now();
  603. }
  604. }
  605. /**
  606. * Update the last-changed timestamp for the node to be now so that the authorization
  607. * system can sychronize with the new value.
  608. *
  609. * @param object Id $nodeId
  610. * @return void
  611. * @access public
  612. * @since 12/20/05
  613. */
  614. function dirtyNode ( $nodeId ) {
  615. ArgumentValidator::validate($nodeId, ExtendsValidatorRule::getRule("Id"), true);
  616. $hierarchyManager = Services::getService("Hierarchy");
  617. $node =$hierarchyManager->getNode($nodeId);
  618. $hierarchy =$hierarchyManager->getHierarchyForNode($node);
  619. $dbHandler = Services::getService("DBHandler");
  620. if (isset($this->_configuration))
  621. $dbIndex = $this->_configuration->getProperty('database_index');
  622. else
  623. $dbIndex = $hierarchyManager->_configuration->getProperty('database_index');
  624. $traversalInfo =$hierarchy->traverse(
  625. $nodeId,
  626. Hierarchy::TRAVERSE_MODE_DEPTH_FIRST(),
  627. Hierarchy::TRAVERSE_DIRECTION_DOWN(),
  628. Hierarchy::TRAVERSE_LEVELS_ALL());
  629. $nodesToDirty = array();
  630. while ($traversalInfo->hasNext()) {
  631. $info =$traversalInfo->next();
  632. $nodeId =$info->getNodeId();
  633. $idString = $nodeId->getIdString();
  634. if (isset($_SESSION['__isAuthorizedCache'])) {
  635. foreach (array_keys($_SESSION['__isAuthorizedCache']) as $agentIdString) {
  636. if (isset($_SESSION['__isAuthorizedCache'][$agentIdString][$idString]))
  637. unset($_SESSION['__isAuthorizedCache'][$agentIdString][$idString]);
  638. }
  639. }
  640. $nodesToDirty[] = "'".addslashes($idString)."'";
  641. }
  642. // Update the node's az_changed time
  643. // so that it can be removed from the caches of other users during
  644. // their synchronization.
  645. $query = new UpdateQuery();
  646. $query->setTable("node");
  647. $query->setColumns(array("az_node_changed"));
  648. $query->setValues(array("NOW()"));
  649. $query->addWhere("node_id IN (".implode(", ", $nodesToDirty).")");
  650. // printpre(MySQL_SQLGenerator::generateSQLQuery($query));
  651. $queryResult =$dbHandler->query($query, $dbIndex);
  652. }
  653. /**
  654. * Unset the cache for the the user as the user has just changed.
  655. *
  656. * @return void
  657. * @access public
  658. * @since 8/7/06
  659. */
  660. function dirtyUser () {
  661. unset($this->_agentIdStrings['USER']);
  662. unset($_SESSION['__isAuthorizedCache']['USER']);
  663. $_SESSION['__isAuthorizedCache']['USER'] = array();
  664. }
  665. }
  666.  
  667. ?>

Documentation generated on Wed, 19 Sep 2007 10:24:42 -0400 by phpDocumentor 1.3.0RC3