PageRenderTime 69ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/objects/segue.inc.php

https://github.com/adamfranco/segue-1.x
PHP | 2187 lines | 1464 code | 256 blank | 467 comment | 344 complexity | a4c4c3a5b28c5715a67afafd0551fbe1 MD5 | raw file
  1. <? /* $Id$ */
  2. /******************************************************************************
  3. * Segue object - basis for all other section, page, and story objects
  4. ******************************************************************************/
  5. class segue {
  6. // var $permissions = array("everyone"=>array(3=>1),"institute"=>array(3=>1));
  7. var $permissions = array();
  8. // var $editors = array("everyone","institute");
  9. var $editors = array();
  10. var $editorsToDelete = array();
  11. var $editorsToDeleteInScope = array();
  12. var $changedpermissions = 0;
  13. var $cachedPermissions = array();
  14. var $builtPermissions=0;
  15. var $id = 0;
  16. var $data = array();
  17. var $changed = array();
  18. var $fetched = array();
  19. var $fetcheddown = 0;
  20. var $fetchedup = 0;
  21. var $tobefetched = 0;
  22. var $owning_site; var $owningSiteObj; // used by all types (including site for compatibility)
  23. var $owning_section; var $owningSectionObj; // only used for pages and stories
  24. var $owning_page; var $owningPageObj; // only used for stories
  25. var $_object_arrays = array("site"=>"sections","section"=>"pages","page"=>"stories"); // used for automatic functions like setFieldDown and setVarDown
  26. var $_tables = array("site"=>"sites","section"=>"sections","page"=>"pages","story"=>"stories"); // used for getField
  27. var $_encode = array("title","header","footer","shorttext","longertext","discussions","url");
  28. var $_parse = array("header","footer","shorttext","longertext");
  29. /******************************************************************************
  30. * siteExists - checks if the site/slot already exists with a certain name $name
  31. ******************************************************************************/
  32. function siteExists($site) {
  33. $query = "
  34. SELECT site_id
  35. FROM slot INNER JOIN site
  36. ON FK_site = site_id AND slot_name='".addslashes($site)."'
  37. ";
  38. // echo $query."<br />";
  39. if (db_num_rows(db_query($query))) return 1;
  40. return 0;
  41. }
  42. /******************************************************************************
  43. * siteNameValid - checks if a user is allowed to create a site of name $name
  44. ******************************************************************************/
  45. function siteNameValid($user,$name) {
  46. return 1;
  47. }
  48. /******************************************************************************
  49. * buildObjArrayFromSites($sites) - builds an array of objects from site names
  50. ******************************************************************************/
  51. function buildObjArrayFromSites($sites) {
  52. if (!is_array($sites)) return array();
  53. $a = array();
  54. foreach ($sites as $s) {
  55. $a[$s] =& new site($s);
  56. $a[$s]->fetchSiteAtOnceForeverAndEverAndDontForgetThePermissionsAsWell_Amen(0,0,true);
  57. }
  58. return $a;
  59. }
  60. /******************************************************************************
  61. * getAllSites - returns a list of all sites owned by $user
  62. ******************************************************************************/
  63. function getAllSites($user) {
  64. $sites = array();
  65. $query = "
  66. SELECT
  67. slot_name
  68. FROM
  69. slot
  70. INNER JOIN
  71. user
  72. ON FK_owner = user_id
  73. AND
  74. user_uname = '".addslashes($user)."'
  75. ";
  76. if (db_num_rows($r = db_query($query)))
  77. while ($a = db_fetch_assoc($r)) {
  78. $sites[] = $a[slot_name];
  79. }
  80. return $sites;
  81. }
  82. /******************************************************************************
  83. * getAllSitesWhereUserIsEditor - gets all sites where $user is an editor
  84. ******************************************************************************/
  85. function getAllSitesWhereUserIsEditor($user='') {
  86. global $dbhost, $dbuser, $dbpass, $dbdb;
  87. if ($user == '') $user = $_SESSION[auser];
  88. // first, get all sites for which the user is an editor
  89. $query = "
  90. SELECT
  91. slot_name
  92. FROM
  93. slot
  94. INNER JOIN
  95. site
  96. ON slot.FK_site = site_id
  97. INNER JOIN
  98. site_editors ON (
  99. site_id = site_editors.FK_site
  100. AND
  101. site_editors_type = 'user'
  102. )
  103. INNER JOIN
  104. user ON FK_editor = user_id AND user_uname='".addslashes($user)."'
  105. WHERE
  106. slot.FK_owner != user_id
  107. ";
  108. db_connect($dbhost, $dbuser, $dbpass, $dbdb);
  109. $r = db_query($query);
  110. $ar = array();
  111. if (db_num_rows($r))
  112. while ($a = db_fetch_assoc($r)) {
  113. $ar[] = $a[slot_name];
  114. }
  115. // now, if a user is a member of any groups, get all sites for which those groups are editors
  116. $query = "
  117. SELECT
  118. slot_name
  119. FROM
  120. slot
  121. INNER JOIN
  122. site
  123. ON slot.FK_site = site_id
  124. INNER JOIN
  125. site_editors ON (
  126. site_id = site_editors.FK_site
  127. AND
  128. site_editors_type = 'ugroup'
  129. )
  130. INNER JOIN
  131. ugroup ON FK_editor = ugroup_id
  132. INNER JOIN
  133. ugroup_user ON ugroup_id = FK_ugroup
  134. INNER JOIN
  135. user ON FK_user = user_id AND user_uname='".addslashes($user)."'
  136. ";
  137. $r = db_query($query);
  138. if (db_num_rows($r))
  139. while ($a = db_fetch_assoc($r)) {
  140. $ar[] = $a[slot_name];
  141. }
  142. // the two queries will return unique values, but their union could have non-unique entries.
  143. // therefore, uniquize it.
  144. return array_unique($ar);
  145. }
  146. /******************************************************************************
  147. * getAllSitesWhereUserIsSiteLevelEditor - gets all sites where $user is an editor
  148. * Like the previous function, but selects only the sites/slots
  149. * where the user has add, edit, and delete permission on the site level
  150. ******************************************************************************/
  151. function getSiteInfoWhereUserIsSiteLevelEditor($user='') {
  152. global $dbhost, $dbuser, $dbpass, $dbdb;
  153. if ($user == '') $user = $_SESSION[auser];
  154. $userId = db_get_value("user","user_id","user_uname='".addslashes($user)."'");
  155. $query = "
  156. SELECT
  157. slot_name,
  158. (site_id IS NOT NULL) AS site_exists,
  159. slot_owner.user_uname AS owner_uname,
  160. (site_id IS NOT NULL) AS site_exists,
  161. site_title,
  162. (classgroup_id IS NOT NULL) AS is_classgroup,
  163. createdby.user_uname AS site_addedby,
  164. site_created_tstamp,
  165. editedby.user_uname AS site_editedby,
  166. site_updated_tstamp,
  167. site_activate_tstamp,
  168. site_deactivate_tstamp,
  169. ( site_active = '1'
  170. AND (site_activate_tstamp = '00000000000000'
  171. OR site_activate_tstamp < CURRENT_TIMESTAMP())
  172. AND (site_deactivate_tstamp = '00000000000000'
  173. OR site_deactivate_tstamp > CURRENT_TIMESTAMP())
  174. ) AS is_active,
  175. permission_scope_type,
  176. permission_value
  177. FROM
  178. slot
  179. INNER JOIN
  180. site ON slot.FK_site = site_id
  181. INNER JOIN
  182. user AS slot_owner ON (
  183. slot.FK_owner != '".addslashes($userId)."'
  184. AND slot.FK_owner = slot_owner.user_id
  185. )
  186. INNER JOIN
  187. site_editors ON (
  188. site_id = site_editors.FK_site
  189. AND ((site_editors_type = 'ugroup')
  190. OR (site_editors_type = 'user'
  191. AND site_editors.FK_editor = '".addslashes($userId)."'))
  192. )
  193. LEFT JOIN
  194. ugroup_user ON (
  195. site_editors_type = 'ugroup'
  196. AND site_editors.FK_editor = FK_ugroup)
  197. INNER JOIN
  198. permission ON (
  199. permission_scope_type = 'site'
  200. AND permission.FK_scope_id = site_id
  201. AND FIND_IN_SET('a', permission_value) > 0
  202. AND FIND_IN_SET('e', permission_value) > 0
  203. AND FIND_IN_SET('d', permission_value) > 0
  204. AND (permission.FK_editor = FK_ugroup
  205. OR (permission.FK_editor = site_editors.FK_editor
  206. AND permission.FK_editor = '".addslashes($userId)."'))
  207. )
  208. LEFT JOIN
  209. classgroup ON slot_name = classgroup_name
  210. INNER JOIN
  211. user AS createdby ON site.FK_createdby = createdby.user_id
  212. INNER JOIN
  213. user AS editedby ON site.FK_updatedby = editedby.user_id
  214. WHERE
  215. (site_editors_type = 'ugroup'
  216. AND ugroup_user.FK_user = '".addslashes($userId)."')
  217. OR (site_editors_type = 'user'
  218. AND site_editors.FK_editor = '".addslashes($userId)."')
  219. ";
  220. $r = db_query($query);
  221. if (db_num_rows($r))
  222. while ($a = db_fetch_assoc($r))
  223. segue::addRowToSiteInfoArray($ar, $a);
  224. return $ar;
  225. }
  226. /******************************************************************************
  227. * getSiteInfoWhereUserIsEditor
  228. * Answers an array of site information for sites where $user is an editor
  229. *
  230. * The process is as follows:
  231. * - For every site where the user or one of their groups is listed as an editor...
  232. * - Get a list of all nodes in the site.
  233. * - For every node (site, section, page, story) get the permissions that apply
  234. * to the user or one of their groups.
  235. * - Return any site-level permissions found and the site info if the user
  236. * has more than just view and discuss permissions on any node in the site.
  237. *
  238. * Note (2006-12-19, Adam Franco):
  239. * This new query using sub-selects is about 12-times faster
  240. * than the previous query. Attempts were made to reformat the query by loading the
  241. * list of appropriate permissions, then finding the site id from there, but that
  242. * proved to be slower than the query below.
  243. *
  244. *
  245. ******************************************************************************/
  246. function getSiteInfoWhereUserIsEditor($user='') {
  247. global $dbhost, $dbuser, $dbpass, $dbdb;
  248. if ($user == '')
  249. $user = $_SESSION[auser];
  250. $userId = db_get_value("user","user_id","user_uname='".addslashes($user)."'");
  251. $query = "
  252. SELECT
  253. slot_name,
  254. slot_type,
  255. owner_uname,
  256. site_exists,
  257. site_title,
  258. is_classgroup,
  259. site_addedby,
  260. site_created_tstamp,
  261. site_editedby,
  262. site_updated_tstamp,
  263. site_activate_tstamp,
  264. site_deactivate_tstamp,
  265. ( site_active = '1'
  266. AND (site_activate_tstamp = '0000-00-00 00:00:00'
  267. OR site_activate_tstamp < CURRENT_TIMESTAMP())
  268. AND (site_deactivate_tstamp = '0000-00-00 00:00:00'
  269. OR site_deactivate_tstamp > CURRENT_TIMESTAMP())
  270. ) AS is_active,
  271. editor_id,
  272. permission_scope_type,
  273. permission_value
  274. FROM
  275. (SELECT
  276. slot_name,
  277. slot_type,
  278. slot_owner.user_uname AS owner_uname,
  279. (site_id IS NOT NULL) AS site_exists,
  280. site_title,
  281. (classgroup_id IS NOT NULL) AS is_classgroup,
  282. createdby.user_uname AS site_addedby,
  283. site_created_tstamp,
  284. editedby.user_uname AS site_editedby,
  285. site_updated_tstamp,
  286. site_activate_tstamp,
  287. site_deactivate_tstamp,
  288. site_active,
  289. site_id,
  290. section_id,
  291. page_id,
  292. story_id,
  293. site_editors.FK_editor AS editor_id
  294. FROM
  295. slot
  296. INNER JOIN
  297. site ON slot.FK_site = site_id
  298. INNER JOIN
  299. user AS slot_owner ON (
  300. slot.FK_owner = slot_owner.user_id
  301. AND slot.FK_owner != '".addslashes($userId)."'
  302. )
  303. INNER JOIN
  304. site_editors ON (
  305. site_id = site_editors.FK_site
  306. AND ((site_editors_type = 'ugroup')
  307. OR (site_editors_type = 'user'
  308. AND site_editors.FK_editor = '".addslashes($userId)."'))
  309. )
  310. LEFT JOIN
  311. ugroup_user ON (
  312. site_editors_type = 'ugroup'
  313. AND site_editors.FK_editor = FK_ugroup)
  314. LEFT JOIN
  315. section ON section.FK_site = site_id
  316. LEFT JOIN
  317. page ON page.FK_section = section_id
  318. LEFT JOIN
  319. story ON story.FK_page = page_id
  320. LEFT JOIN
  321. classgroup ON slot_name = classgroup_name
  322. LEFT JOIN
  323. user AS createdby ON site.FK_createdby = createdby.user_id
  324. LEFT JOIN
  325. user AS editedby ON site.FK_updatedby = editedby.user_id
  326. WHERE
  327. (site_editors_type = 'ugroup'
  328. AND ugroup_user.FK_user = '".addslashes($userId)."')
  329. OR (site_editors_type = 'user'
  330. AND site_editors.FK_editor = '".addslashes($userId)."')
  331. ) AS tmp_sites
  332. INNER JOIN
  333. permission ON (
  334. (permission.FK_editor = editor_id)
  335. AND ((permission_scope_type = 'site'
  336. AND permission.FK_scope_id = site_id)
  337. OR (permission_scope_type = 'section'
  338. AND permission.FK_scope_id = section_id)
  339. OR (permission_scope_type = 'page'
  340. AND permission.FK_scope_id = page_id)
  341. OR (permission_scope_type = 'story'
  342. AND permission.FK_scope_id = story_id))
  343. AND (FIND_IN_SET('a', permission_value) > 0
  344. OR FIND_IN_SET('e', permission_value) > 0
  345. OR FIND_IN_SET('d', permission_value) > 0)
  346. )
  347. GROUP BY
  348. slot_name,
  349. permission_value
  350. ORDER BY
  351. slot_name
  352. ";
  353. $r = db_query($query);
  354. if (db_num_rows($r)) {
  355. while ($a = db_fetch_assoc($r))
  356. segue::addRowToSiteInfoArray($ar, $a);
  357. }
  358. return $ar;
  359. }
  360. /******************************************************************************
  361. * getSiteInfoWhereUserIsEditor
  362. * Answers an array of site information for sites where $user is an editor
  363. *
  364. ******************************************************************************/
  365. function getSiteInfoWhereUserOwner($user='') {
  366. global $dbhost, $dbuser, $dbpass, $dbdb;
  367. if ($user == '') $user = $_SESSION[auser];
  368. $query = "
  369. SELECT
  370. slot_name,
  371. slot_type,
  372. slot_owner.user_uname AS owner_uname,
  373. (site_id IS NOT NULL) AS site_exists,
  374. site_title,
  375. (classgroup_id IS NOT NULL) AS is_classgroup,
  376. createdby.user_uname AS site_addedby,
  377. site_created_tstamp,
  378. editedby.user_uname AS site_editedby,
  379. site_updated_tstamp,
  380. site_activate_tstamp,
  381. site_deactivate_tstamp,
  382. ( site_active = '1'
  383. AND (site_activate_tstamp = '00000000000000'
  384. OR site_activate_tstamp < CURRENT_TIMESTAMP())
  385. AND (site_deactivate_tstamp = '00000000000000'
  386. OR site_deactivate_tstamp > CURRENT_TIMESTAMP())
  387. ) AS is_active
  388. FROM
  389. slot
  390. INNER JOIN
  391. user AS slot_owner ON (
  392. slot.FK_owner = slot_owner.user_id
  393. AND
  394. slot_owner.user_uname = '".addslashes($user)."'
  395. )
  396. INNER JOIN
  397. site ON slot.FK_site = site_id
  398. INNER JOIN
  399. user AS createdby ON site.FK_createdby = createdby.user_id
  400. INNER JOIN
  401. user AS editedby ON site.FK_updatedby = editedby.user_id
  402. LEFT JOIN
  403. classgroup ON slot_name = classgroup_name
  404. GROUP BY
  405. slot_name
  406. ";
  407. $r = db_query($query);
  408. if (db_num_rows($r)) {
  409. while ($a = db_fetch_assoc($r))
  410. segue::addRowToSiteInfoArray($ar, $a);
  411. }
  412. return $ar;
  413. }
  414. function addRowToSiteInfoArray( &$infoArray, &$a ) {
  415. if (!isset($infoArray[$a['slot_name']])) {
  416. $infoArray[$a['slot_name']] = array();
  417. $infoArray[$a['slot_name']]['slot_name'] = $a['slot_name'];
  418. $infoArray[$a['slot_name']]['slot_type'] = $a['slot_type'];
  419. $infoArray[$a['slot_name']]['slot_owner'] = $a['owner_uname'];
  420. $infoArray[$a['slot_name']]['site_exists'] = ($a['site_exists'] == '1')?true:false;
  421. $infoArray[$a['slot_name']]['site_title'] = stripslashes($a['site_title']);
  422. $infoArray[$a['slot_name']]['is_classgroup'] = ($a['is_classgroup'] == '1')?true:false;
  423. $infoArray[$a['slot_name']]['site_addedby'] = $a['site_addedby'];
  424. $infoArray[$a['slot_name']]['site_added_timestamp'] = $a['site_created_tstamp'];
  425. $infoArray[$a['slot_name']]['site_editedby'] = $a['site_editedby'];
  426. $infoArray[$a['slot_name']]['site_edited_timestamp'] = $a['site_updated_tstamp'];
  427. $infoArray[$a['slot_name']]['activatedate'] = $a['site_activate_tstamp'];
  428. $infoArray[$a['slot_name']]['deactivatedate'] = $a['site_deactivate_tstamp'];
  429. $infoArray[$a['slot_name']]['site_active'] = ($a['is_active'] == '1')?true:false;
  430. $infoArray[$a['slot_name']]['hasSitePermissionV'] = false;
  431. $infoArray[$a['slot_name']]['hasSitePermissionA'] = false;
  432. $infoArray[$a['slot_name']]['hasSitePermissionE'] = false;
  433. $infoArray[$a['slot_name']]['hasSitePermissionD'] = false;
  434. $infoArray[$a['slot_name']]['hasSitePermissionDI'] = false;
  435. $infoArray[$a['slot_name']]['hasPermissionDownV'] = false;
  436. $infoArray[$a['slot_name']]['hasPermissionDownA'] = false;
  437. $infoArray[$a['slot_name']]['hasPermissionDownE'] = false;
  438. $infoArray[$a['slot_name']]['hasPermissionDownD'] = false;
  439. $infoArray[$a['slot_name']]['hasPermissionDownDI'] = false;
  440. }
  441. if (ereg('v', $a['permission_value']) !== FALSE) {
  442. $infoArray[$a['slot_name']]['hasPermissionDownV'] = true;
  443. if ($a['permission_scope_type'] == 'site')
  444. $infoArray[$a['slot_name']]['hasSitePermissionV'] = true;
  445. }
  446. if (ereg('a', $a['permission_value']) !== FALSE) {
  447. $infoArray[$a['slot_name']]['hasPermissionDownA'] = true;
  448. if ($a['permission_scope_type'] == 'site')
  449. $infoArray[$a['slot_name']]['hasSitePermissionA'] = true;
  450. }
  451. if (ereg('e', $a['permission_value']) !== FALSE) {
  452. $infoArray[$a['slot_name']]['hasPermissionDownE'] = true;
  453. if ($a['permission_scope_type'] == 'site')
  454. $infoArray[$a['slot_name']]['hasSitePermissionE'] = true;
  455. }
  456. if (ereg('d([^i]*)', $a['permission_value']) !== FALSE) {
  457. $infoArray[$a['slot_name']]['hasPermissionDownD'] = true;
  458. if ($a['permission_scope_type'] == 'site')
  459. $infoArray[$a['slot_name']]['hasSitePermissionD'] = true;
  460. }
  461. if (ereg('di', $a['permission_value']) !== FALSE) {
  462. $infoArray[$a['slot_name']]['hasPermissionDownDI'] = true;
  463. if ($a['permission_scope_type'] == 'site')
  464. $infoArray[$a['slot_name']]['hasSitePermissionDI'] = true;
  465. }
  466. }
  467. /******************************************************************************
  468. * getAllValues - returns all values of $name in $scope in the current tree
  469. ******************************************************************************/
  470. function getAllValues($scope,$name) {
  471. if (!$this->fetcheddown) $this->fetchDown();
  472. $class = get_class($this);
  473. $ar = $this->_object_arrays[$class];
  474. // print "getting all values for $name in $class ".$this->getField("title")." with scope $scope<br />";
  475. if ($class==$scope) {
  476. if (($n = $this->getField($name)) != "")
  477. return array($n);
  478. else return array();
  479. }
  480. if ($ar) {
  481. $a = array();
  482. $oa = &$this->$ar;
  483. if ($oa) {
  484. foreach ($oa as $i=>$o) {
  485. // print "doing $i in $ar...<br />";
  486. $a = array_merge($a,$oa[$i]->getAllValues($scope,$name));
  487. }
  488. }
  489. }
  490. return $a;
  491. }
  492. function fetchData() {
  493. if ($fetched) return $this->data;
  494. else return 0;
  495. }
  496. function setData($data) {
  497. error("::setData() -- this function should not be used!");
  498. if (is_array($data)) {
  499. $this->data = $data;
  500. $this->changed = 1;
  501. $this->parseMediaTextForEdit("header");
  502. $this->parseMediaTextForEdit("footer");
  503. $this->parseMediaTextForEdit("shorttext");
  504. $this->parseMediaTextForEdit("longertext");
  505. }
  506. }
  507. /******************************************************************************
  508. * getField - Will return the value of a field in the data array.
  509. * $field should be the name of the field in the object, not the database
  510. *
  511. * If the value of the field has not yet been fetched from the database,
  512. * it is fetched from the database, otherwise it is simply returned from
  513. * the data array.
  514. *
  515. * Each class that extends segue has the following properties:
  516. *
  517. * An associative array called _datafields that associates the object
  518. * field name to a database join syntax and a database field name or pair of names.
  519. *
  520. * An array called _encode that holds the names of fields that need to
  521. * have slashes added and urlencoding to save them into the database
  522. ******************************************************************************/
  523. function getField ($field) {
  524. global $dbuser, $dbpass, $dbdb, $dbhost;
  525. if (ereg("^l%",$field))
  526. return $this->data[$field];
  527. if ($this->tobefetched && !$this->fetched[$field] && $this->id) { // we haven't allready gotten this data
  528. // and this object is in the database.
  529. // print "<pre>".get_class($this)." --$field---\n";
  530. // print_r ($this->_datafields[$field][1]);
  531. // print_r($this);
  532. // print "</pre>";
  533. // echo "<br />HERE: ".$field."<br />";
  534. $query = "
  535. SELECT
  536. ".implode(",",$this->_datafields[$field][1])."
  537. FROM
  538. ".$this->_datafields[$field][0]."
  539. WHERE
  540. ".$this->_table."_id=".$this->id."
  541. ORDER BY
  542. ".$this->_datafields[$field][2]."
  543. ";
  544. /* print $query; */
  545. if ($debug)
  546. print "-----------beginning---------$field<br /><pre>".$query;
  547. db_connect($dbhost,$dbuser,$dbpass, $dbdb);
  548. $r = db_query($query);
  549. if ($debug) {
  550. print mysql_error()."<br />Numrows = ".db_num_rows($r);
  551. print "\n\nresult arrays:\n";
  552. }
  553. if (!db_num_rows($r)) { // if we get no results
  554. if (in_array($field,$this->_object_arrays)) {
  555. // return an empty array
  556. $this->data[$field] = array();
  557. } else {
  558. return false;
  559. }
  560. }
  561. $valarray = array();
  562. while($a = db_fetch_assoc($r)) {
  563. // print_r($a);
  564. if (count($this->_datafields[$field][1]) == 1) {
  565. // We just want a single value
  566. $val = $a[$this->_datafields[$field][1][0]];
  567. $key = 0;
  568. } else {
  569. // we want a pair of values
  570. $val = $a[$this->_datafields[$field][1][0]];
  571. $key = $a[$this->_datafields[$field][1][1]];
  572. }
  573. // Decode this value if it is a member of _encode
  574. if (in_array($field,$this->_encode))
  575. $val = stripslashes(urldecode($val));
  576. if (count($this->_datafields[$field][1]) == 1) {
  577. $valarray[] = $val;
  578. } else {
  579. $valarray[$key] = $val;
  580. }
  581. /* print "<br />key = $key \nval = $val \nvalarray =\n"; */
  582. // print_r($valarray);
  583. }
  584. // only object_arrays should really be returning arrays to the data array.
  585. if (count($valarray) == 1 && !in_array($field,$this->_object_arrays))
  586. $this->data[$field] = $valarray[0];
  587. else
  588. $this->data[$field] = $valarray;
  589. $this->fetched[$field] = 1;
  590. if ($debug) {
  591. print "Valarray: ";
  592. print_r($valarray);
  593. print "\nInArray: \n$field";
  594. print_r($_object_arrays);
  595. print "<br />Is object?: ".((in_array($field,$this->_object_arrays))?"TRUE":"FALSE");
  596. print "</pre>----------end------------$field<br />";
  597. }
  598. }
  599. return $this->data[$field];
  600. }
  601. function fetchAllFields() {
  602. foreach ($this->_datafields as $key => $val) {
  603. $this->getField($key);
  604. }
  605. }
  606. function setField($name,$value) {
  607. $this->data[$name] = $value;
  608. $this->changed[$name] = 1;
  609. if ($name == "footer" || $name == "header" || $name == "shorttext" || $name == "longertext") {
  610. $this->parseMediaTextForEdit($name);
  611. }
  612. }
  613. function setFieldDown($name,$value) {
  614. if (!$this->fetcheddown) $this->fetchDown();
  615. $class=get_class($this);
  616. $ar = $this->_object_arrays[$class];
  617. $this->setField($name,$value);
  618. if ($ar) {
  619. $a = &$this->$ar;
  620. if ($a) {
  621. foreach ($a as $i=>$o) {
  622. $a[$i]->setFieldDown($name,$value);
  623. }
  624. }
  625. }
  626. }
  627. /* function setSiteNameDown($name) { */
  628. /* // if (!$this->fetcheddown) $this->fetchDown(); */
  629. /* $class=get_class($this); */
  630. /* $ar = $this->_object_arrays[$class]; */
  631. /* $this->owning_site = $name; */
  632. /* if ($class == "site") { */
  633. /* $this->name = $name; */
  634. /* $this->setField("name",$name); */
  635. /* } else { */
  636. /* $this->setField("site_id",$name); */
  637. /* } */
  638. /* if ($ar) { */
  639. /* $a = &$this->$ar; */
  640. /* foreach ($a as $i=>$o) { */
  641. /* $a[$i]->setSiteNameDown($name); */
  642. /* } */
  643. /* } */
  644. /* } */
  645. /******************************************************************************
  646. * copyObj - Copies an object to a new parent
  647. ******************************************************************************/
  648. function copyObj(&$newParent,$removeOrigional=1,$keepaddedby=0, $copyDiscussions=TRUE) {
  649. $_a = array("site"=>3,"section"=>2,"page"=>1,"story"=>0);
  650. // check that the newParent can be a parent
  651. $thisClass = get_class($this);
  652. $parentClass = get_class($newParent);
  653. /* print $this->id."$thisClass - $parentClass<br />"; */
  654. if (!($_a[$parentClass]-1 == $_a[$thisClass])) return 0;
  655. $this->fetchDown(1);
  656. /* print "<br /><br />Copying $thisClass ".$this->getField("title")." <br />"; */
  657. if ($thisClass == 'section') {
  658. $owning_site = $newParent->name;
  659. $this->id = 0; // createSQLArray uses this to tell if we are inserting or updating
  660. $this->insertDB(1, $owning_site, $removeOrigional, $keepaddedby, $copyDiscussions);
  661. }
  662. if ($thisClass == 'page') {
  663. $owning_site = $newParent->owning_site;
  664. $owning_section = $newParent->id;
  665. $this->id = 0; // createSQLArray uses this to tell if we are inserting or updating
  666. $this->insertDB(1, $owning_site, $owning_section, $removeOrigional, $keepaddedby, $copyDiscussions);
  667. }
  668. if ($thisClass == 'story') {
  669. $record_tags = get_record_tags($this->id);
  670. $owning_site = $newParent->owning_site;
  671. $owning_section = $newParent->owning_section;
  672. $owning_page = $newParent->id;
  673. $this->id = 0; // createSQLArray uses this to tell if we are inserting or updating
  674. /* print "insertDB: 1,$owning_site,$owning_section,$owning_page,$keepaddedby<br />"; */
  675. $this->insertDB(1, $owning_site, $owning_section, $owning_page, $removeOrigional, $keepaddedby, $copyDiscussions, $record_tags);
  676. }
  677. /* print_r($newParent); */
  678. return 1;
  679. }
  680. /******************************************************************************
  681. * getMediaIDs - returns an array of media ids found in a string
  682. ******************************************************************************/
  683. function getMediaIDs($field) {
  684. $string = stripslashes($this->getField($field));
  685. $ids = array();
  686. $string = explode("####",$string);
  687. for ($i=1; $i<count($string); $i=$i+2) {
  688. $ids[] = $string[$i];
  689. }
  690. return $ids;
  691. }
  692. /******************************************************************************
  693. * replaceMediaIDs - searches for and replaces each id in the string
  694. ******************************************************************************/
  695. function replaceMediaIDs($ids,$field,$newsite) {
  696. $string = $this->getField($field);
  697. foreach ($ids as $origID) {
  698. $newID = copy_media($origID,$newsite);
  699. $string = str_replace("####$origID####","####$newID####",$string);
  700. }
  701. $this->setField($field,$string);
  702. }
  703. /******************************************************************************
  704. * ACTIVATE/DEACTIVATE FUNCTIONS
  705. *
  706. * these functions handle de/activate dates in forms
  707. * - initFormDates() must be called upon edit session initialization
  708. * - outputDateForm() must be called where the HTML form data should be printed
  709. * - handleFormDates() must be called where all POST/GET data is processed
  710. ******************************************************************************/
  711. /******************************************************************************
  712. * handleFormDates - checks form fields for new de/activate dates and subsequently
  713. * sets the correct $_SESSION[settings][] variables
  714. ******************************************************************************/
  715. function handleFormDates() {
  716. // initialize the session vars.. if needed
  717. if (!isset($_SESSION[settings][activateyear]) || !isset($_SESSION[settings][deactivateyear])) {
  718. $this->initFormDates();
  719. }
  720. if ($_REQUEST[activateyear] != "") $_SESSION[settings][activateyear] = $_REQUEST[activateyear];
  721. if ($_REQUEST[activatemonth] != "") $_SESSION[settings][activatemonth] = $_REQUEST[activatemonth];
  722. if ($_REQUEST[activateday] != "") $_SESSION[settings][activateday] = $_REQUEST[activateday];
  723. if ($_REQUEST[deactivateyear] != "") $_SESSION[settings][deactivateyear] = $_REQUEST[deactivateyear];
  724. if ($_REQUEST[deactivatemonth] != "") $_SESSION[settings][deactivatemonth] = $_REQUEST[deactivatemonth];
  725. if ($_REQUEST[deactivateday] != "") $_SESSION[settings][deactivateday] = $_REQUEST[deactivateday];
  726. if ($_REQUEST[setformdates]) {
  727. if (/* !$_REQUEST[link] && */$_REQUEST[activatedate]) {
  728. $_SESSION[settings][activatedate] = 1;
  729. $this->setActivateDate($_REQUEST[activateyear],$_REQUEST[activatemonth],$_REQUEST[activateday]);
  730. } else {
  731. $_SESSION[settings][activatedate] = 0;
  732. $this->setActivateDate(-1);
  733. }
  734. if (/* !$_REQUEST[link] && */$_REQUEST[deactivatedate]) {
  735. $_SESSION[settings][deactivatedate] = 1;
  736. $this->setDeactivateDate($_REQUEST[deactivateyear],$_REQUEST[deactivatemonth],$_REQUEST[deactivateday]);
  737. } else {
  738. $_SESSION[settings][deactivatedate] = 0;
  739. $this->setDeactivateDate(-1);
  740. }
  741. }
  742. }
  743. /******************************************************************************
  744. * outputDateForm - outputs the HTML de/activate date form to be handled by above
  745. ******************************************************************************/
  746. function outputDateForm() {
  747. global $months, $months_values;
  748. // print_r($_SESSION[settings][activatedate]);
  749. printc("<input type='hidden' name='setformdates' value='1' />");
  750. printc("<table>");
  751. printc("<tr><td align='right'>");
  752. printc("Activate date:</td><td><input type='checkbox' name='activatedate' value='1'".(($_SESSION[settings][activatedate])?" checked='checked'":"")." /> <select name='activateday'>");
  753. for ($i=1;$i<=31;$i++) {
  754. printc("<option" . (($_SESSION[settings][activateday] == $i)?" selected":"") . ">".$i."\n");
  755. }
  756. printc("</select>");
  757. printc("<select name='activatemonth'>");
  758. for ($i=1; $i<13; $i++) {
  759. printc("<option value='$i'" . (($_SESSION[settings][activatemonth] == $i)?" selected":"") . ">".$months[$i-1]."\n");
  760. }
  761. printc("</select>\n<select name='activateyear'>");
  762. $curryear = date("Y");
  763. for ($i=$curryear; $i <= ($curryear+5); $i++) {
  764. printc("<option" . (($_SESSION[settings][activateyear] == $i)?" selected":"") . ">$i\n");
  765. }
  766. printc("</select>");
  767. printc("</td></tr>");
  768. printc("<tr><td align='right'>");
  769. printc("Deactivate date:</td><td><input type='checkbox' name='deactivatedate' value='1'".(($_SESSION[settings][deactivatedate])?" checked='checked'":"")." /> <select name='deactivateday'>");
  770. for ($i=1;$i<=31;$i++) {
  771. printc("<option" . (($_SESSION[settings][deactivateday] == $i)?" selected":"") . ">".$i."\n");
  772. }
  773. printc("</select>\n");
  774. printc("<select name='deactivatemonth'>");
  775. for ($i=1; $i<13; $i++) {
  776. printc("<option value='$i'" . (($_SESSION[settings][deactivatemonth] == $i)?" selected":"") . ">".$months[$i-1]."\n");
  777. }
  778. printc("</select>\n<select name='deactivateyear'>");
  779. for ($i=$curryear; $i <= ($curryear+5); $i++) {
  780. printc("<option" . (($_SESSION[settings][deactivateyear] == $i)?" selected":"") . ">$i\n");
  781. }
  782. printc("</select>");
  783. printc("</td></tr></table>");
  784. }
  785. /******************************************************************************
  786. * initFormDates - initializes necessary session vars for form date handling
  787. ******************************************************************************/
  788. function initFormDates() {
  789. $_SESSION[settings][activateyear] = "0000";
  790. $_SESSION[settings][activatemonth] = "00";
  791. $_SESSION[settings][activateday] = "00";
  792. $_SESSION[settings][activatedate] = 0;
  793. $_SESSION[settings][deactivateyear] = "0000";
  794. $_SESSION[settings][deactivatemonth] = "00";
  795. $_SESSION[settings][deactivateday] = "00";
  796. $_SESSION[settings][deactivatedate] = 0;
  797. list($_SESSION[settings][activateyear],$_SESSION[settings][activatemonth],$_SESSION[settings][activateday]) = explode("-",$this->getField("activatedate"));
  798. list($_SESSION[settings][deactivateyear],$_SESSION[settings][deactivatemonth],$_SESSION[settings][deactivateday]) = explode("-",$this->getField("deactivatedate"));
  799. // $_SESSION[settings][activatemonth]-=1;
  800. // $_SESSION[settings][deactivatemonth]-=1;
  801. /* echo $this->getField("activatedate")."<br />"; */
  802. $_SESSION[settings][activatedate]=($this->getField("activatedate")=='0000-00-00')?0:1;
  803. $_SESSION[settings][deactivatedate]=($this->getField("deactivatedate")=='0000-00-00')?0:1;
  804. }
  805. function setActivateDate($year,$month=0,$day=0) {
  806. // test to see if it's a valid date
  807. if ($year == -1) { // unset field
  808. $this->setField("activatedate","0000-00-00");
  809. return true;
  810. }
  811. if (!checkdate($month,$day,$year)) {
  812. error("The activate date you entered is invalid. It has not been set.");
  813. return false;
  814. }
  815. if ($month < 10) {
  816. $month = "0".$month;
  817. }
  818. if ($day < 10) {
  819. $day = "0".$day;
  820. }
  821. $this->setField("activatedate",$year."-".$month."-".$day);
  822. return true;
  823. }
  824. function setDeactivateDate($year,$month=0,$day=0) {
  825. // test to see if it's a valid date
  826. if ($year == -1) { // unset field
  827. $this->setField("deactivatedate","0000-00-00");
  828. return true;
  829. }
  830. if (!checkdate($month,$day,$year)) {
  831. error("The deactivate date you entered is invalid. It has not been set.");
  832. return false;
  833. }
  834. if ($month < 10) {
  835. $month = "0".$month;
  836. }
  837. if ($day < 10) {
  838. $day = "0".$day;
  839. }
  840. $this->setField("deactivatedate",$year."-".$month."-".$day);
  841. return true;
  842. }
  843. /******************************************************************************
  844. * cropString - crops a string to an appropriate length and adds elipses if
  845. * nessisary.
  846. ******************************************************************************/
  847. function cropString ($string, $maxChars) {
  848. $length = strlen($string);
  849. if ($length > $maxChars) {
  850. $length = $maxChars-3;
  851. $string = substr($string,0,$length)."...";
  852. }
  853. return $string;
  854. }
  855. /******************************************************************************
  856. * parseMediaTextForEdit - replaces ####<id>#### with appropriate filename info
  857. * -> used for inline images from the media library in text
  858. ******************************************************************************/
  859. function parseMediaTextForEdit($field) {
  860. if (!$this->getField("$field")) return false;
  861. $this->data[$field] = ereg_replace("src=('{0,1})####('{0,1})","####",$this->getField($field));
  862. $textarray1 = explode("####", $this->getField($field));
  863. if (count($textarray1) > 1) {
  864. for ($i=1; $i < count($textarray1); $i+=2) {
  865. $id = $textarray1[$i];
  866. $filename = db_get_value("media","media_tag","media_id='".addslashes($id)."'");
  867. $query = "
  868. SELECT
  869. slot_name
  870. FROM
  871. media
  872. INNER JOIN
  873. site ON media.FK_site = site_id
  874. INNER JOIN
  875. slot ON site_id = slot.FK_site
  876. WHERE
  877. media_id = '".addslashes($id)."'
  878. ";
  879. $a = db_fetch_assoc(db_query($query));
  880. $dir = $a[slot_name];
  881. $filepath = $uploadurl."/".$dir."/".$filename;
  882. $textarray1[$i] = "&&&& src='".$filepath."' @@@@".$id."@@@@ &&&&";
  883. }
  884. $this->data[$field] = implode("",$textarray1);
  885. }
  886. }
  887. /******************************************************************************
  888. * parseMediaTextForDB - does the exact opposite of above
  889. ******************************************************************************/
  890. function parseMediaTextForDB($field) {
  891. if (!$this->getField($field)) return false;
  892. $textarray1 = explode("&&&&", $this->getField($field));
  893. if (count($textarray1) > 1) {
  894. for ($i=1; $i<count($textarray1); $i=$i+2) {
  895. $textarray2 = explode("@@@@", $textarray1[$i]);
  896. $id = $textarray2[1];
  897. $textarray1[$i] = "src='####".$id."####'";
  898. }
  899. $this->data[$field] = implode("",$textarray1);
  900. }
  901. }
  902. /******************************************************************************
  903. * PERMISSIONS FUNCTIONS
  904. *
  905. * these functions handle part-specific permissions
  906. * isEditor($user) checks if $user is an editor for this part
  907. * addEditor($e) adds $e as an editor with default permissions (view only)
  908. * delEditor($e) removes all of $e's site permissions (ALL OF THEM)
  909. * getEditors() returns an array of editors for the site
  910. * setPermissions($p) set permissions to $p (a permission-formatted array)
  911. * getPermissions() returns a permission-formatted array of permissions
  912. * clearPermissions() flags all editor's scope-specific permissions to be removed
  913. * setUserPermissions($user,$add,$edit,$del,$view,$discuss)
  914. * sets $user's permissions to values of parameters (0 or 1)
  915. * setUserPermissionsFromArray($user,$p)
  916. * sets $user's permissions from permission-formatted array $p
  917. * buildPermissionsArray()
  918. * builds a permission-formatted array from the database
  919. * updatePermissionsDB()
  920. * updates the permissions database to reflect changes made above
  921. * canview($user) returns true/false depending on whether $user can view
  922. * this part of the site. takes into account de/activate dates
  923. * and active flag
  924. * hasPermission($perms,$user)
  925. * takes a formatted string $perms (ex, 'add and (edit or delete)')
  926. * and returns true/false if $user has those permissions
  927. * hasPermissionDown($perms,$user)
  928. * checks if someone has $perms anywhere down the line
  929. ******************************************************************************/
  930. function isEditor($user='') {
  931. if ($user=='')
  932. $user=$_SESSION[auser];
  933. if ($user == 'everyone' || $user == 'institute')
  934. return FALSE;
  935. if (!$this->builtPermissions && $this->id) $this->buildPermissionsArray();
  936. $this->fetchUp();
  937. $owner = $this->owningSiteObj->owner;
  938. /* print "owner: $owner"; */
  939. if (strtolower($user) == strtolower($owner)) return 1;
  940. $toCheck = array(strtolower($user));
  941. $toCheck = array_merge($toCheck,$this->returnEditorOverlap(getuserclasses($user,"all")));
  942. $toCheck = array_merge($toCheck, getusergroups($user,"all"));
  943. $toCheck = array_unique($toCheck);
  944. // printpre("-----------------------------\nDebugging:");
  945. // printpre(__FILE__.": ".__LINE__);
  946. // printpre($toCheck);
  947. // printpre($this->editors);
  948. // printpre("-----------------------------");
  949. foreach ($this->editors as $e) {
  950. if (in_array($e,$toCheck)) return 1;
  951. }
  952. return 0;
  953. }
  954. function addEditor($e) {
  955. /* print "<br />Adding editor $e<br />"; */
  956. // if ($e == 'institute' || $e == 'everyone') return false; // With the new permissions structure, this may be unwanted.
  957. if ($_SESSION[auser] == $e) { error("You do not need to add yourself as an editor."); return false; }
  958. if ($e && !in_array($e,$this->editors)) {
  959. $this->editors[]=$e;
  960. $this->setUserPermissions($e);
  961. $this->changedpermissions = 1;
  962. }
  963. }
  964. function delEditor($e) {
  965. $class=get_class($this);
  966. if ($e == 'institute' || $e == 'everyone') return false;
  967. if (!$e) return false;
  968. if (in_array($e,$this->editors)) {
  969. $n = array();
  970. foreach($this->editors as $v) {
  971. if ($v != $e) $n[]=$v;
  972. }
  973. $this->editors = $n;
  974. $this->setFieldDown("l%$e%add",0);
  975. $this->setFieldDown("l%$e%edit",0);
  976. $this->setFieldDown("l%$e%delete",0);
  977. $this->setFieldDown("l%$e%view",0);
  978. $this->setFieldDown("l%$e%discuss",0);
  979. $this->setUserPermissionDown("ADD",$e,0);
  980. $this->setUserPermissionDown("VIEW",$e,0);
  981. $this->setUserPermissionDown("EDIT",$e,0);
  982. $this->setUserPermissionDown("DELETE",$e,0);
  983. $this->setUserPermissionDown("DISCUSS",$e,0);
  984. $this->editorsToDelete[] = $e;
  985. }
  986. }
  987. function getEditors() {
  988. if (!$this->builtPermissions && $this->id)
  989. $this->buildPermissionsArray(0,0);
  990. return array_unique($this->editors);
  991. }
  992. /**
  993. * Answer the users who have add, edit, and delete permission at the site
  994. * level
  995. * retun array The editor ids
  996. */
  997. function getSiteLevelEditors () {
  998. if (!isset($this->_siteLevelEditors)) {
  999. $this->_siteLevelEditors = array();
  1000. foreach ($this->getEditors() as $editor) {
  1001. if ($this->owningSiteObj->hasPermission('add && edit && delete', $editor)) {
  1002. $this->_siteLevelEditors[] = $editor;
  1003. }
  1004. }
  1005. }
  1006. return $this->_siteLevelEditors;
  1007. }
  1008. function setPermissions($p) {
  1009. if (is_array($p)) {
  1010. $this->permissions = $p;
  1011. $this->editors = array_unique(array_merge(array_keys($p),$this->editors)); // add new editors from new permissions array
  1012. $this->changedpermissions = 1;
  1013. }
  1014. }
  1015. /* function setPermissionsDown($p) { */
  1016. /* if (!$this->fetcheddown) $this->fetchDown(); */
  1017. /* $class=get_class($this); */
  1018. /* $ar = $this->_object_arrays[$class]; */
  1019. /* $this->setPermissions($p); */
  1020. /* if ($ar) { */
  1021. /* $a = &$this->$ar; */
  1022. /* if ($a) { */
  1023. /* foreach ($a as $i=>$o) { */
  1024. /* $a[$i]->setPermissionsDown($p); */
  1025. /* } */
  1026. /* } */
  1027. /* } */
  1028. /* } */
  1029. function clearPermissions($editor = '') {
  1030. /* print "Editors: <pre>"; print_r($this->getEditors()); print "</pre>"; */
  1031. /* print "To Delete: <pre>"; print_r($this->editorsToDeleteInScope); print "</pre>"; */
  1032. $this->editors = array();
  1033. $this->permissions = array();
  1034. $this->changedpermissions = 1;
  1035. }
  1036. function setUserPermissions($user,$add=0,$edit=0,$del=0,$view=0,$discuss=0) {
  1037. $this->setUserPermissionsFromArray($user,array(ADD=>$add,EDIT=>$edit,DELETE=>$del,VIEW=>$view,DISCUSS=>$discuss));
  1038. }
  1039. function setUserPermissionsFromArray($user,$p) {
  1040. $this->permissions[$user] = $p;
  1041. $this->changedpermissions = 1;
  1042. }
  1043. function setUserPermissionDown($perm,$user,$val=1) {
  1044. $class=get_class($this);
  1045. $ar = $this->_object_arrays[$class];
  1046. $p = strtoupper($perm);
  1047. $c = permissions::$p();
  1048. if ($this->permissions[$user][$c] != $val) {
  1049. $this->permissions[$user][$c] = $val;
  1050. $this->cachedPermissions["onlyuser".$user.$perm] = $val; // Update the cached permissions array so that
  1051. // hasPermission doesn't get a fscked up
  1052. $this->cachedPermissions[$user.$perm] = $val; // Update the cached permissions array so that
  1053. // hasPermission doesn't get a fscked up
  1054. $this->changedpermissions=1;
  1055. }
  1056. /* if ($class == "site") $n = 0; */
  1057. /* else if ($class == "section")$n =4; */
  1058. /* else if ($class == "page")$n = 8; */
  1059. /* else $n=12; */
  1060. /* $i = 0; */
  1061. /* while($i <= $n) { */
  1062. /* print " &nbsp; "; */
  1063. /* $i++; */
  1064. /* } */
  1065. /* print $this->permissions[$user][$c]; */
  1066. /* print $class.": set -- has permission= -- should be: $val<br />"; */
  1067. /* print $this->permissions[$user][$c]; */
  1068. /* print "<pre>"; print_r($this->permissions[$user]); print "</pre>"; */
  1069. if ($ar) {
  1070. $a = &$this->$ar;
  1071. if ($a) {
  1072. foreach (array_keys($a) as $k=>$i) {
  1073. $a[$i]->setUserPermissionDown($perm,$user,$val);
  1074. $a[$i]->cachedPermissions["onlyuser".$user.$perm] = $val; // Update the cached permissions array so that
  1075. // hasPermission doesn't get a fscked up
  1076. $a[$i]->cachedPermissions[$user.$perm] = $val; // Update the cached permissions array so that
  1077. // hasPermission doesn't get a fscked up
  1078. }
  1079. }
  1080. }
  1081. }
  1082. function getPermissions() {
  1083. // returns an html-formable permissions array based on the permissions table
  1084. return $this->permissions;
  1085. }
  1086. function movePermission($action, $user, $origSite, $moveLevel) {
  1087. // determines whether user can move an object here
  1088. if ($this->getField("type") != get_class($this)) return 0;
  1089. if ($this->owning_site == $origSite) {
  1090. if ($action == "COPY") {
  1091. if ($this->hasPermission("add",$user)) return 1;
  1092. if ($moveLevel != get_class($this) && $this->hasPermissionDown("add",$user)) return 1;
  1093. } else {
  1094. if ($this->hasPermission("add or edit",$user)) return 1;
  1095. if ($moveLevel != get_class($this) && $this->hasPermissionDown("add or edit",$user)) return 1;
  1096. }
  1097. } else {
  1098. if ($this->hasPermission("add",$user)) return 1;
  1099. if ($moveLevel != get_class($this) && $this->hasPermissionDown("add",$user)) return 1;
  1100. }
  1101. return 0;
  1102. }
  1103. /******************************************************************************
  1104. * buildPermissionsArray - builds the permissions array for current obj from DB
  1105. ******************************************************************************/
  1106. function buildPermissionsArray($force=0,$down=0) {
  1107. if (!$force && $this->builtPermissions) return;
  1108. $scope = get_class($this);
  1109. $site = $this->owning_site;
  1110. $id = $this->id;
  1111. // the SQL queries for obtaining the permissions vary with the scope type. Thus, we have 4 cases, 1 for each scope type.
  1112. // editors can be either institute, everyone, a username or a ugroup name
  1113. // we need two queries for any one scope
  1114. // CASE 1: scope is SITE
  1115. if ($scope == 'site') {
  1116. $query = "
  1117. SELECT
  1118. user_uname as editor, ugroup_name as editor2, site_editors_type as editor_type,
  1119. MAKE_SET(IFNULL((permission_value+0),0), 'v', 'a', 'e', 'd', 'di') as permissions
  1120. FROM
  1121. site
  1122. INNER JOIN
  1123. site_editors ON
  1124. site_id = ".$this->id."
  1125. AND
  1126. site_id = FK_site
  1127. LEFT JOIN
  1128. user ON
  1129. site_editors.FK_editor = user_id
  1130. LEFT JOIN
  1131. ugroup ON
  1132. site_editors.FK_editor = ugroup_id
  1133. LEFT JOIN
  1134. permission ON
  1135. site_id = FK_scope_id
  1136. AND
  1137. permission_scope_type = 'site'
  1138. AND
  1139. permission.FK_editor <=> site_editors.FK_editor
  1140. AND
  1141. permission_editor_type = site_editors_type
  1142. ";
  1143. }
  1144. // CASE 2: scope is SECTION
  1145. else if ($scope == 'section') {
  1146. $query = "
  1147. SELECT
  1148. user_uname as editor, ugroup_name as editor2, site_editors_type as editor_type,
  1149. MAKE_SET(IFNULL((p1.permission_value+0),0) | IFNULL((p2.permission_value+0),0), 'v', 'a', 'e', 'd', 'di') as permissions
  1150. FROM
  1151. site
  1152. INNER JOIN
  1153. section
  1154. ON site_id = section.FK_site
  1155. AND
  1156. section_id = ".$this->id."
  1157. INNER JOIN
  1158. site_editors ON
  1159. site_id = site_editors.FK_site
  1160. LEFT JOIN
  1161. user ON
  1162. site_editors.FK_editor = user_id
  1163. LEFT JOIN
  1164. ugroup ON
  1165. site_editors.FK_editor = ugroup_id
  1166. LEFT JOIN
  1167. permission as p1 ON
  1168. site_id = p1.FK_scope_id
  1169. AND
  1170. p1.permission_scope_type = 'site'
  1171. AND
  1172. p1.FK_editor <=> site_editors.FK_editor
  1173. AND
  1174. p1.permission_editor_type = site_editors_type
  1175. LEFT JOIN
  1176. permission as p2 ON
  1177. section_id = p2.FK_scope_id
  1178. AND
  1179. p2.permission_scope_type = 'section'
  1180. AND
  1181. p2.FK_editor <=> site_editors.FK_editor
  1182. AND
  1183. p2.permission_editor_type = site_editors_type
  1184. ";
  1185. }
  1186. // CASE 3: scope is PAGE
  1187. else if ($scope == 'page') {
  1188. $query = "
  1189. SELECT
  1190. user_uname as editor, ugroup_name as editor2, site_editors_type as editor_type,
  1191. MAKE_SET(IFNULL((p1.permission_value+0),0) | IFNULL((p2.permission_value+0),0) | IFNULL((p3.permission_value+0),0), 'v', 'a', 'e', 'd', 'di') as permissions
  1192. FROM
  1193. site
  1194. INNER JOIN
  1195. section
  1196. ON site_id = section.FK_site
  1197. INNER JOIN
  1198. page
  1199. ON section_id = page.FK_section
  1200. AND
  1201. page_id = ".$this->id."
  1202. INNER JOIN
  1203. site_editors ON
  1204. site_id = site_editors.FK_site
  1205. LEFT JOIN
  1206. user ON
  1207. site_editors.FK_editor = user_id
  1208. LEFT JOIN
  1209. ugroup ON
  1210. site_editors.FK_editor = ugroup_id
  1211. LEFT JOIN
  1212. permission as p1 ON
  1213. site_id = p1.FK_scope_id
  1214. AND
  1215. p1.permission_scope_type = 'site'
  1216. AND
  1217. p1.FK_editor <=> site_editors.FK_editor
  1218. AND
  1219. p1.permission_editor_type = site_editors_type
  1220. LEFT JOIN
  1221. permission as p2 ON
  1222. section_id = p2.FK_scope_id
  1223. AND
  1224. p2.permission_scope_type = 'section'
  1225. AND
  1226. p2.FK_editor <=> site_editors.FK_editor
  1227. AND
  1228. p2.permission_editor_type = site_editors_type
  1229. LEFT JOIN
  1230. permission as p3 ON
  1231. page_id = p3.FK_scope_id
  1232. AND
  1233. p3.permission_scope_type = 'page'
  1234. AND
  1235. p3.FK_editor <=> site_editors.FK_editor
  1236. AND
  1237. p3.permission_editor_type = site_editors_type
  1238. ";
  1239. }
  1240. // CASE 4: scope is PAGE
  1241. else if ($scope == 'story') {
  1242. $query = "
  1243. SELECT
  1244. user_uname as editor, ugroup_name as editor2, site_editors_type as editor_type,
  1245. MAKE_SET(IFNULL((p1.permission_value+0),0) | IFNULL((p2.permission_value+0),0) | IFNULL((p3.permission_value+0),0) | IFNULL((p4.permission_value+0),0), 'v', 'a', 'e', 'd', 'di') as permissions
  1246. FROM
  1247. site
  1248. INNER JOIN
  1249. section
  1250. ON site_id = section.FK_site
  1251. INNER JOIN
  1252. page
  1253. ON section_id = page.FK_section
  1254. INNER JOIN
  1255. story
  1256. ON page_id = story.FK_page
  1257. AND
  1258. story_id = '".addslashes($this->id)."'
  1259. INNER JOIN
  1260. site_editors ON
  1261. site_id = site_editors.FK_site
  1262. LEFT JOIN
  1263. user ON
  1264. site_editors.FK_editor = user_id
  1265. LEFT JOIN
  1266. ugroup ON
  1267. site_editors.FK_editor = ugroup_id
  1268. LEFT JOIN
  1269. permission as p1 ON
  1270. site_id = p1.FK_scope_id
  1271. AND
  1272. p1.permission_scope_type = 'site'
  1273. AND
  1274. p1.FK_editor <=> site_editors.FK_editor
  1275. AND
  1276. p1.permission_editor_type = site_editors_type
  1277. LEFT JOIN
  1278. permission as p2 ON
  1279. section_id = p2.FK_scope_id
  1280. AND
  1281. p2.permission_scope_type = 'section'
  1282. AND
  1283. p2.FK_editor <=> site_editors.FK_editor
  1284. AND
  1285. p2.permission_editor_type = site_editors_type
  1286. LEFT JOIN
  1287. permission as p3 ON
  1288. page_id = p3.FK_scope_id
  1289. AND
  1290. p3.permission_scope_type = 'page'
  1291. AND
  1292. p3.FK_editor <=> site_editors.FK_editor
  1293. AND
  1294. p3.permission_editor_type = site_editors_type
  1295. LEFT JOIN
  1296. permission as p4 ON
  1297. story_id = p4.FK_scope_id
  1298. AND
  1299. p4.permission_scope_type = 'story'
  1300. AND
  1301. p4.FK_editor <=> site_editors.FK_editor
  1302. AND
  1303. p4.permission_editor_type = site_editors_type
  1304. ";
  1305. }
  1306. // execute the query
  1307. // echo $query;
  1308. $r = db_query($query);
  1309. //echo "Query result: ".$r."<br />";
  1310. // reset the editor array
  1311. if ($r) {
  1312. $this->editors = array();
  1313. $this->permissions = array();
  1314. }
  1315. // for every permisson entry, add it to the permissions array
  1316. while ($row=db_fetch_assoc($r)) {
  1317. // decode 'final_permissions';
  1318. // 'final_permissions' is a field returned by the query and contains a string of the form "'a','vi','e'" etc.
  1319. $a = array();
  1320. $dbPerms = explode(",", $row[permissions]);
  1321. $a[v] = in_array('v', $dbPerms);
  1322. $a[a] = in_array('a', $dbPerms);
  1323. $a[e] = in_array('e', $dbPerms);
  1324. $a[d] = in_array('d', $dbPerms);
  1325. $a[di] = in_array('di', $dbPerms);
  1326. // Trash the db perms variable.
  1327. $dbPerms = NULL;
  1328. unset ($dbPerms);
  1329. // if the editor is a user then the editor's name is just the user name
  1330. // if the editor is 'institute' or 'everyone' then set the editor's name correspondingly
  1331. if ($row[editor_type]=='user')
  1332. $t_editor = $row[editor];
  1333. else if ($row[editor_type]=='ugroup')
  1334. $t_editor = $row[editor2];
  1335. else
  1336. $t_editor = $row[editor_type];
  1337. // Everyone and institute can't have add, edit, or delete permissions.
  1338. // Somehow, these were added sometimes. If this is the case, prevent
  1339. // these from being set and reset those for the site.
  1340. if ($t_editor == 'everyone' || $t_editor == 'institute') {
  1341. // If we have a bad permission, do cleanup.
  1342. if ($a[a] || $a[e] || $a[d]) {
  1343. // Make sure that zeros get passed on.
  1344. $a[a] = 0;
  1345. $a[e] = 0;
  1346. $a[d] = 0;
  1347. // Clean up the permissions
  1348. $this->owningSiteObj->setUserPermissionDown('add', $t_editor, 0);
  1349. $this->owningSiteObj->setUserPermissionDown('edit', $t_editor, 0);
  1350. $this->owningSiteObj->setUserPermissionDown('delete', $t_editor, 0);
  1351. $this->owningSiteObj->updatePermissionsDB(TRUE);
  1352. }
  1353. }
  1354. // echo "<br /><br />Editor: $t_editor; Add: $a[a]; Edit: $a[e]; Delete: $a[d]; View: $a[v]; Discuss: $a[di];";
  1355. // set the permissions for this editor
  1356. // $this->permissions[strtolower($t_editor)] = array(
  1357. $this->permissions[$t_editor] = array(
  1358. permissions::ADD()=>($a[a] || ($this->permissions[$t_editor] && $this->permissions[$t_editor][permissions::ADD()])),
  1359. permissions::EDIT()=>($a[e] || ($this->permissions[$t_editor] && $this->permissions[$t_editor][permissions::EDIT()])),
  1360. permissions::DELETE()=>($a[d] || ($this->permissions[$t_editor] && $this->permissions[$t_editor][permissions::DELETE()])),
  1361. permissions::VIEW()=>($a[v] || ($this->permissions[$t_editor] && $this->permissions[$t_editor][permissions::VIEW()])),
  1362. permissions::DISCUSS()=>($a[di] || ($this->permissions[$t_editor] && $this->permissions[$t_editor][permissions::DISCUSS()]))
  1363. );
  1364. // now add the editor to the editor array
  1365. // $this->editors[]=strtolower($t_editor);
  1366. if ($t_editor) $this->editors[]=$t_editor;
  1367. }
  1368. // print_r($this->permissions);
  1369. $this->builtPermissions=1;
  1370. if ($down) {
  1371. $ar = $this->_object_arrays[$scope];
  1372. if ($ar) {
  1373. $a = &$this->$ar;
  1374. if ($a) {
  1375. foreach ($a as $i=>$o) {
  1376. $a[$i]->buildPermissionsArray($force,$down);
  1377. }
  1378. }
  1379. }
  1380. }
  1381. }
  1382. /******************************************************************************
  1383. * spiderDownLockedFlag - used for editing permissions... sets the locked flag
  1384. * on children of a section with certain permissions
  1385. * don't try to understand this, just use it. it works
  1386. ******************************************************************************/
  1387. function spiderDownLockedFlag() {
  1388. $editors = $this->getEditors();
  1389. $p = $this->getPermissions();
  1390. // print_r($editors);print "<br />";print_r($p);
  1391. $_a = array("add","edit","delete","view");
  1392. foreach ($editors as $e) {
  1393. // print "doing flags for $e<br />";
  1394. for ($i=0;$i<4;$i++) {
  1395. $this->checkLockedFlag($e,$_a[$i]);
  1396. }
  1397. }
  1398. }
  1399. function checkLockedFlag($e,$perm) {
  1400. // if (!$this->builtPermissions && $this->id) //might be needed. unknown.
  1401. $this->buildPermissionsArray(); // just in case
  1402. $p = $this->getPermissions();
  1403. $_t = strtoupper($perm);
  1404. $pid = permissions::$_t();
  1405. $e = $e;
  1406. if ($p[$e][$pid]) { // set locked flag
  1407. $this->setFieldDown("l%$e%$perm",1);
  1408. $this->setField("l%$e%$perm",0);
  1409. } else {
  1410. // keep going down the line
  1411. $ar = $this->_object_arrays[get_class($this)];
  1412. if ($ar) {
  1413. $a = &$this->$ar;
  1414. if ($a) {
  1415. foreach ($a as $i=>$o)
  1416. $a[$i]->checkLockedFlag($e,$perm);
  1417. }
  1418. }
  1419. }
  1420. }
  1421. /******************************************************************************
  1422. * updatePermissionsDB - updates the permissions DB based on new permissions
  1423. ******************************************************************************/
  1424. function updatePermissionsDB($force=0) {
  1425. if ($this->changedpermissions || $force) {
  1426. $scope = get_class($this);
  1427. $id = $this->id;
  1428. $site = $this->owning_site;
  1429. $n = array_unique(array_merge($this->editors,$this->editorsToDelete,array_keys($this->permissions)));
  1430. // printpre($n);
  1431. foreach ($n as $editor) {
  1432. $p2 = $this->permissions[$editor];
  1433. if (!is_array($p2)) {
  1434. // echo "p2: ************************** BE CAREFUL!!!! ********************************<br />";
  1435. $p2 = array();
  1436. $p2[ADD] = 0;
  1437. $p2[EDIT] = 0;
  1438. $p2[DELETE] = 0;
  1439. $p2[VIEW] = 0;
  1440. $p2[DISCUSS] = 0;
  1441. }
  1442. // print_r($p);
  1443. // now get the permissions for the parent object. We need to do this so that we can determine whether
  1444. // the child permissions have simply inherited the parent permissions, or they have added something new.
  1445. // if a section object, get permissions for the site
  1446. if ($scope == "section")
  1447. $p1 = $this->owningSiteObj->permissions[$editor];
  1448. // if a page object, get permissions for the parent section
  1449. else if ($scope == "page")
  1450. $p1 = $this->owningSectionObj->permissions[$editor];
  1451. // if a story object, get permissions for the parent page
  1452. else if ($scope == "story")
  1453. $p1 = $this->owningPageObj->permissions[$editor];
  1454. if (!is_array($p1) && $scope != 'site') {
  1455. // echo "p1: ************************** BE CAREFUL!!!! ********************************<br />";
  1456. $p1 = array();
  1457. $p1[ADD] = 0;
  1458. $p1[EDIT] = 0;
  1459. $p1[DELETE] = 0;
  1460. $p1[VIEW] = 0;
  1461. $p1[DISCUSS] = 0;
  1462. }
  1463. // Make sure that everyone and institute aren't given
  1464. // add, edit, or delete permission
  1465. if ($editor == 'everyone' || $editor == 'institute') {
  1466. if ($p1[ADD] || $p1[EDIT] || $p1[DELETE] || $p2[ADD] || $p2[EDIT] ||$p2[DELETE])
  1467. printError("Ahh, trying to give $editor invalid permissions!");
  1468. $p1[ADD] = 0;
  1469. $p1[EDIT] = 0;
  1470. $p1[DELETE] = 0;
  1471. $p2[ADD] = 0;
  1472. $p2[EDIT] = 0;
  1473. $p2[DELETE] = 0;
  1474. }
  1475. // note that if a certain permission is set in $p1, it is impossible that the same permission is not set in $p2 (because $p2 inherits $p1's permissions)
  1476. // thus, there are 3 possibilities:
  1477. // 1) $p1 - SET, $p2 - SET
  1478. // 2) $p1 - UNSET, $p2 - SET
  1479. // 3) $p1 - UNSET, $p2 - UNSET
  1480. // now, put the inherited permissions in $p_inherit and the new permissions in $p_new
  1481. $p_inherit = array();
  1482. $p_new = array();
  1483. if ($scope != "site") {
  1484. foreach ($p1 as $key => $value)
  1485. // in case 1) and 3) $p2 inherits $p1's permission
  1486. if ($p1[$key] || (!$p1[$key] && !$p2[$key])) {
  1487. $p_inherit[$key] = 1;
  1488. $p_new[$key] = 0;
  1489. }
  1490. // in case 2), $p2 adds a new permission
  1491. else {
  1492. $p_inherit[$key] = 0;
  1493. $p_new[$key] = 1;
  1494. }
  1495. }
  1496. // if a site object
  1497. else {
  1498. $p_new = $p2; // everything is new
  1499. foreach ($p2 as $key => $value)
  1500. $p_inherit[$key] = 0; // nothing is inherited
  1501. }
  1502. // convert $p_new to a "'a','v',..." format.
  1503. $p_new_str = "";
  1504. if ($p_new[ADD]) $p_new_str.="a,";
  1505. if ($p_new[EDIT]) $p_new_str.="e,";
  1506. if ($p_new[DELETE]) $p_new_str.="d,";
  1507. if ($p_new[VIEW]) $p_new_str.="v,";
  1508. if ($p_new[DISCUSS]) $p_new_str.="di,";
  1509. if ($p_new_str) $p_new_str = substr($p_new_str, 0, strlen($p_new_str)-1); // strip last comma from the end of a string
  1510. // find the id and type of this editor
  1511. if ($editor == 'everyone' || $editor == 'institute') {
  1512. $ed_type = $editor;
  1513. $ed_id = 'NULL';
  1514. }
  1515. else if ($ugroup_id = ugroup::getGroupID($editor)) {
  1516. $ed_type = 'ugroup';
  1517. $ed_id = "'".addslashes($ugroup_id)."'";
  1518. }
  1519. else {
  1520. $ed_type = 'user';
  1521. // Make sure the person is in the DB and synched.
  1522. synchronizeLocalUserAndClassDB($editor);
  1523. // need to fetch the id from the user table
  1524. $query = "SELECT user_id FROM user WHERE user_uname = '".addslashes($editor)."'";
  1525. $r = db_query($query);
  1526. if (!db_num_rows($r)) {
  1527. echo $query."<br />";
  1528. die("updatePermissionsDB() :: could not find an ID to associate with editor: '$editor'!!!");
  1529. }
  1530. $arr = db_fetch_assoc($r);
  1531. $ed_id = "'".addslashes($arr['user_id'])."'";
  1532. }
  1533. // echo "<br /><br /><b>***** New permissions in $scope #$id with editor $editor: '".$p_new_str."'</b><br />";
  1534. // echo "EID: $ed_id; ETYPE: $ed_type <br />";
  1535. // see if the editor is in the site_editors table
  1536. if ($scope == "site")
  1537. $site_id = $id;
  1538. else
  1539. $site_id = $this->owningSiteObj->id;
  1540. $query = "
  1541. SELECT
  1542. FK_editor
  1543. FROM
  1544. site_editors
  1545. WHERE
  1546. FK_editor <=> ".$ed_id." AND
  1547. site_editors_type = '".addslashes($ed_type)."' AND
  1548. FK_site = '".addslashes($site_id)."'
  1549. ";
  1550. // echo $query."<br />";
  1551. $r_editor = db_query($query); // this query checks to see if the editor is in the site_editors table
  1552. // if the editor is not in the site_editors then insert him
  1553. if (!db_num_rows($r_editor)) {
  1554. $query = "
  1555. INSERT
  1556. INTO site_editors
  1557. (FK_site, FK_editor, site_editors_type)
  1558. VALUES
  1559. ('".addslashes($site_id)."', ".$ed_id.", '".addslashes($ed_type)."')
  1560. ";
  1561. // echo $query."<br />";
  1562. db_query($query);
  1563. }
  1564. // now that we have all the information pertaining to this user, check if the permission entry is already present
  1565. // if yes, update it
  1566. // if not, insert it
  1567. $query = "
  1568. SELECT
  1569. permission_id
  1570. FROM
  1571. permission
  1572. WHERE
  1573. permission_scope_type='".addslashes($scope)."' AND
  1574. FK_scope_id='".addslashes($id)."' AND
  1575. FK_editor <=> ".$ed_id." AND
  1576. permission_editor_type = '".addslashes($ed_type)."'
  1577. ";
  1578. // echo $query."<br />";
  1579. $r_perm = db_query($query); // this query checks to see if the entry exists in the permission table
  1580. // if permission entry exists
  1581. if (db_num_rows($r_perm)) {
  1582. $a = db_fetch_assoc($r_perm);
  1583. // if we are changing the permissions, update the db
  1584. if ($p_new_str) {
  1585. $query = "
  1586. UPDATE
  1587. permission
  1588. SET
  1589. permission_value='".addslashes($p_new_str)."'
  1590. WHERE
  1591. permission_id = '".addslashes($a[permission_id])."'
  1592. ";
  1593. // echo $query."<br />";
  1594. db_query($query);
  1595. }
  1596. // if we are clearing the permissions, delete the entry from the db
  1597. else {
  1598. $query = "
  1599. DELETE FROM
  1600. permission
  1601. WHERE
  1602. permission_id = '".addslashes($a[permission_id])."'
  1603. ";
  1604. db_query($query);
  1605. }
  1606. }
  1607. // if permission entry does not exist in the permission table
  1608. else if ($p_new_str) {
  1609. // need to insert permissions
  1610. $query = "
  1611. INSERT
  1612. INTO permission
  1613. (FK_editor, permission_editor_type, FK_scope_id, permission_scope_type, permission_value)
  1614. VALUES (".$ed_id.", '".addslashes($ed_type)."', '".addslashes($id)."', '".addslashes($scope)."', '".addslashes($p_new_str)."')
  1615. ";
  1616. // echo $query."<br />";
  1617. db_query($query);
  1618. }
  1619. }
  1620. }
  1621. }
  1622. /******************************************************************************
  1623. * deletePendingEditors() - takes care of editors in editorsToDelete and
  1624. * editorsToDeleteInScope.
  1625. * THIS FUNCTION MUST BE CALLED AFTER updatePermissionsDB()!!!
  1626. ******************************************************************************/
  1627. function deletePendingEditors() {
  1628. // if user wants to delete editors, remove their permissions from site_editors
  1629. foreach ($this->editorsToDelete as $e) {
  1630. $query = "SELECT user_id FROM user WHERE user_uname = '".addslashes($e)."'";
  1631. $r = db_query($query);
  1632. $arr = db_fetch_assoc($r);
  1633. $ed_id = $arr['user_id'];
  1634. $ed_type = 'user';
  1635. if (!$ed_id) {
  1636. $ed_id = ugroup::getGroupID($e);
  1637. $ed_type = 'ugroup';
  1638. }
  1639. if ($ed_id) {
  1640. $query = "
  1641. DELETE FROM
  1642. site_editors
  1643. WHERE
  1644. FK_editor = $ed_id
  1645. AND
  1646. site_editors_type = '".addslashes($ed_type)."'
  1647. AND
  1648. FK_site = '".addslashes($this->owningSiteObj->id)."'
  1649. ";
  1650. $r = db_query($query);
  1651. }
  1652. }
  1653. $this->editorsToDelete = array();
  1654. /*
  1655. foreach ($this->editorsToDeleteInScope as $e) {
  1656. db_query("delete from permissions where user='$e' and site='$site' and scope='$scope' and scopeid=$id");
  1657. }
  1658. */
  1659. }
  1660. /**
  1661. * Checks Several things to determine if the user can view the part:
  1662. * - is this part Active?
  1663. * - is this part within the enabled date ranges?
  1664. * - does the user have permission to view this part if the above are true?
  1665. *
  1666. * @param optional string $user
  1667. * @return boolean TRUE if the user can view the part
  1668. * @access public
  1669. * @date 8/31/04
  1670. */
  1671. function canview ($user = "") {
  1672. // Get our current user:
  1673. if ($user == "")
  1674. $user = $_SESSION[auser];
  1675. // Make sure we have everything fetched that we need.
  1676. $this->fetchUp();
  1677. // The owner can always view, so return TRUE
  1678. if ($this->owningSiteObj->owner == $user) {
  1679. return TRUE;
  1680. }
  1681. // print "\n<br />Checking canview for '$user' ".get_class($this)." ".$this->name." / ".$this->id." - ".$this->getField("title");
  1682. // ------ Activation ------
  1683. // First lets check if this part is active so that we don't have to bother
  1684. // checking permissions if it isn't active.
  1685. // What level of the hierarchy are we looking at?
  1686. $scope = get_class($this);
  1687. // Check to see if this part is active.
  1688. // Sections and pages of type "heading" can't be disabled
  1689. if (!$this->getField("active") && ($scope != 'story' && $this->getField("type") != 'heading')) {
  1690. return FALSE;
  1691. }
  1692. // Check to see if this part is outside of its active date range.
  1693. if (!indaterange($this->getField("activatedate"),$this->getField("deactivatedate")))
  1694. return FALSE;
  1695. // If we are passed the 'anyuser' user, then we are being asked if this
  1696. // part is active, akin to asking, "Can anybody see this thing?". If we have
  1697. // gotten this far, this is the case, so return TRUE if we are passed
  1698. // $user == 'anyuser'.
  1699. if ($user == 'anyuser')
  1700. return TRUE;
  1701. // ------ Permission ------
  1702. // If we have gotten this far, then the part is active.
  1703. // We now need to check if the current user has permission to view the
  1704. // part.
  1705. // If we are looking at a site and already fetched the permissions,
  1706. // we don't need to fetch them again.
  1707. if ($this->fetched_forever_and_ever && get_class($this)=="site")
  1708. $fetch = FALSE;
  1709. else
  1710. $fetch = TRUE;
  1711. // view: The permission to check
  1712. // $user: The user to check
  1713. // FALSE: Don't check only the user, include the user in any groups they
  1714. // may be a part of.
  1715. // $fetch: Should we fetch permissions?
  1716. return $this->hasPermissionDown("view", $user, FALSE, $fetch);
  1717. }
  1718. /**
  1719. * Checks to see if the user has the specified permissions.
  1720. *
  1721. * @param string $perms The permissions to check.
  1722. * $perms paramater can be a complex string consisting
  1723. * of ()'s, 'and', 'or', and permission types:
  1724. * 'add','edit','delete','view','discuss'
  1725. * @param optional string $user The user to check.
  1726. * @param option boolean $useronly If true, the user's permissions will be
  1727. * checked explicitly and the user will not be included in any
  1728. * groups.
  1729. * @return boolean True if the user has the permissions asked for.
  1730. * @access public
  1731. * @date 8/31/04
  1732. */
  1733. function hasPermission ($perms, $user = "", $useronly = FALSE) {
  1734. //****************************************
  1735. // ----- Setup -----
  1736. //****************************************
  1737. global $allclasses, $_loggedin, $cfg;
  1738. // Build the permissions array to check against.
  1739. $this->buildPermissionsArray();
  1740. // Get our current user if we weren't passed one to check:
  1741. if ($user == "")
  1742. $user = $_SESSION[auser];
  1743. // If we haven't built the classes array and we need it,
  1744. // build the classes array.
  1745. if (!is_array($allclasses[$_SESSION['auser']]) && !$useronly)
  1746. $allclasses[$_SESSION['auser']] = getuserclasses($user,"all");
  1747. //****************************************
  1748. // ----- Return Cached Permissions ------
  1749. // If we have checked this permission string before and cached it,
  1750. // just return the cached result.
  1751. //
  1752. // There are separate entries for useronly and those with groups as well.
  1753. // This is to prevent the caching of perms for a user with groups, then
  1754. // getting that cached result when asking only for user permissions.
  1755. //****************************************
  1756. if ($useronly && isset($this->cachedPermissions["onlyuser".$user.$perms]))
  1757. return $this->cachedPermissions["onlyuser".$user.$perms];
  1758. if (!$useronly && isset($this->cachedPermissions[$user.$perms]))
  1759. return $this->cachedPermissions[$user.$perms];
  1760. //****************************************
  1761. // ----- New checking of Permissions -----
  1762. // Below is where we will check to see if the user has the permissions
  1763. // asked for.
  1764. //****************************************
  1765. // Make sure that we are fetched.
  1766. $this->fetchUp();
  1767. // The site owner will always have permission, so return
  1768. // TRUE if the user is the owner.
  1769. $owner = $this->owningSiteObj->owner;
  1770. if (strtolower($user) == strtolower($owner))
  1771. return TRUE;
  1772. // ------ Verify the permissions String ------
  1773. // Verify that the permissions string is well formed. And return
  1774. // FALSE if it is not.
  1775. $validGrants = array('add', 'edit', 'delete', 'view', 'discuss');
  1776. $validOperators = array('and', 'or', '&&', '||');
  1777. $permissionParts = explode(' ',ereg_replace("([()]){1}","",$perms));
  1778. $i=0;
  1779. $stringValid=1;
  1780. foreach ($permissionParts as $permissionPart) {
  1781. if (!strlen($permissionPart))
  1782. continue;
  1783. // Begining with our first part, every other permission part
  1784. // should be a grant.
  1785. if (!($i % 2) && !in_array($permissionPart,$validGrants))
  1786. $stringValid = FALSE;
  1787. // Beginning with our second part, every other permissions
  1788. // part should be an operator
  1789. if (!(($i + 1) % 2) && !in_array($permissionPart,$validOperators))
  1790. $stringValid = FALSE;
  1791. // If we don't have a valid permissions string, return FALSE.
  1792. if (!$stringValid) {
  1793. print "ERROR! loop: $i: Malformed permissions string: $perms<br /><br />";
  1794. return FALSE;
  1795. }
  1796. $i++;
  1797. }
  1798. // convert word operators to symbol operators
  1799. $perms = str_replace('and','&&',$perms);
  1800. $perms = str_replace('or','||',$perms);
  1801. // ---- pull from the database/cache ---
  1802. // Get the permissions from the database
  1803. $permissions = $this->getPermissions();
  1804. // Make sure that we have a lowercase version of each entity
  1805. foreach ($permissions as $entity => $permission)
  1806. $permissions[strtolower($entity)] = $permission;
  1807. // --- Build a list of all entities to check for the permissions ---
  1808. $entitiesToCheck = array();
  1809. // Add the user to the array if we have a user.
  1810. if (strlen($user))
  1811. $entitiesToCheck[] = strtolower($user);
  1812. // Determine what additional entities to check.
  1813. if (!$useronly) {
  1814. // ----- everyone ------
  1815. // Everyone, even not-logged-in users are a part of everyone.
  1816. $entitiesToCheck[] = "everyone";
  1817. // ----- institute ------
  1818. // If we are logged-in, but not of type 'visitor', the user
  1819. // is a member of institute.
  1820. // Also, if we are previewing the permissions of another user,
  1821. // and that other user is 'everyone', we don't want to include
  1822. // institute checks.
  1823. if ($_loggedin && $_SESSION['atype'] != 'visitor' && $_SESSION['auser'] != 'everyone')
  1824. $entitiesToCheck[] = "institute";
  1825. // If the user has a valid campus ip-address, then they are a
  1826. // member of 'institute'.
  1827. $ipIsInInstitute = FALSE;
  1828. $ip = $_SERVER[REMOTE_ADDR];
  1829. // check if our IP is in inst_ips
  1830. if (is_array($cfg[inst_ips])) {
  1831. foreach ($cfg[inst_ips] as $i) {
  1832. if (ereg("^$i",$ip))
  1833. $ipIsInInstitute = TRUE;
  1834. }
  1835. }
  1836. // One other case to check is if we are trying to preview a site as it would
  1837. // be seen by another user. In this case, we don't want to check the IPs
  1838. // as that would give a false indication of what they could see.
  1839. if ($ipIsInInstitute && !$_SESSION['__no_inst_ips']) {
  1840. $entitiesToCheck[] = "institute";
  1841. }
  1842. // ----- classes ------
  1843. $classesUserIsIn = $this->returnEditorOverlap($allclasses[$_SESSION['auser']]);
  1844. $entitiesToCheck = array_merge($classesUserIsIn, $entitiesToCheck, getusergroups($_SESSION['auser']));
  1845. }
  1846. $entitiesToCheck = array_unique($entitiesToCheck);
  1847. // ------ Evaluation Strings--------
  1848. // Create an array of permission checking strings to be evaluated, one per entity.
  1849. $evalStrings = array();
  1850. foreach ($entitiesToCheck as $entity) {
  1851. $evalString = $perms;
  1852. foreach ($validGrants as $grant) {
  1853. $replacement = ' $permissions[\''.addslashes($entity).'\'][permissions::'.strtoupper($grant).'()] ';
  1854. // check for just the grant in a string
  1855. $evalString = preg_replace('/^'.$grant.'$/', $replacement, $evalString);
  1856. // check for the grant at the begining of a string
  1857. $evalString = preg_replace('/^'.$grant.'\\s/', $replacement, $evalString);
  1858. // check for the grant in the middle of the string
  1859. $evalString = preg_replace('/\\s'.$grant.'\\s/', $replacement, $evalString);
  1860. // check for the grant at the end of the string
  1861. $evalString = preg_replace('/\\s'.$grant.'$/', $replacement, $evalString);
  1862. }
  1863. $evalStrings[] = "(".$evalString.")";
  1864. }
  1865. // Debugging line
  1866. // print "\n<br />Checking hasPermission '$perms' for '$user' ".get_class($this)." ".$this->name." / ".$this->id." - ".$this->getField("title");
  1867. // print "\n<br />Permissions = ".printpre($permissions,TRUE);
  1868. // print "\n<br />entitiesToCheck = ".printpre($entitiesToCheck,TRUE);
  1869. // ------- Check the permissions ----------
  1870. $hasPermission = FALSE;
  1871. // 'OR' the permissions of each entity together so that if one is valid,
  1872. // the user has permission.
  1873. $condition = '$hasPermission = ('.implode(" || ",$evalStrings).')?TRUE:FALSE;';
  1874. // printOb0("\n<hr/>");
  1875. // printOb0(printpre($condition, true));
  1876. eval($condition);
  1877. // printOb0("<br/><br/>HasPermission=".var_dumpPre($hasPermission, true));
  1878. // Cache the permissions
  1879. if ($useronly)
  1880. $this->cachedPermissions["onlyuser".$user.$perms] = $hasPermission;
  1881. else
  1882. $this->cachedPermissions[$user.$perms] = $hasPermission;
  1883. // ------- return our result -----------
  1884. return $hasPermission;
  1885. }
  1886. /******************************************************************************
  1887. * hasPermissionsDown checks if user (or usergroup) has permissions
  1888. * to access all children
  1889. ******************************************************************************/
  1890. function hasPermissionDown($perms,$user='',$useronly=0,$fetch=0) {
  1891. if ($fetch) {
  1892. if (!$this->fetcheddown) $this->fetchDown();
  1893. }
  1894. if ($this->hasPermission($perms,$user,$useronly)) {
  1895. return true;
  1896. }
  1897. $class = get_class($this);
  1898. $ar = $this->_object_arrays[$class];
  1899. if ($ar) {
  1900. $a = &$this->$ar;
  1901. if ($a) {
  1902. foreach ($a as $i=>$o) {
  1903. if($a[$i]->hasPermissionDown($perms,$user,$useronly)) return true;
  1904. }
  1905. }
  1906. }
  1907. return false;
  1908. }
  1909. /******************************************************************************
  1910. * returnEditorOverlap checks to see if user is in group or class
  1911. * and merges permissions of group and class
  1912. ******************************************************************************/
  1913. function returnEditorOverlap($classes) {
  1914. $toCheck = array();
  1915. // print_r($classes);
  1916. foreach ($this->editors as $u) {
  1917. $good=0;
  1918. // print "$u - ";
  1919. // if (isclass($u)) print "class";
  1920. $c = array();
  1921. if (isclass($u)) $c[] = $u;
  1922. if ($g = isgroup($u)) $c = array_merge($c,$g);
  1923. foreach($c as $class) {
  1924. if (is_array($classes[$class])) $good=1;
  1925. }
  1926. if ($good) $toCheck[]=$u;
  1927. }
  1928. /* print_r($toCheck); */
  1929. return $toCheck;
  1930. }
  1931. }