PageRenderTime 51ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/concreteOLD/models/page.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 2554 lines | 1738 code | 376 blank | 440 comment | 323 complexity | b56bdeceef3bcb9c62522eb2f617a424 MD5 | raw file
  1. <?php
  2. defined('C5_EXECUTE') or die("Access Denied.");
  3. /**
  4. *
  5. * The page object in Concrete encapsulates all the functionality used by a typical page and their contents
  6. * including blocks, page metadata, page permissions.
  7. * @package Pages
  8. *
  9. */
  10. class Page extends Collection {
  11. protected $blocksAliasedFromMasterCollection = null;
  12. /**
  13. * @param string $path /path/to/page
  14. * @param string $version ACTIVE or RECENT
  15. * @return Page
  16. */
  17. public static function getByPath($path, $version = 'RECENT') {
  18. $path = rtrim($path, '/'); // if the path ends in a / remove it.
  19. $cID = Cache::get('page_id_from_path', $path);
  20. if ($cID == false) {
  21. $db = Loader::db();
  22. $cID = $db->GetOne("select cID from PagePaths where cPath = ?", array($path));
  23. Cache::set("page_id_from_path", $path, $cID);
  24. }
  25. return Page::getByID($cID, $version);
  26. }
  27. /**
  28. * @param int $cID Collection ID of a page
  29. * @param string $versionOrig ACTIVE or RECENT
  30. * @param string $class
  31. * @return Page
  32. */
  33. public static function getByID($cID, $versionOrig = 'RECENT', $class = 'Page') {
  34. if ($versionOrig) {
  35. $version = CollectionVersion::getNumericalVersionID($cID, $versionOrig);
  36. }
  37. $ca = new Cache();
  38. $c = ($version > 0) ? $ca->get(strtolower($class), $cID . ':' . $version) : '';
  39. if ($c instanceof $class) {
  40. return $c;
  41. }
  42. $where = "where Pages.cID = ?";
  43. $c = new $class;
  44. $c->populatePage($cID, $where, $version);
  45. // must use cID instead of c->getCollectionID() because cID may be the pointer to another page
  46. if ($version > 0) {
  47. $ca->set(strtolower($class), $cID . ':' . $version, $c);
  48. }
  49. return $c;
  50. }
  51. /**
  52. * @access private
  53. */
  54. protected function populatePage($cInfo, $where, $cvID) {
  55. $db = Loader::db();
  56. $q0 = "select Pages.cID, Pages.pkgID, Pages.cPointerID, Pages.cPointerExternalLink, Pages.cIsActive, Pages.cIsSystemPage, Pages.cPointerExternalLinkNewWindow, Pages.cFilename, Collections.cDateAdded, Pages.cDisplayOrder, Collections.cDateModified, cInheritPermissionsFromCID, cInheritPermissionsFrom, cOverrideTemplatePermissions, cPendingAction, cPendingActionUID, cPendingActionTargetCID, cPendingActionDatetime, cCheckedOutUID, cIsTemplate, uID, cPath, Pages.ctID, ctHandle, ctIcon, ptID, cParentID, cChildren, ctName, cCacheFullPageContent, cCacheFullPageContentOverrideLifetime, cCacheFullPageContentLifetimeCustom from Pages inner join Collections on Pages.cID = Collections.cID left join PageTypes on (PageTypes.ctID = Pages.ctID) left join PagePaths on (Pages.cID = PagePaths.cID and PagePaths.ppIsCanonical = 1) ";
  57. //$q2 = "select cParentID, cPointerID, cPath, Pages.cID from Pages left join PagePaths on (Pages.cID = PagePaths.cID and PagePaths.ppIsCanonical = 1) ";
  58. $v = array($cInfo);
  59. $r = $db->query($q0 . $where, $v);
  60. $row = $r->fetchRow();
  61. if ($row['cPointerID'] > 0) {
  62. $q1 = $q0 . "where Pages.cID = ?";
  63. $cPointerOriginalID = $row['cID'];
  64. $v = array($row['cPointerID']);
  65. $cParentIDOverride = $row['cParentID'];
  66. $cPathOverride = $row['cPath'];
  67. $cPointerID = $row['cPointerID'];
  68. $cDisplayOrderOverride = $row['cDisplayOrder'];
  69. $r = $db->query($q1, $v);
  70. $row = $r->fetchRow();
  71. }
  72. if ($r) {
  73. if ($row) {
  74. foreach ($row as $key => $value) {
  75. $this->{$key} = $value;
  76. }
  77. if (isset($cParentIDOverride)) {
  78. $this->cPointerID = $cPointerID;
  79. $this->cPointerOriginalID = $cPointerOriginalID;
  80. $this->cPath = $cPathOverride;
  81. $this->cParentID = $cParentIDOverride;
  82. }
  83. $this->isMasterCollection = $row['cIsTemplate'];
  84. } else {
  85. if ($cInfo == 1) {
  86. $this->cID = '1';
  87. $this->loadError(COLLECTION_INIT);
  88. } else {
  89. // there was no record of this particular collection in the database
  90. $this->loadError(COLLECTION_NOT_FOUND);
  91. }
  92. }
  93. $r->free();
  94. } else {
  95. $this->loadError(COLLECTION_NOT_FOUND);
  96. }
  97. if ($cvID != false) {
  98. // we don't do this on the front page
  99. $this->loadVersionObject($cvID);
  100. }
  101. unset($r);
  102. }
  103. /**
  104. * Returns 1 if the page is in edit mode
  105. * @return bool
  106. */
  107. public function isEditMode() {
  108. $v = View::getInstance();
  109. return ($this->isCheckedOutByMe() && ($v->editingEnabled()));
  110. }
  111. /**
  112. * Get the package ID for a page (page thats added by a package) (returns 0 if its not in a package)
  113. * @return int
  114. */
  115. public function getPackageID() {return $this->pkgID;}
  116. /**
  117. * Get the package handle for a page (page thats added by a package)
  118. * @return string
  119. */
  120. public function getPackageHandle() {
  121. return PackageList::getHandle($this->pkgID);
  122. }
  123. /**
  124. * Returns 1 if the page is in arrange mode
  125. * @return bool
  126. */
  127. public function isArrangeMode() {return ($this->isCheckedOutByMe() && ($_REQUEST['btask'] == 'arrange'));}
  128. /**
  129. * Forces the page to be checked in if its checked out
  130. */
  131. public function forceCheckIn() {
  132. // This function forces checkin to take place
  133. $db = Loader::db();
  134. $q = "update Pages set cIsCheckedOut = 0, cCheckedOutUID = null, cCheckedOutDatetime = null, cCheckedOutDatetimeLastEdit = null where cID = '{$this->cID}'";
  135. $r = $db->query($q);
  136. }
  137. /**
  138. * Checks if the page is a dashboard page, returns true if it is
  139. * @return bool
  140. */
  141. public function isAdminArea() {
  142. if ($this->isGeneratedCollection()) {
  143. $pos = strpos($this->getCollectionFilename(), "/" . DIRNAME_DASHBOARD);
  144. return ($pos > -1);
  145. }
  146. return false;
  147. }
  148. /**
  149. * Takes an array of area/block values and makes that the arrangement for this page's version
  150. * Format is like: $area[10][0] = 2, $area[10][1] = 8, $area[15][0] = 27, with the area ID being the
  151. * key and the block IDs being 1-n values inside it
  152. * @param array $areas
  153. */
  154. public function processArrangement($areas) {
  155. // this function is called via ajax, so it's a bit wonky, but the format is generally
  156. // a{areaID} = array(b1, b2, b3) (where b1, etc... are blocks with ids appended.)
  157. $db = Loader::db();
  158. $db->Execute('delete from CollectionVersionBlockStyles where cID = ? and cvID = ?', array($this->getCollectionID(), $this->getVersionID()));
  159. foreach($areas as $arID => $blocks) {
  160. if (intval($arID) > 0) {
  161. // this is a serialized area;
  162. $arHandle = $db->getOne("select arHandle from Areas where arID = ?", array($arID));
  163. $startDO = 0;
  164. foreach($blocks as $bIdentifier) {
  165. $bID = 0;
  166. $csrID = 0;
  167. $bd2 = explode('-', $bIdentifier);
  168. $bID = $bd2[0];
  169. $csrID = $bd2[1];
  170. if (intval($bID) > 0) {
  171. $v = array($startDO, $arHandle, $bID, $this->getCollectionID(), $this->getVersionID());
  172. try {
  173. $db->query("update CollectionVersionBlocks set cbDisplayOrder = ?, arHandle = ? where bID = ? and cID = ? and (cvID = ? or cbIncludeAll = 1)", $v);
  174. if ($csrID > 0) {
  175. $db->query("insert into CollectionVersionBlockStyles (csrID, arHandle, bID, cID, cvID) values (?, ?, ?, ?, ?)", array(
  176. $csrID, $arHandle, $bID, $this->getCollectionID(), $this->getVersionID()
  177. ));
  178. }
  179. // update the style for any of these blocks
  180. } catch(Exception $e) {}
  181. $startDO++;
  182. }
  183. }
  184. }
  185. }
  186. Cache::delete('collection_blocks', $this->getCollectionID() . ':' . $this->getVersionID());
  187. }
  188. /**
  189. * checks if the page is checked out, if it is return true
  190. * @return bool
  191. */
  192. function isCheckedOut() {
  193. // function to inform us as to whether the current collection is checked out
  194. $db = Loader::db();
  195. if (isset($this->isCheckedOutCache)) {
  196. return $this->isCheckedOutCache;
  197. }
  198. $dh = Loader::helper('date');
  199. $q = "select cIsCheckedOut, UNIX_TIMESTAMP('" . $dh->getSystemDateTime() . "') - UNIX_TIMESTAMP(cCheckedOutDatetimeLastEdit) as timeout from Pages where cID = '{$this->cID}'";
  200. $r = $db->query($q);
  201. if ($r) {
  202. $row = $r->fetchRow();
  203. if ($row['cIsCheckedOut'] == 0) {
  204. return false;
  205. } else {
  206. if ($row['timeout'] > CHECKOUT_TIMEOUT) {
  207. $this->forceCheckIn();
  208. $this->isCheckedOutCache = false;
  209. return false;
  210. } else {
  211. $this->isCheckedOutCache = true;
  212. return true;
  213. }
  214. }
  215. }
  216. }
  217. /**
  218. * Gets the user that is editing the current page.
  219. * $return string $name
  220. */
  221. public function getCollectionCheckedOutUserName() {
  222. $db = Loader::db();
  223. $query = "select cCheckedOutUID from Pages where cID = ?";
  224. $vals=array($this->cID);
  225. $checkedOutId = $db->getOne($query, $vals);
  226. if(is_object(UserInfo::getByID($checkedOutId))){
  227. $ui = UserInfo::getByID($checkedOutId);
  228. $name=$ui->getUserName();
  229. }else{
  230. $name= t('Unknown User');
  231. }
  232. return $name;
  233. }
  234. /**
  235. * Checks if the page is checked out by the current user
  236. * @return bool
  237. */
  238. function isCheckedOutByMe() {
  239. $u = new User();
  240. return ($this->getCollectionCheckedOutUserID() > 0 && $this->getCollectionCheckedOutUserID() == $u->getUserID());
  241. }
  242. /**
  243. * Checks if the page is a single page
  244. * @return bool
  245. */
  246. function isGeneratedCollection() {
  247. // generated collections are collections without types, that have special cFilename attributes
  248. return $this->cFilename != null && $this->ctID == 0;
  249. }
  250. /**
  251. * Assign permissions to a page based on an array
  252. * <code>
  253. * $pxml->guests['canRead'] = 1;
  254. * $pxml->registered['canWrite'] = 1;
  255. * $pxml->group[0]['canWrite'] = 1;
  256. * $pxml->group[0]['canRead'] = 1;
  257. * </code>
  258. * @param array $permissionsArray
  259. */
  260. function assignPermissionSet($permissionsArray) {
  261. $db = Loader::db();
  262. // first, we make sure to set this collection's permission inheritance to override
  263. if ($this->getCollectionInheritance() != 'OVERRIDE') {
  264. // now, if we were inheriting permissions from elsewhere, we'll grab those, copy them to this node, before we
  265. // assign/add new permission
  266. $v = array($this->getPermissionsCollectionID());
  267. $q = "select cID, uID, gID, cgPermissions, cgStartDate, cgEndDate from PagePermissions where cID = ?";
  268. $r = $db->query($q, $v);
  269. while($row = $r->fetchRow()) {
  270. $v = array($this->cID, $row['uID'], $row['gID'], $row['cgPermissions'], $row['cgStartDate'], $row['cgEndDate']);
  271. $q = "insert into PagePermissions (cID, uID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?, ?)";
  272. $db->query($q, $v);
  273. }
  274. $v = array($this->getPermissionsCollectionID());
  275. $q = "select cID, uID, gID, ctID from PagePermissionPageTypes where cID = ?";
  276. $r = $db->query($q, $v);
  277. while($row = $r->fetchRow()) {
  278. $v = array($this->cID, $row['uID'], $row['gID'], $row['ctID']);
  279. $q = "insert into PagePermissionPageTypes (cID, uID, gID, ctID) values (?, ?, ?, ?)";
  280. $db->query($q, $v);
  281. }
  282. // ack - we need to copy area permissions from that page as well
  283. // wait, i'm not sure if we need to do this anymore.
  284. $v = array($this->getPermissionsCollectionID());
  285. $q = "select cID, arHandle, gID, uID, agPermissions from AreaGroups where cID = ?";
  286. $r = $db->query($q, $v);
  287. while($row = $r->fetchRow()) {
  288. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['agPermissions']);
  289. $q = "insert into AreaGroups (cID, arHandle, gID, uID, agPermissions) values (?, ?, ?, ?, ?)";
  290. $db->query($q, $v);
  291. }
  292. $v = array($this->getPermissionsCollectionID());
  293. $q = "select cID, arHandle, gID, uID, btID from AreaGroupBlockTypes where cID = ?";
  294. $r = $db->query($q, $v);
  295. while($row = $r->fetchRow()) {
  296. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['btID']);
  297. $q = "insert into AreaGroupBlockTypes (cID, arHandle, gID, uID, btID) values (?, ?, ?, ?, ?)";
  298. $db->query($q, $v);
  299. }
  300. }
  301. // now that we're done copying, we set the collection to override
  302. $q = "update Pages set cInheritPermissionsFromCID = {$this->cID}, cInheritPermissionsFrom = 'OVERRIDE' where cID = {$this->cID}";
  303. $r = $db->query($q);
  304. $this->cInheritPermissionsFromCID = $this->cID;
  305. $this->cInheritPermissionsFrom = 'OVERRIDE';
  306. // permissions format is read from XML into an array by simplexml
  307. // this gets us something like this
  308. // $pxml->guests['canRead'] = 1;
  309. // $pxml->registered['canWrite'] = 1;
  310. // $pxml->group[0]['canWrite'] = 1;
  311. // $pxml->group[0]['canRead'] = 1;
  312. $px = $permissionsArray;
  313. // this is too verbose but i don't know of a good place to stash a reusable function :-(
  314. // not sure if we want to ALWAYS remove permissions for everything then stack the new ones
  315. // or not, so for now i'm commenting out the selective removal and removing everything
  316. // THIS IS DUMB: If you want to turn off permissions for a group don't auto-delete them just make sure
  317. // your permissions XML set's them to not be able to read
  318. //$db->query("delete from PagePermissions where cID = '{$this->cID}'");
  319. if (isset($px->guests)) {
  320. $permissions = Permissions::buildPermissionsFromArray($px->guests);
  321. $q = "delete from PagePermissions where cID = '{$this->cID}' and gID = " . GUEST_GROUP_ID;
  322. $r = $db->query($q);
  323. if ($permissions != '') {
  324. $v = array($this->cID, GUEST_GROUP_ID, $permissions, $px->guests['cgStartDate'], $px->guests['cgEndDate']);
  325. $q = "insert into PagePermissions (cID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  326. $db->query($q, $v);
  327. }
  328. }
  329. if (isset($px->registered)) {
  330. $permissions = Permissions::buildPermissionsFromArray($px->registered);
  331. $q = "delete from PagePermissions where cID = '{$this->cID}' and gID = " . REGISTERED_GROUP_ID;
  332. $r = $db->query($q);
  333. if ($permissions != '') {
  334. $v = array($this->cID, REGISTERED_GROUP_ID, $permissions, $px->registered['cgStartDate'], $px->registered['cgEndDate']);
  335. $q = "insert into PagePermissions (cID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  336. $db->query($q, $v);
  337. }
  338. }
  339. if (isset($px->administrators)) {
  340. $permissions = Permissions::buildPermissionsFromArray($px->administrators);
  341. $q = "delete from PagePermissions where cID = '{$this->cID}' and gID = " . ADMIN_GROUP_ID;
  342. $r = $db->query($q);
  343. if ($permissions != '') {
  344. $v = array($this->cID, ADMIN_GROUP_ID, $permissions, $px->administrators['cgStartDate'], $px->administrators['cgEndDate']);
  345. $q = "insert into PagePermissions (cID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  346. $db->query($q, $v);
  347. }
  348. }
  349. if (isset($px->group)) {
  350. foreach($px->group as $g) {
  351. $permissions = Permissions::buildPermissionsFromArray($g);
  352. $gID = $g['gID'];
  353. if (isset($g['gName'])) {
  354. $gID = $db->getOne("select gID from Groups where gName = ?", array($g['gName']));
  355. }
  356. $q = "delete from PagePermissions where cID = '{$this->cID}' and gID = " . $gID;
  357. $r = $db->query($q);
  358. if ($permissions != '') {
  359. $v = array($this->cID, $gID, $permissions, $g['cgStartDate'], $g['cgEndDate']);
  360. $q = "insert into PagePermissions (cID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  361. $db->query($q, $v);
  362. }
  363. }
  364. }
  365. if (isset($px->user)) {
  366. foreach($px->user as $_u) {
  367. $permissions = Permissions::buildPermissionsFromArray($_u);
  368. $uID = $_u['uID'];
  369. if (isset($_u['uName'])) {
  370. $uID = $db->getOne("select uID from Users where uName = ?", array($_u['uName']));
  371. }
  372. $q = "delete from PagePermissions where cID = '{$this->cID}' and uID = " . $uID;
  373. $r = $db->query($q);
  374. if ($permissions != '') {
  375. $v = array($this->cID, $uID, $permissions, $_u['cgStartDate'], $_u['cgEndDate']);
  376. $q = "insert into PagePermissions (cID, uID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  377. $db->query($q, $v);
  378. }
  379. }
  380. }
  381. $this->refreshCache();
  382. }
  383. /**
  384. * Make an alias to a page
  385. * @param Collection $c
  386. * @return int $newCID
  387. */
  388. function addCollectionAlias($c) {
  389. $db = Loader::db();
  390. // the passed collection is the parent collection
  391. $cParentID = $c->getCollectionID();
  392. $u = new User();
  393. $uID = $u->getUserID();
  394. $ctID = 0;
  395. $dh = Loader::helper('date');
  396. $cDate = $dh->getSystemDateTime();
  397. $cDatePublic = $dh->getSystemDateTime();
  398. $handle = $this->getCollectionHandle();
  399. $_cParentID = $c->getCollectionID();
  400. $q = "select PagePaths.cPath from PagePaths where cID = '{$_cParentID}'";
  401. if ($_cParentID > 1) {
  402. $q .= " and ppIsCanonical = 1";
  403. }
  404. $cPath = $db->getOne($q);
  405. $data['handle'] = $this->getCollectionHandle();
  406. $data['name'] = $this->getCollectionName();
  407. $cobj = parent::add($data);
  408. $newCID = $cobj->getCollectionID();
  409. $v = array($newCID, $ctID, $cParentID, $uID, $this->getCollectionID());
  410. $q = "insert into Pages (cID, ctID, cParentID, uID, cPointerID) values (?, ?, ?, ?, ?)";
  411. $r = $db->prepare($q);
  412. $res = $db->execute($r, $v);
  413. $newCID = $db->Insert_ID();
  414. Loader::model('page_statistics');
  415. PageStatistics::incrementParents($newCID);
  416. $q2 = "insert into PagePaths (cID, cPath) values (?, ?)";
  417. $v2 = array($newCID, $cPath . '/' . $handle);
  418. $db->query($q2, $v2);
  419. $c->refreshCache();
  420. return $newCID;
  421. }
  422. /**
  423. * Update the name, link, and to open in a new window for an external link
  424. * @param string $cName
  425. * @param string $cLink
  426. * @param bool $newWindow
  427. */
  428. function updateCollectionAliasExternal($cName, $cLink, $newWindow = 0) {
  429. if ($this->cPointerExternalLink != '') {
  430. $db = Loader::db();
  431. $this->markModified();
  432. if ($newWindow) {
  433. $newWindow = 1;
  434. } else {
  435. $newWindow = 0;
  436. }
  437. $db->query("update CollectionVersions set cvName = ? where cID = ?", array($cName, $this->cID));
  438. $db->query("update Pages set cPointerExternalLink = ?, cPointerExternalLinkNewWindow = ? where cID = ?", array($cLink, $newWindow, $this->cID));
  439. $this->refreshCache();
  440. }
  441. }
  442. /**
  443. * Add a new external link
  444. * @param string $cName
  445. * @param string $cLink
  446. * @param bool $newWindow
  447. * @return int $newCID
  448. */
  449. function addCollectionAliasExternal($cName, $cLink, $newWindow = 0) {
  450. $db = Loader::db();
  451. $dh = Loader::helper('date');
  452. $dt = Loader::helper('text');
  453. $u = new User();
  454. $cParentID = $this->getCollectionID();
  455. $uID = $u->getUserID();
  456. $ctID = 0;
  457. $cDate = $dh->getSystemDateTime();
  458. $cDatePublic = $dh->getSystemDateTime();
  459. $handle = $this->getCollectionHandle();
  460. // make the handle out of the title
  461. $handle = $dt->sanitizeFileSystem($cLink);
  462. $data['handle'] = $handle;
  463. $data['name'] = $cName;
  464. $cobj = parent::add($data);
  465. $newCID = $cobj->getCollectionID();
  466. if ($newWindow) {
  467. $newWindow = 1;
  468. } else {
  469. $newWindow = 0;
  470. }
  471. $v = array($newCID, $ctID, $cParentID, $uID, $cLink, $newWindow);
  472. $q = "insert into Pages (cID, ctID, cParentID, uID, cPointerExternalLink, cPointerExternalLinkNewWindow) values (?, ?, ?, ?, ?, ?)";
  473. $r = $db->prepare($q);
  474. $res = $db->execute($r, $v);
  475. $newCID = $db->Insert_ID();
  476. Loader::model('page_statistics');
  477. PageStatistics::incrementParents($newCID);
  478. return $newCID;
  479. }
  480. /**
  481. * Check if a page is a single page that is in the core (/concrete directory)
  482. * @return bool
  483. */
  484. public function isSystemPage() {
  485. return $this->cIsSystemPage;
  486. }
  487. /**
  488. * Gets the icon for a page (also fires the on_page_get_icon event)
  489. * @return string $icon Path to the icon
  490. */
  491. public function getCollectionIcon() {
  492. // returns a fully qualified image link for this page's icon, either based on its collection type or if icon.png appears in its view directory
  493. $icon = '';
  494. $icon = Events::fire('on_page_get_icon', $this);
  495. if ($icon) {
  496. return $icon;
  497. }
  498. if ($this->isGeneratedCollection()) {
  499. if ($this->getPackageID() > 0) {
  500. if (is_dir(DIR_PACKAGES . '/' . $this->getPackageHandle())) {
  501. $dirp = DIR_PACKAGES;
  502. $url = BASE_URL . DIR_REL;
  503. } else {
  504. $dirp = DIR_PACKAGES_CORE;
  505. $url = ASSETS_URL;
  506. }
  507. $file = $dirp . '/' . $this->getPackageHandle() . '/' . DIRNAME_PAGES . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON;
  508. if (file_exists($file)) {
  509. $icon = $url . '/' . DIRNAME_PACKAGES . '/' . $this->getPackageHandle() . '/' . DIRNAME_PAGES . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON;
  510. }
  511. } else if (file_exists(DIR_FILES_CONTENT . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON)) {
  512. $icon = BASE_URL . DIR_REL . '/' . DIRNAME_PAGES . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON;
  513. } else if (file_exists(DIR_FILES_CONTENT_REQUIRED . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON)) {
  514. $icon = ASSETS_URL . '/' . DIRNAME_PAGES . $this->getCollectionPath() . '/' . FILENAME_PAGE_ICON;
  515. }
  516. } else {
  517. }
  518. return $icon;
  519. }
  520. /**
  521. * Remove an external link/alias
  522. * @return int $cIDRedir cID for the original page if the page was an alias
  523. */
  524. function removeThisAlias() {
  525. $cIDRedir = $this->getCollectionPointerID();
  526. $cPointerExternalLink = $this->getCollectionPointerExternalLink();
  527. parent::refreshCache();
  528. if ($cPointerExternalLink != '') {
  529. $this->delete();
  530. } else if ($cIDRedir > 0) {
  531. $db = Loader::db();
  532. Loader::model('page_statistics');
  533. PageStatistics::decrementParents($this->getCollectionPointerOriginalID());
  534. $args = array($this->getCollectionPointerOriginalID());
  535. $q = "delete from Pages where cID = ?";
  536. $r = $db->query($q, $args);
  537. $q = "delete from Collections where cID = ?";
  538. $r = $db->query($q, $args);
  539. $q = "delete from CollectionVersions where cID = ?";
  540. $r = $db->query($q, $args);
  541. $q = "delete from PagePaths where cID = ?";
  542. $r = $db->query($q, $args);
  543. Cache::delete('page', $this->getCollectionPointerOriginalID() );
  544. Cache::delete('page_path', $this->getCollectionPointerOriginalID() );
  545. Cache::delete('request_path_page', $this->getCollectionPointerOriginalID() );
  546. return $cIDRedir;
  547. }
  548. }
  549. public function export($pageNode) {
  550. $p = $pageNode->addChild('page');
  551. $p->addAttribute('name', Loader::helper('text')->entities($this->getCollectionName()));
  552. $p->addAttribute('path', $this->getCollectionPath());
  553. $p->addAttribute('filename', $this->getCollectionFilename());
  554. $p->addAttribute('pagetype', $this->getCollectionTypeHandle());
  555. $p->addAttribute('description', Loader::helper('text')->entities($this->getCollectionDescription()));
  556. $p->addAttribute('package', $this->getPackageHandle());
  557. if ($this->getCollectionParentID() == 0 && $this->isSystemPage()) {
  558. $p->addAttribute('root', 'true');
  559. }
  560. $attribs = $this->getSetCollectionAttributes();
  561. if (count($attribs) > 0) {
  562. $attributes = $p->addChild('attributes');
  563. foreach($attribs as $ak) {
  564. $av = $this->getAttributeValueObject($ak);
  565. $cnt = $ak->getController();
  566. $cnt->setAttributeValue($av);
  567. $akx = $attributes->addChild('attributekey');
  568. $akx->addAttribute('handle', $ak->getAttributeKeyHandle());
  569. $cnt->exportValue($akx);
  570. }
  571. }
  572. $db = Loader::db();
  573. $r = $db->Execute('select arHandle from Areas where cID = ? and arIsGlobal = 0', array($this->getCollectionID()));
  574. while ($row = $r->FetchRow()) {
  575. $ax = Area::get($this, $row['arHandle']);
  576. $ax->export($p, $this);
  577. }
  578. }
  579. /**
  580. * Returns the uID for a page that is checked out
  581. * @return int
  582. */
  583. function getCollectionCheckedOutUserID() {
  584. return $this->cCheckedOutUID;
  585. }
  586. /**
  587. * Gets the allowed sub pages for a page
  588. */
  589. function getAllowedSubCollections() {
  590. return $this->allowedSubCollections;
  591. }
  592. /**
  593. * Returns the path for the current page
  594. * @return string
  595. */
  596. function getCollectionPath() {
  597. return $this->cPath;
  598. }
  599. /**
  600. * Returns the path for a page from its cID
  601. * @param int cID
  602. * @return string $path
  603. */
  604. public static function getCollectionPathFromID($cID) {
  605. $db = Loader::db();
  606. $path = $db->GetOne("select cPath from PagePaths inner join CollectionVersions on (PagePaths.cID = CollectionVersions.cID and CollectionVersions.cvIsApproved = 1) where PagePaths.cID = ?", array($cID));
  607. $path .= '/';
  608. return $path;
  609. }
  610. /**
  611. * Returns the uID for a page ownder
  612. * @return int
  613. */
  614. function getCollectionUserID() {
  615. return $this->uID;
  616. }
  617. /**
  618. * Returns the page's handle
  619. * @return string
  620. */
  621. function getCollectionHandle() {
  622. return $this->vObj->cvHandle;
  623. }
  624. /**
  625. * Returns the page's name
  626. * @return string
  627. */
  628. function getCollectionTypeName() {
  629. return $this->ctName;
  630. }
  631. /**
  632. * Returns the Collection Type ID
  633. * @return int
  634. */
  635. function getCollectionTypeID() {
  636. return $this->ctID;
  637. }
  638. /**
  639. * Returns the Collection Type handle
  640. * @return string
  641. */
  642. function getCollectionTypeHandle() {
  643. return $this->ctHandle;
  644. }
  645. /**
  646. * Returns theme id for the collection
  647. * @return int
  648. */
  649. function getCollectionThemeID() {
  650. if ($this->ptID < 1 && $this->cID != HOME_CID) {
  651. $c = Page::getByID(HOME_CID);
  652. return $c->getCollectionThemeID();
  653. } else {
  654. return $this->ptID;
  655. }
  656. }
  657. /**
  658. * Check if a block is an alias from a page default
  659. * @param array $b
  660. * @return bool
  661. */
  662. function isBlockAliasedFromMasterCollection(&$b) {
  663. //Retrieve info for all of this page's blocks at once (and "cache" it)
  664. // so we don't have to query the database separately for every block on the page.
  665. if (is_null($this->blocksAliasedFromMasterCollection)) {
  666. $db = Loader::db();
  667. $q = 'SELECT bID FROM CollectionVersionBlocks WHERE cID = ? AND isOriginal = 0 AND cvID = ? AND bID IN (SELECT bID FROM CollectionVersionBlocks AS cvb2 WHERE cvb2.cid = ?)';
  668. $v = array($this->getCollectionID(), $this->getVersionObject()->getVersionID(), $this->getMasterCollectionID());
  669. $r = $db->execute($q, $v);
  670. $this->blocksAliasedFromMasterCollection = $db->GetCol($q, $v);
  671. }
  672. return ($b->isAlias() && in_array($b->getBlockID(), $this->blocksAliasedFromMasterCollection));
  673. }
  674. /**
  675. * Returns Collection's theme object
  676. * @return PageTheme
  677. */
  678. function getCollectionThemeObject() {
  679. if ($this->ptID < 1) {
  680. return PageTheme::getSiteTheme();
  681. } else {
  682. $pl = PageTheme::getByID($this->ptID);
  683. return $pl;
  684. }
  685. }
  686. /**
  687. * Returns the page's name
  688. * @return string
  689. */
  690. function getCollectionName() {
  691. if (isset($this->vObj)) {
  692. return $this->vObj->cvName;
  693. }
  694. return $this->cvName;
  695. }
  696. /**
  697. * Returns the collection ID for the aliased page (returns 0 unless used on an actual alias)
  698. * @return int
  699. */
  700. function getCollectionPointerID() {
  701. return $this->cPointerID;
  702. }
  703. /**
  704. * Returns link for the aliased page
  705. * @return string
  706. */
  707. function getCollectionPointerExternalLink() {
  708. return $this->cPointerExternalLink;
  709. }
  710. /**
  711. * Returns if the alias opens in a new window
  712. * @return bool
  713. */
  714. function openCollectionPointerExternalLinkInNewWindow() {
  715. return $this->cPointerExternalLinkNewWindow;
  716. }
  717. /**
  718. * Checks to see if the page is an alias
  719. * @return bool
  720. */
  721. function isAlias() {
  722. return $this->cPointerID > 0 || $this->cPointerExternalLink != null;
  723. }
  724. /**
  725. * Checks if a page is an external link
  726. * @return bool
  727. */
  728. function isExternalLink() {
  729. return ($this->cPointerExternalLink != null);
  730. }
  731. /**
  732. * Get the original cID of a page
  733. * @return int
  734. */
  735. function getCollectionPointerOriginalID() {
  736. return $this->cPointerOriginalID;
  737. }
  738. /**
  739. * Get the file name of a page (single pages)
  740. * @return string
  741. */
  742. function getCollectionFilename() {
  743. return $this->cFilename;
  744. }
  745. /**
  746. * Gets the date a the current version was made public,
  747. * if user is specified, returns in the current user's timezone
  748. * @param string $dateFormat
  749. * @param string $type (system || user)
  750. * @return string date formated like: 2009-01-01 00:00:00
  751. */
  752. function getCollectionDatePublic($dateFormat = null, $type='system') {
  753. if(!$dateFormat) {
  754. $dateFormat = 'Y-m-d H:i:s';
  755. }
  756. if(ENABLE_USER_TIMEZONES && $type == 'user') {
  757. $dh = Loader::helper('date');
  758. return $dh->getLocalDateTime($this->vObj->cvDatePublic, $dateFormat);
  759. } else {
  760. return date($dateFormat, strtotime($this->vObj->cvDatePublic));
  761. }
  762. }
  763. /**
  764. * Get the description of a page
  765. * @return string
  766. */
  767. function getCollectionDescription() {
  768. return $this->vObj->cvDescription;
  769. }
  770. /**
  771. * Gets the cID of the page's parent
  772. * @return int
  773. */
  774. function getCollectionParentID() {
  775. return $this->cParentID;
  776. }
  777. /**
  778. * Get the Parent cID from a page by using a cID
  779. * @param int $cID
  780. * @return int
  781. */
  782. function getCollectionParentIDFromChildID($cID) {
  783. $db = Loader::db();
  784. $q = "select cParentID from Pages where cID = ?";
  785. $cParentID = $db->GetOne($q, array($cID));
  786. return $cParentID;
  787. }
  788. /**
  789. * Returns an array of this cParentID and aliased parentIDs
  790. * @return array $cID
  791. */
  792. function getCollectionParentIDs(){
  793. $cIDs=array($this->cParentID);
  794. $db = Loader::db();
  795. $aliasedParents=$db->getAll('SELECT cParentID FROM Pages WHERE cPointerID='.intval($this->cID).' ');
  796. foreach($aliasedParents as $aliasedParent)
  797. $cIDs[]=$aliasedParent['cParentID'];
  798. return $cIDs;
  799. }
  800. /**
  801. * Checks if a page is a page default
  802. * @return bool
  803. */
  804. function isMasterCollection() {
  805. return $this->isMasterCollection;
  806. }
  807. /**
  808. * Gets the pending action for a page
  809. * @return string
  810. */
  811. function getPendingAction() {
  812. return $this->cPendingAction;
  813. }
  814. /**
  815. * Gets the uID of the user that intiated the pending action
  816. * @return int
  817. */
  818. function getPendingActionUserID() {
  819. return $this->cPendingActionUID;
  820. }
  821. /**
  822. * Gets the pending action date,
  823. * if user is specified, returns in the current user's timezone
  824. * @param string $type (system || user)
  825. * @return string date formated like: 2009-01-01 00:00:00
  826. */
  827. function getPendingActionDateTime($type = 'system') {
  828. if(ENABLE_USER_TIMEZONES && $type == 'user') {
  829. $dh = Loader::helper('date');
  830. return $dh->getLocalDateTime($this->cPendingActionDatetime);
  831. } else {
  832. return $this->cPendingActionDatetime;
  833. }
  834. }
  835. /**
  836. * Gets the cID of the target page (like for deleting)
  837. * @return int
  838. */
  839. function getPendingActionTargetCollectionID() {
  840. return $this->cPendingActionTargetCID;
  841. }
  842. /**
  843. * Checks if the pending action is move
  844. * @return bool
  845. */
  846. function isPendingMove() {
  847. return ($this->cPendingAction == 'MOVE');
  848. }
  849. /**
  850. * Checks if the pending action is copy
  851. * @return bool
  852. */
  853. function isPendingCopy() {
  854. return ($this->cPendingAction == 'COPY');
  855. }
  856. /**
  857. * Checks if the pending action is delete
  858. * @return bool
  859. */
  860. function isPendingDelete() {
  861. return ($this->cPendingAction == 'DELETE');
  862. }
  863. /**
  864. * Gets the template permissions
  865. * @return string
  866. */
  867. function overrideTemplatePermissions() {
  868. return $this->cOverrideTemplatePermissions;
  869. }
  870. /**
  871. * Gets the position of the page in the sitemap
  872. * @return int
  873. */
  874. function getCollectionDisplayOrder() {
  875. return $this->cDisplayOrder;
  876. }
  877. /**
  878. * Set the theme for a page using the page object
  879. * @param PageTheme $pl
  880. */
  881. public function setTheme($pl) {
  882. $db = Loader::db();
  883. $db->query('update Pages set ptID = ? where cID = ?', array($pl->getThemeID(), $this->cID));
  884. parent::refreshCache();
  885. }
  886. /**
  887. * Set the permissions of sub-collections added beneath this permissions to inherit from the template
  888. */
  889. function setPermissionsInheritanceToTemplate() {
  890. $db = Loader::db();
  891. if ($this->cID) {
  892. $db->query("update Pages set cOverrideTemplatePermissions = 0 where cID = {$this->cID}");
  893. }
  894. }
  895. /**
  896. * Set the permissions of sub-collections added beneath this permissions to inherit from the parent
  897. */
  898. function setPermissionsInheritanceToOverride() {
  899. $db = Loader::db();
  900. if ($this->cID) {
  901. $db->query("update Pages set cOverrideTemplatePermissions = 1 where cID = {$this->cID}");
  902. }
  903. }
  904. function getPermissionsCollectionID() {
  905. return $this->cInheritPermissionsFromCID;
  906. }
  907. function getCollectionInheritance() {
  908. return $this->cInheritPermissionsFrom;
  909. }
  910. function getParentPermissionsCollectionID() {
  911. $db = Loader::db();
  912. $v = array($this->cParentID);
  913. $q = "select cInheritPermissionsFromCID from Pages where cID = ?";
  914. $ppID = $db->getOne($q, $v);
  915. return $ppID;
  916. }
  917. function getPermissionsCollectionObject() {
  918. return Page::getByID($this->cInheritPermissionsFromCID, "RECENT");
  919. }
  920. function getMasterCollectionID() {
  921. $db = Loader::db();
  922. $q = "select cID from Pages where Pages.ctID = '{$this->ctID}' and cIsTemplate = 1";
  923. $cID = $db->getOne($q);
  924. if ($cID) {
  925. return $cID;
  926. }
  927. }
  928. function getOriginalCollectionID() {
  929. // this is a bit weird...basically, when editing a master collection, we store the
  930. // master collection ID in session, along with the collection ID we were looking at before
  931. // moving to the master collection. This allows us to get back to that original collection
  932. return $_SESSION['ocID'];
  933. }
  934. function getNumChildren() {
  935. return $this->cChildren;
  936. }
  937. function getNumChildrenDirect() {
  938. // direct children only
  939. $db = Loader::db();
  940. $v = array($this->cID);
  941. $num = $db->getOne('select count(cID) as total from Pages where cParentID = ?', $v);
  942. if ($num) {
  943. return $num;
  944. }
  945. return 0;
  946. }
  947. /**
  948. * Returns the first child of the current page, or null if there is no child
  949. * @param string $sortColumn
  950. * @return Page
  951. */
  952. public function getFirstChild($sortColumn = 'cDisplayOrder asc') {
  953. $db = Loader::db();
  954. $cID = $db->GetOne("select Pages.cID from Pages inner join CollectionVersions on Pages.cID = CollectionVersions.cID where cvIsApproved = 1 and cParentID = ? order by {$sortColumn}", array($this->cID));
  955. if ($cID > 1) {
  956. return Page::getByID($cID, "ACTIVE");
  957. }
  958. return false;
  959. }
  960. function getCollectionChildrenArray( $oneLevelOnly=0 ) {
  961. $this->childrenCIDArray = array();
  962. $this->_getNumChildren($this->cID,$oneLevelOnly);
  963. return $this->childrenCIDArray;
  964. }
  965. function _getNumChildren($cID,$oneLevelOnly=0, $sortColumn = 'cDisplayOrder asc') {
  966. $db = Loader::db();
  967. $q = "select cID from Pages left join Packages on Pages.pkgID = Packages.pkgID where cParentID = {$cID} and cIsTemplate = 0 and (Packages.pkgHandle <> 'core' or pkgHandle is null or Pages.ctID > 0) order by {$sortColumn}";
  968. $r = $db->query($q);
  969. if ($r) {
  970. while ($row = $r->fetchRow()) {
  971. if ($row['cID'] > 0) {
  972. $this->childrenCIDArray[] = $row['cID'];
  973. if( !$oneLevelOnly ) $this->_getNumChildren($row['cID']);
  974. }
  975. }
  976. }
  977. }
  978. function canMoveCopyTo($cobj) {
  979. // ensures that we're not moving or copying to a collection inside our part of the tree
  980. $children = $this->getCollectionChildrenArray();
  981. $children[] = $this->getCollectionID();
  982. return (!in_array($cobj->getCollectionID(), $children));
  983. }
  984. function update($data) {
  985. $db = Loader::db();
  986. $vo = $this->getVersionObject();
  987. $cvID = $vo->getVersionID();
  988. $this->markModified();
  989. parent::refreshCache();
  990. $cName = $this->getCollectionName();
  991. $cDescription = $this->getCollectionDescription();
  992. $cDatePublic = $this->getCollectionDatePublic();
  993. $ctID = $this->getCollectionTypeID();
  994. $uID = $this->getCollectionUserID();
  995. $pkgID = $this->getPackageID();
  996. $cFilename = $this->getCollectionFilename();
  997. $rescanTemplatePermissions = false;
  998. $cCacheFullPageContent = $this->cCacheFullPageContent;
  999. $cCacheFullPageContentLifetimeCustom = $this->cCacheFullPageContentLifetimeCustom;
  1000. $cCacheFullPageContentOverrideLifetime = $this->cCacheFullPageContentOverrideLifetime;
  1001. if (isset($data['cName'])) {
  1002. $cName = $data['cName'];
  1003. }
  1004. if (isset($data['cCacheFullPageContent'])) {
  1005. $cCacheFullPageContent = $data['cCacheFullPageContent'];
  1006. }
  1007. if (isset($data['cCacheFullPageContentLifetimeCustom'])) {
  1008. $cCacheFullPageContentLifetimeCustom = $data['cCacheFullPageContentLifetimeCustom'];
  1009. }
  1010. if (isset($data['cCacheFullPageContentOverrideLifetime'])) {
  1011. $cCacheFullPageContentOverrideLifetime = $data['cCacheFullPageContentOverrideLifetime'];
  1012. }
  1013. if (isset($data['cDescription'])) {
  1014. $cDescription = $data['cDescription'];
  1015. }
  1016. if (isset($data['cDatePublic'])) {
  1017. $cDatePublic = $data['cDatePublic'];
  1018. }
  1019. if (isset($data['uID'])) {
  1020. $uID = $data['uID'];
  1021. }
  1022. if (isset($data['ctID'])) {
  1023. $ctID = $data['ctID'];
  1024. // we grab the package that this ct belongs to
  1025. $pkgID = $db->GetOne("select pkgID from PageTypes where ctID = ?", array($data['ctID']));
  1026. $rescanTemplatePermissions = true;
  1027. }
  1028. $txt = Loader::helper('text');
  1029. if (!isset($data['cHandle']) && ($this->getCollectionHandle() != '')) {
  1030. $cHandle = $this->getCollectionHandle();
  1031. } else if (!$data['cHandle']) {
  1032. // make the handle out of the title
  1033. $cHandle = $txt->sanitizeFileSystem($cName);
  1034. } else {
  1035. $cHandle = $txt->sanitizeFileSystem($data['cHandle']);
  1036. }
  1037. $cName = $txt->sanitize($cName);
  1038. // Update the non-canonical page paths
  1039. if (isset($data['ppURL']))
  1040. $this->rescanPagePaths($data['ppURL']);
  1041. if ($this->isGeneratedCollection()) {
  1042. if (isset($data['cFilename'])) {
  1043. $cFilename = $data['cFilename'];
  1044. }
  1045. // we only update a subset
  1046. $v = array($cName, $cHandle, $cDescription, $cDatePublic, $cvID, $this->cID);
  1047. $q = "update CollectionVersions set cvName = ?, cvHandle = ?, cvDescription = ?, cvDatePublic = ? where cvID = ? and cID = ?";
  1048. $r = $db->prepare($q);
  1049. $res = $db->execute($r, $v);
  1050. } else {
  1051. $v = array($cName, $cHandle, $cDescription, $cDatePublic, $cvID, $this->cID);
  1052. $q = "update CollectionVersions set cvName = ?, cvHandle = ?, cvDescription = ?, cvDatePublic = ? where cvID = ? and cID = ?";
  1053. $r = $db->prepare($q);
  1054. $res = $db->execute($r, $v);
  1055. }
  1056. $db->query("update Pages set uID = ?, ctID = ?, pkgID = ?, cFilename = ?, cCacheFullPageContent = ?, cCacheFullPageContentLifetimeCustom = ?, cCacheFullPageContentOverrideLifetime = ? where cID = ?", array($uID, $ctID, $pkgID, $cFilename, $cCacheFullPageContent, $cCacheFullPageContentLifetimeCustom, $cCacheFullPageContentOverrideLifetime, $this->cID));
  1057. if ($rescanTemplatePermissions) {
  1058. if ($this->cInheritPermissionsFrom == 'TEMPLATE') {
  1059. // we make sure to update the cInheritPermissionsFromCID value
  1060. $ct = CollectionType::getByID($ctID);
  1061. $masterC = $ct->getMasterTemplate();
  1062. $db->Execute('update Pages set cInheritPermissionsFromCID = ? where cID = ?', array($masterC->getCollectionID(), $this->getCollectioniD()));
  1063. }
  1064. }
  1065. // run any internal event we have for page update
  1066. // i don't think we need to do this because approve reindexes
  1067. //$this->reindex();
  1068. parent::refreshCache();
  1069. $ret = Events::fire('on_page_update', $this);
  1070. }
  1071. public function uniquifyPagePath($origPath) {
  1072. $db = Loader::db();
  1073. $proceed = false;
  1074. $suffix = 0;
  1075. while ($proceed != true) {
  1076. $newPath = ($suffix == 0) ? $origPath : $origPath . $suffix;
  1077. $v = array($newPath, $this->cID);
  1078. $q = "select cID from PagePaths where cPath = ? and cID <> ?";
  1079. $r = $db->query($q, $v);
  1080. if ($r->numRows() == 0) {
  1081. $proceed = true;
  1082. } else {
  1083. $suffix++;
  1084. }
  1085. }
  1086. return $newPath;
  1087. }
  1088. public function rescanPagePaths($newPaths) {
  1089. $db = Loader::db();
  1090. $txt = Loader::helper('text');
  1091. // First, get the list of page paths from the DB.
  1092. $ppaths = $this->getPagePaths();
  1093. // Second, reset all of their cPath values to null.
  1094. $paths = array();
  1095. foreach ($ppaths as $ppath) {
  1096. if (!$ppath['ppIsCanonical']) {
  1097. $paths[$ppath['ppID']] = null;
  1098. }
  1099. }
  1100. // Third, fill in the cPath values from the user updated data.
  1101. foreach ($newPaths as $key=>$val) {
  1102. if (!empty($val)) {
  1103. // Auto-prepend a slash if one is missing.
  1104. $val = trim($val, '/');
  1105. $val = $txt->sanitizeFileSystem($val, true);
  1106. if ($val{0} != '/') {
  1107. $val = '/' . $val;
  1108. }
  1109. $paths[$key] = $val;
  1110. }
  1111. }
  1112. // Fourth, delete, update, or insert page paths as necessary.
  1113. foreach ($paths as $key=>$val) {
  1114. if (empty($val)) {
  1115. $v = array($this->cID, $key);
  1116. $q = "delete from PagePaths where cID = ? and ppID = ?";
  1117. } else if (is_numeric($key)) {
  1118. $val = $this->uniquifyPagePath($val);
  1119. $v = array($val, $this->cID, $key);
  1120. $q = "update PagePaths set cPath = ?, ppIsCanonical = 0 where cID = ? and ppID = ?";
  1121. } else {
  1122. $val = $this->uniquifyPagePath($val);
  1123. $v = array($this->cID, $val);
  1124. $q = "insert into PagePaths (cID, cPath, ppIsCanonical) values (?, ?, 0)";
  1125. }
  1126. $r = $db->query($q, $v);
  1127. }
  1128. }
  1129. function acquireAreaPermissions($permissionsCollectionID) {
  1130. $v = array($this->cID);
  1131. $db = Loader::db();
  1132. $q = "delete from AreaGroups where cID = ?";
  1133. $db->query($q, $v);
  1134. $q = "delete from AreaGroupBlockTypes where cID = ?";
  1135. $db->query($q, $v);
  1136. // ack - we need to copy area permissions from that page as well
  1137. $v = array($permissionsCollectionID);
  1138. $q = "select cID, arHandle, gID, uID, agPermissions from AreaGroups where cID = ?";
  1139. $r = $db->query($q, $v);
  1140. while($row = $r->fetchRow()) {
  1141. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['agPermissions']);
  1142. $q = "insert into AreaGroups (cID, arHandle, gID, uID, agPermissions) values (?, ?, ?, ?, ?)";
  1143. $db->query($q, $v);
  1144. }
  1145. $v = array($permissionsCollectionID);
  1146. $q = "select cID, arHandle, gID, uID, btID from AreaGroupBlockTypes where cID = ?";
  1147. $r = $db->query($q, $v);
  1148. while($row = $r->fetchRow()) {
  1149. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['btID']);
  1150. $q = "insert into AreaGroupBlockTypes (cID, arHandle, gID, uID, btID) values (?, ?, ?, ?, ?)";
  1151. $db->query($q, $v);
  1152. }
  1153. }
  1154. function updatePermissions($args = null) {
  1155. $db = Loader::db();
  1156. if (!is_array($args)) {
  1157. $args = $_POST; // legacy support
  1158. }
  1159. if ($args['cInheritPermissionsFrom'] == 'OVERRIDE') {
  1160. // we're hitting manual override, which means we need to do permissions updates
  1161. if ($this->getPermissionsCollectionID() != $this->cID) {
  1162. // that means we're selecting override from some collection that _wasn't_ set to override
  1163. // we have to grab the existing area permissions for that collection, then, clear out any
  1164. // area permissions we might have (for some reason) and add them to this collection
  1165. $this->acquireAreaPermissions($this->getPermissionsCollectionID());
  1166. }
  1167. $v = array('OVERRIDE', $this->cID, $this->cID);
  1168. $q = "update Pages set cInheritPermissionsFrom = ?, cInheritPermissionsFromCID = ? where cID = ?";
  1169. $r = $db->query($q, $v);
  1170. $this->updateGroups($args);
  1171. } else {
  1172. // we're not overriding permissions so we don't do those updates
  1173. if ($args['cInheritPermissionsFrom'] == 'PARENT') {
  1174. $cpID = $this->getParentPermissionsCollectionID();
  1175. $this->updatePermissionsCollectionID($this->cID, $cpID);
  1176. } else if ($args['cInheritPermissionsFrom'] == 'TEMPLATE') {
  1177. $cpID = $this->getMasterCollectionID();
  1178. $this->updatePermissionsCollectionID($this->cID, $cpID);
  1179. } else {
  1180. $cpID = $this->getCollectionID();
  1181. }
  1182. $v = array($args['cInheritPermissionsFrom'], $cpID, $this->cID);
  1183. $q = "update Pages set cInheritPermissionsFrom = ?, cInheritPermissionsFromCID = ? where cID = ?";
  1184. $r = $db->query($q, $v);
  1185. $this->cInheritPermissionsFrom = $args['cInheritPermissionsFrom'];
  1186. $this->cInheritPermissionsFromCID = $cpID;
  1187. // we do this because we may be going from a manual override to inheritance, and we don't
  1188. // want any orphaned groups
  1189. $this->clearGroups();
  1190. }
  1191. $cOverrideTemplatePermissions = ($args['cOverrideTemplatePermissions'] == 1) ? 1 : 0;
  1192. $v = array($cOverrideTemplatePermissions, $this->cID);
  1193. $q = "update Pages set cOverrideTemplatePermissions = ? where cID = ?";
  1194. $this->cOverrideTemplatePermissions = $cOverrideTemplatePermissions;
  1195. $arHandles = $db->GetCol('select arHandle from Areas where cID = ?', $this->getCollectionID());
  1196. foreach($arHandles as $arHandle) {
  1197. $a = Area::getOrCreate($this, $arHandle);
  1198. $a->rescanAreaPermissionsChain();
  1199. }
  1200. $blocks = $this->getBlocks();
  1201. foreach($blocks as $b) {
  1202. $b->refreshCache();
  1203. }
  1204. $db->query($q, $v);
  1205. parent::refreshCache();
  1206. }
  1207. public function __destruct() {
  1208. parent::__destruct();
  1209. }
  1210. function updatePermissionsCollectionID($cParentIDString, $npID) {
  1211. // now we iterate through
  1212. $db = Loader::db();
  1213. $pcID = $this->getPermissionsCollectionID();
  1214. $q = "select cID from Pages where cParentID in ({$cParentIDString}) and cInheritPermissionsFromCID = {$pcID}";
  1215. $r = $db->query($q);
  1216. $cList = array();
  1217. while ($row = $r->fetchRow()) {
  1218. $cList[] = $row['cID'];
  1219. }
  1220. if (count($cList) > 0) {
  1221. $cParentIDString = implode(',', $cList);
  1222. $q2 = "update Pages set cInheritPermissionsFromCID = {$npID} where cID in ({$cParentIDString})";
  1223. $r2 = $db->query($q2);
  1224. $this->updatePermissionsCollectionID($cParentIDString, $npID);
  1225. }
  1226. }
  1227. function updateGroupsSubCollection($cParentIDString) {
  1228. // now we iterate through
  1229. $db = Loader::db();
  1230. $pcID = $this->getPermissionsCollectionID();
  1231. $q = "select cID from Pages where cParentID in ({$cParentIDString}) and cInheritPermissionsFrom = 'PARENT'";
  1232. $r = $db->query($q);
  1233. $cList = array();
  1234. while ($row = $r->fetchRow()) {
  1235. $cList[] = $row['cID'];
  1236. }
  1237. if (count($cList) > 0) {
  1238. $cParentIDString = implode(',', $cList);
  1239. $q2 = "update Pages set cInheritPermissionsFromCID = {$this->cID} where cID in ({$cParentIDString})";
  1240. $r2 = $db->query($q2);
  1241. $this->updateGroupsSubCollection($cParentIDString);
  1242. }
  1243. }
  1244. function move($nc, $retainOldPagePath = false) {
  1245. $db = Loader::db();
  1246. $newCParentID = $nc->getCollectionID();
  1247. $dh = Loader::helper('date');
  1248. Loader::model('page_statistics');
  1249. $cID = ($this->getCollectionPointerOriginalID() > 0) ? $this->getCollectionPointerOriginalID() : $this->cID;
  1250. PageStatistics::decrementParents($cID);
  1251. parent::refreshCache();
  1252. $cDateModified = $dh->getSystemDateTime();
  1253. if ($this->getPermissionsCollectionID() != $this->getCollectionID() && $this->getPermissionsCollectionID() != $this->getMasterCollectionID()) {
  1254. // implicitly, we're set to inherit the permissions of wherever we are in the site.
  1255. // as such, we'll change to inherit whatever permissions our new parent has
  1256. $npID = $nc->getPermissionsCollectionID();
  1257. if ($npID != $this->getPermissionsCollectionID()) {
  1258. //we have to update the existing collection with the info for the new
  1259. //as well as all collections beneath it that are set to inherit from this parent
  1260. // first we do this one
  1261. $q = "update Pages set cInheritPermissionsFromCID = {$npID} where cID = {$this->cID}";
  1262. $r = $db->query($q);
  1263. $this->updatePermissionsCollectionID($this->getCollectionID(), $npID);
  1264. }
  1265. }
  1266. $db->query("update Collections set cDateModified = ? where cID = ?", array($cDateModified, $cID));
  1267. $v = array($newCParentID, $cID);
  1268. $q = "update Pages set cParentID = ? where cID = ?";
  1269. $r = $db->prepare($q);
  1270. $res = $db->execute($r, $v);
  1271. PageStatistics::incrementParents($cID);
  1272. if (!$this->isActive()) {
  1273. $this->activate();
  1274. }
  1275. $this->rescanSystemPageStatus();
  1276. // run any event we have for page move. Arguments are
  1277. // 1. current page being moved
  1278. // 2. former parent
  1279. // 3. new parent
  1280. $oldParent = Page::getByID($this->getCollectionParentID(), 'RECENT');
  1281. $newParent = Page::getByID($newCParentID, 'RECENT');
  1282. $oldParent->refreshCache();
  1283. $newParent->refreshCache();
  1284. $ret = Events::fire('on_page_move', $this, $oldParent, $newParent);
  1285. // now that we've moved the collection, we rescan its path
  1286. $this->rescanCollectionPath($retainOldPagePath);
  1287. }
  1288. function duplicateAll($nc, $preserveUserID = false) {
  1289. $db = Loader::db();
  1290. $nc2 = $this->duplicate($nc);
  1291. Page::_duplicateAll($this, $nc2, $preserveUserID);
  1292. return $nc2;
  1293. }
  1294. /**
  1295. * @access private
  1296. **/
  1297. function _duplicateAll($cParent, $cNewParent, $preserveUserID = false) {
  1298. $db = Loader::db();
  1299. $cID = $cParent->getCollectionID();
  1300. $q = "select cID from Pages where cParentID = '{$cID}' order by cDisplayOrder asc";
  1301. $r = $db->query($q);
  1302. if ($r) {
  1303. while ($row = $r->fetchRow()) {
  1304. $tc = Page::getByID($row['cID']);
  1305. $nc = $tc->duplicate($cNewParent, $preserveUserID);
  1306. $tc->_duplicateAll($tc, $nc, $preserveUserID);
  1307. }
  1308. }
  1309. }
  1310. function duplicate($nc, $preserveUserID = false) {
  1311. $db = Loader::db();
  1312. // the passed collection is the parent collection
  1313. $cParentID = $nc->getCollectionID();
  1314. $u = new User();
  1315. $uID = $u->getUserID();
  1316. if ($preserveUserID) {
  1317. $uID = $this->getCollectionUserID();
  1318. }
  1319. $dh = Loader::helper('date');
  1320. $cDate = $dh->getSystemDateTime();
  1321. $cobj = parent::getByID($this->cID);
  1322. // create new name
  1323. $newCollectionName = $this->getCollectionName();
  1324. $index = 1;
  1325. $nameCount = 1;
  1326. while ($nameCount > 0) {
  1327. // if we have a node at the new level with the same name, we keep incrementing til we don't
  1328. $nameCount = $db->GetOne('select count(Pages.cID) from CollectionVersions inner join Pages on (CollectionVersions.cID = Pages.cID and CollectionVersions.cvIsApproved = 1) where Pages.cParentID = ? and CollectionVersions.cvName = ?',
  1329. array($cParentID, $newCollectionName)
  1330. );
  1331. if ($nameCount > 0) {
  1332. $index++;
  1333. $newCollectionName = $this->getCollectionName() . ' ' . $index;
  1334. }
  1335. }
  1336. $newC = $cobj->duplicate();
  1337. $newCID = $newC->getCollectionID();
  1338. $v = array($newCID, $this->getCollectionTypeID(), $cParentID, $uID, $this->overrideTemplatePermissions(), $this->getPermissionsCollectionID(), $this->getCollectionInheritance(), $this->cFilename, $this->cPointerID, $this->cPointerExternalLink, $this->cPointerExternalLinkNewWindow, $this->ptID, $this->cDisplayOrder);
  1339. $q = "insert into Pages (cID, ctID, cParentID, uID, cOverrideTemplatePermissions, cInheritPermissionsFromCID, cInheritPermissionsFrom, cFilename, cPointerID, cPointerExternalLink, cPointerExternalLinkNewWindow, ptID, cDisplayOrder) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
  1340. $res = $db->query($q, $v);
  1341. Loader::model('page_statistics');
  1342. PageStatistics::incrementParents($newCID);
  1343. // now with any specific permissions - but only if this collection is set to override
  1344. if ($this->getCollectionInheritance() == 'OVERRIDE') {
  1345. $q = "select cID, gID, uID, cgPermissions, cgStartDate, cgEndDate from PagePermissions where cID = '{$this->cID}'";
  1346. $r = $db->query($q);
  1347. while ($row = $r->fetchRow()) {
  1348. $vp = array($newCID, $row['gID'], $row['uID'], $row['cgPermissions'], $row['cgStartDate'], $row['cgEndDate']);
  1349. $qp = "insert into PagePermissions (cID, gID, uID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?, ?)";
  1350. $db->query($qp, $vp);
  1351. }
  1352. $q = "select cID, gID, uID, ctID from PagePermissionPageTypes where cID = '{$this->cID}'";
  1353. $r = $db->query($q);
  1354. while ($row = $r->fetchRow()) {
  1355. $vp = array($newCID, $row['gID'], $row['uID'], $row['ctID']);
  1356. $qp = "insert into PagePermissionPageTypes (cID, gID, uID, ctID) values (?, ?, ?, ?)";
  1357. $db->query($qp, $vp);
  1358. }
  1359. $q = "select cID, arHandle, gID, uID, agPermissions from AreaGroups where cID = '{$this->cID}'";
  1360. $r = $db->query($q);
  1361. while($row = $r->fetchRow()) {
  1362. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['agPermissions']);
  1363. $q = "insert into AreaGroups (cID, arHandle, gID, uID, agPermissions) values (?, ?, ?, ?, ?)";
  1364. $db->query($q, $v);
  1365. }
  1366. $q = "select cID, arHandle, gID, uID, btID from AreaGroupBlockTypes where cID = '{$this->cID}'";
  1367. $r = $db->query($q);
  1368. while($row = $r->fetchRow()) {
  1369. $v = array($this->cID, $row['arHandle'], $row['gID'], $row['uID'], $row['btID']);
  1370. $q = "insert into AreaGroupBlockTypes (cID, arHandle, gID, uID, btID) values (?, ?, ?, ?, ?)";
  1371. $db->query($q, $v);
  1372. }
  1373. } else if ($this->getCollectionInheritance() == "PARENT") {
  1374. // we need to clear out any lingering permissions groups (just in case), and set this collection to inherit from the parent
  1375. $npID = $nc->getPermissionsCollectionID();
  1376. $q = "update Pages set cInheritPermissionsFromCID = {$npID} where cID = {$newCID}";
  1377. $r = $db->query($q);
  1378. }
  1379. if ($res) {
  1380. // rescan the collection path
  1381. $nc->refreshCache();
  1382. $nc2 = Page::getByID($newCID);
  1383. if ($index > 1) {
  1384. $args['cName'] = $newCollectionName;
  1385. $args['cHandle'] = $nc2->getCollectionHandle() . '-' . $index;
  1386. }
  1387. $nc2->update($args);
  1388. // arguments for event
  1389. // 1. new page
  1390. // 2. old page
  1391. $ret = Events::fire('on_page_duplicate', $nc2, $this);
  1392. $nc2->rescanCollectionPath();
  1393. return $nc2;
  1394. }
  1395. }
  1396. function delete() {
  1397. Loader::model('page_statistics');
  1398. $cID = $this->getCollectionID();
  1399. if ($cID <= 1) {
  1400. return false;
  1401. }
  1402. $db = Loader::db();
  1403. // run any internal event we have for page deletion
  1404. $ret = Events::fire('on_page_delete', $this);
  1405. if ($ret < 0) {
  1406. return false;
  1407. }
  1408. parent::refreshCache();
  1409. parent::delete();
  1410. $cID = $this->getCollectionID();
  1411. $cParentID = $this->getCollectionParentID();
  1412. // Now that all versions are gone, we can delete the collection information
  1413. $q = "delete from PagePaths where cID = '{$cID}'";
  1414. $r = $db->query($q);
  1415. // remove all pages where the pointer is this cID
  1416. $r = $db->query("select cID from Pages where cPointerID = ?", array($cID));
  1417. while ($row = $r->fetchRow()) {
  1418. PageStatistics::decrementParents($row['cID']);
  1419. }
  1420. // Update cChildren for cParentID
  1421. PageStatistics::decrementParents($cID);
  1422. $q = "delete from PagePermissions where cID = '{$cID}'";
  1423. $r = $db->query($q);
  1424. $q = "delete from Pages where cID = '{$cID}'";
  1425. $r = $db->query($q);
  1426. $q = "delete from Pages where cPointerID = '{$cID}'";
  1427. $r = $db->query($q);
  1428. $q = "delete from Areas WHERE cID = '{$cID}'";
  1429. $r = $db->query($q);
  1430. $q = "delete from ComposerDrafts WHERE cID = '{$cID}'";
  1431. $r = $db->query($q);
  1432. $db->query('delete from PageSearchIndex where cID = ?', array($cID));
  1433. $q = "select cID from Pages where cParentID = '{$cID}'";
  1434. $r = $db->query($q);
  1435. if ($r) {
  1436. while ($row = $r->fetchRow()) {
  1437. if ($row['cID'] > 0) {
  1438. $nc = Page::getByID($row['cID']);
  1439. if( $nc->isAlias() )
  1440. $nc->removeThisAlias();
  1441. else $nc->delete();
  1442. }
  1443. }
  1444. }
  1445. }
  1446. function markPendingAction($action, $targetC = null) {
  1447. // delete() and move() and copy() do the dirty work - this is what is called when a user tries to
  1448. // perform an action - this marks it pending
  1449. if ((!$this->isPendingCopy()) && (!$this->isPendingDelete()) && (!$this->isPendingMove())) {
  1450. $db = Loader::db();
  1451. // can't stack actions
  1452. $u = new User();
  1453. $uID = $u->getUserID();
  1454. $cID = $this->getCollectionID();
  1455. $dh = Loader::helper('date');
  1456. $dateTime = $dh->getSystemDateTime();
  1457. $targetCID = (is_object($targetC)) ? $targetC->getCollectionID() : 0;
  1458. $this->cPendingAction = $action;
  1459. $this->cPendingActionUID = $uID;
  1460. $this->cPendingActionDateTime = $dateTime;
  1461. $this->cPendingActionTargetCID = $targetCID;
  1462. $v = array($action, $uID, $dateTime, $targetCID, $cID);
  1463. $q = "update Pages set cPendingAction = ?, cPendingActionUID = ?, cPendingActionDatetime = ?, cPendingActionTargetCID = ? where cID = ?";
  1464. $r = $db->query($q, $v);
  1465. parent::refreshCache();
  1466. }
  1467. }
  1468. function clearPendingAction() {
  1469. $db = Loader::db();
  1470. $cID = $this->getCollectionID();
  1471. $q = "update Pages set cPendingAction = null, cPendingActionUID = null, cPendingActionDatetime = 0 where cID = {$cID}";
  1472. $r = $db->query($q);
  1473. parent::refreshCache();
  1474. }
  1475. function approvePendingAction() {
  1476. $db = Loader::db();
  1477. switch($this->getPendingAction()) {
  1478. case 'DELETE':
  1479. if (ENABLE_TRASH_CAN) {
  1480. $this->moveToTrash();
  1481. } else {
  1482. $this->delete();
  1483. }
  1484. break;
  1485. case 'MOVE':
  1486. $nc = Page::getByID($this->getPendingActionTargetCollectionID());
  1487. $this->move($nc);
  1488. $this->clearPendingAction();
  1489. break;
  1490. }
  1491. }
  1492. public function moveToTrash() {
  1493. $trash = Page::getByPath(TRASH_PAGE_PATH);
  1494. $this->move($trash);
  1495. $this->deactivate();
  1496. $this->clearPendingAction();
  1497. }
  1498. function rescanChildrenDisplayOrder() {
  1499. $db = Loader::db();
  1500. // this should be re-run every time a new page is added, but i don't think it is yet - AE
  1501. //$oneLevelOnly=1;
  1502. //$children_array = $this->getCollectionChildrenArray( $oneLevelOnly );
  1503. $q = "SELECT cID FROM Pages WHERE cParentID=".intval($this->getCollectionID()).' ORDER BY cDisplayOrder';
  1504. $children_array = $db->getCol($q);
  1505. $current_count=0;
  1506. foreach($children_array as $newcID) {
  1507. $q = "update Pages set cDisplayOrder='$current_count' where cID='$newcID'";
  1508. $r = $db->query($q);
  1509. $current_count++;
  1510. }
  1511. }
  1512. function getNextSubPageDisplayOrder() {
  1513. $db = Loader::db();
  1514. $max = $db->getOne("select max(cDisplayOrder) from Pages where cParentID = " . $this->getCollectionID());
  1515. if ($max == "" || $max == null) {
  1516. return 0;
  1517. } else if (!$max) {
  1518. return 1;
  1519. } else {
  1520. return $max + 1;
  1521. }
  1522. }
  1523. function rescanCollectionPath($retainOldPagePath = false) {
  1524. if ($this->cParentID > 0) {
  1525. $db = Loader::db();
  1526. // first, we grab the path of the parent, if such a thing exists, for our prefix
  1527. $q = "select PagePaths.cPath as cPathParent from PagePaths left join Pages on (Pages.cParentID = PagePaths.cID and PagePaths.ppIsCanonical = 1) where Pages.cID = '{$this->cID}'";
  1528. $cPath = $db->getOne($q);
  1529. // Now we perform the collection path function on the current cID
  1530. $np = $this->rescanCollectionPathIndividual($this->cID, $cPath, $retainOldPagePath);
  1531. $this->cPath = $np;
  1532. // Now we start with the recursive collection path scanning, armed with our prefix (from the level above what we're scanning)
  1533. if ($np) {
  1534. $this->rescanCollectionPathChildren($this->cID, $np);
  1535. }
  1536. }
  1537. }
  1538. function updateDisplayOrder($do,$cID=0) {
  1539. //this line was added to allow changing the display order of aliases
  1540. if(!intval($cID)) $cID=$this->getCollectionID();
  1541. $db = Loader::db();
  1542. $db->query("update Pages set cDisplayOrder = ? where cID = ?", array($do, $cID));
  1543. $this->refreshCache();
  1544. }
  1545. public function movePageDisplayOrderToTop() {
  1546. // first, we take the current collection, stick it at the beginning of an array, then get all other items from the current level that aren't that cID, order by display order, and then update
  1547. $db = Loader::db();
  1548. $nodes = array();
  1549. $nodes[] = $this->getCollectionID();
  1550. $r = $db->GetCol('select cID from Pages where cParentID = ? and cID <> ? order by cDisplayOrder asc', array($this->getCollectionParentID(), $this->getCollectionID()));
  1551. $nodes = array_merge($nodes, $r);
  1552. $displayOrder = 0;
  1553. foreach($nodes as $do) {
  1554. $co = Page::getByID($do);
  1555. $co->updateDisplayOrder($displayOrder);
  1556. $displayOrder++;
  1557. }
  1558. }
  1559. public function movePageDisplayOrderToBottom() {
  1560. // first, we take the current collection, stick it at the beginning of an array, then get all other items from the current level that aren't that cID, order by display order, and then update
  1561. $db = Loader::db();
  1562. $nodes = $db->GetCol('select cID from Pages where cParentID = ? and cID <> ? order by cDisplayOrder asc', array($this->getCollectionParentID(), $this->getCollectionID()));
  1563. $displayOrder = 0;
  1564. $nodes[] = $this->getCollectionID();
  1565. foreach($nodes as $do) {
  1566. $co = Page::getByID($do);
  1567. $co->updateDisplayOrder($displayOrder);
  1568. $displayOrder++;
  1569. }
  1570. }
  1571. function rescanCollectionPathIndividual($cID, $cPath, $retainOldPagePath = false) {
  1572. $db = Loader::db();
  1573. $q = "select CollectionVersions.cID, CollectionVersions.cvHandle, CollectionVersions.cvID, PagePaths.cID as cpcID from CollectionVersions left join PagePaths on (PagePaths.cID = CollectionVersions.cID) where CollectionVersions.cID = '{$cID}' and CollectionVersions.cvIsApproved = 1";
  1574. $r = $db->query($q);
  1575. if (!$r) return;
  1576. $row = $r->fetchRow();
  1577. if (!$row['cvHandle']) {
  1578. $row['cvHandle'] = $row['cID'];
  1579. }
  1580. if ($row['cvHandle']) {
  1581. $origPath = $cPath . '/' . $row['cvHandle'];
  1582. // first, we check to see if this path already exists
  1583. $proceed = false;
  1584. $suffix = 0;
  1585. while ($proceed != true) {
  1586. $newPath = ($suffix == 0) ? $origPath : $origPath . $suffix;
  1587. $v2 = array($newPath);
  1588. $q2 = "select cID from PagePaths where cPath = ? and cID <> {$cID}";
  1589. $r2 = $db->query($q2, $v2);
  1590. if ($r2->numRows() == 0) {
  1591. $proceed = true;
  1592. } else {
  1593. $suffix++;
  1594. }
  1595. }
  1596. if ($row['cpcID']) {
  1597. if ($retainOldPagePath) {
  1598. $db->query("update PagePaths set ppIsCanonical = 0 where cID = {$cID}");
  1599. } else {
  1600. $db->query('delete from PagePaths where ppIsCanonical = 1 and cID = ?', array($row['cpcID']));
  1601. }
  1602. }
  1603. // Check to see if a non-canonical page path already exists for the new location.
  1604. $v = array($cID, $newPath);
  1605. $rc = $db->query("select cID from PagePaths where cID = ? and cPath = ?", $v);
  1606. if ($rc->numRows() > 0) {
  1607. // Update the non-canonical path to be canonical.
  1608. $q3 = "update PagePaths set ppIsCanonical = 1 where cID = ? and cPath = ?";
  1609. } else {
  1610. // Create a new page path for the new location.
  1611. $q3 = "insert into PagePaths (cID, cPath) values (?, ?)";
  1612. }
  1613. $rc->free();
  1614. $r3 = $db->prepare($q3);
  1615. $res3 = $db->execute($r3, $v);
  1616. if ($res3) {
  1617. $np = Page::getByID($cID, $row['cvID']);
  1618. $np->rescanSystemPageStatus();
  1619. $np->refreshCache();
  1620. return $newPath;
  1621. }
  1622. }
  1623. $r->free();
  1624. }
  1625. public function rescanSystemPageStatus() {
  1626. $cID = $this->getCollectionID();
  1627. $db = Loader::db();
  1628. $newPath = $db->GetOne('select cPath from PagePaths where cID = ? and ppIsCanonical = 1', array($cID));
  1629. // now we mark the page as a system page based on this path:
  1630. $systemPages=array('/login', '/register', '/!trash', '/!stacks', '/!drafts', '/!trash/*', '/!stacks/*', '/!drafts/*', '/download_file', '/profile', '/dashboard', '/profile/*', '/dashboard/*','/page_forbidden','/page_not_found','/members');
  1631. $th = Loader::helper('text');
  1632. $db->Execute('update Pages set cIsSystemPage = 0 where cID = ?', array($cID));
  1633. foreach($systemPages as $sp) {
  1634. if ($th->fnmatch($sp, $newPath)) {
  1635. $db->Execute('update Pages set cIsSystemPage = 1 where cID = ?', array($cID));
  1636. }
  1637. }
  1638. }
  1639. public function isInTrash() {
  1640. return $this->getCollectionPath() != TRASH_PAGE_PATH && strpos($this->getCollectionPath(), TRASH_PAGE_PATH) === 0;
  1641. }
  1642. public function moveToRoot() {
  1643. $db = Loader::db();
  1644. $db->Execute('update Pages set cParentID = 0 where cID = ?', array($this->getCollectionID()));
  1645. $this->refreshCache();
  1646. }
  1647. public function rescanSystemPages() {
  1648. $db = Loader::db();
  1649. $systemPages=array('/login', '/register', '/!trash/%', '/!drafts/%', '/!stacks/%', '/!trash', '/!stacks', '/!drafts', '/download_file', '/profile', '/dashboard', '/profile/%', '/dashboard/%','/page_forbidden','/page_not_found','/members');
  1650. foreach($systemPages as $sp) {
  1651. $r = $db->Execute('select cID from PagePaths where cPath like "' . $sp . '"');
  1652. while ($row = $r->Fetchrow()) {
  1653. $db->Execute('update Pages set cIsSystemPage = 1 where cID = ?', array($row['cID']));
  1654. }
  1655. }
  1656. }
  1657. public function deactivate() {
  1658. $db = Loader::db();
  1659. $db->Execute('update Pages set cIsActive = 0 where cID = ?', array($this->getCollectionID()));
  1660. $this->refreshCache();
  1661. }
  1662. public function activate() {
  1663. $db = Loader::db();
  1664. $db->Execute('update Pages set cIsActive = 1 where cID = ?', array($this->getCollectionID()));
  1665. $this->refreshCache();
  1666. }
  1667. public function isActive() {
  1668. return $this->cIsActive;
  1669. }
  1670. public function setPageIndexScore($score) {
  1671. $this->cIndexScore = $score;
  1672. }
  1673. public function getPageIndexScore() {
  1674. return round($this->cIndexScore, 2);
  1675. }
  1676. public function getPageIndexContent() {
  1677. $db = Loader::db();
  1678. return $db->GetOne('select content from PageSearchIndex where cID = ?', array($this->cID));
  1679. }
  1680. function rescanCollectionPathChildren($cID, $cPath) {
  1681. $db = Loader::db();
  1682. $q = "select cID from Pages where cParentID = $cID";
  1683. $r = $db->query($q);
  1684. if ($r) {
  1685. while ($row = $r->fetchRow()) {
  1686. $np = $this->rescanCollectionPathIndividual($row['cID'], $cPath);
  1687. $this->rescanCollectionPathChildren($row['cID'], $np);
  1688. }
  1689. $r->free();
  1690. }
  1691. }
  1692. function getCollectionAction() {
  1693. $cID = $this->cID;
  1694. $valt = Loader::helper('validation/token');
  1695. $token = $valt->getParameter();
  1696. if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' && defined('BASE_URL_SSL')) {
  1697. $str = BASE_URL_SSL . DIR_REL . "/" . DISPATCHER_FILENAME . "?cID={$cID}&" . $token;
  1698. } else {
  1699. $str = BASE_URL . DIR_REL . "/" . DISPATCHER_FILENAME . "?cID={$cID}&" . $token;
  1700. }
  1701. return $str;
  1702. }
  1703. /**
  1704. *
  1705. * @access private
  1706. *
  1707. **/
  1708. function clearGroups() {
  1709. $db = Loader::db();
  1710. $q = "delete from PagePermissions where cID = '{$this->cID}'";
  1711. $r = $db->query($q);
  1712. $q2 = "delete from PagePermissionPageTypes where cID = '{$this->cID}'";
  1713. $r2 = $db->query($q2);
  1714. Cache::delete("page_permission_set_guest", $this->getCollectionID());
  1715. }
  1716. /**
  1717. *
  1718. * @access private
  1719. *
  1720. **/
  1721. function updateGroups($args = null) {
  1722. // All right, so here's how we do this. We iterate through the posted form arrays, storing and concatenating
  1723. // permission sets for each particular group. Then we delete all of the groups associated with this collectionblock
  1724. // and insert new ones
  1725. $this->clearGroups();
  1726. $gIDArray = array();
  1727. $uIDArray = array();
  1728. if (!is_array($args)) {
  1729. $args = $_POST; // legacy support
  1730. }
  1731. if (is_array($args['collectionRead'])) {
  1732. foreach ($args['collectionRead'] as $ugID) {
  1733. if (strpos($ugID, 'uID') > -1) {
  1734. $uID = substr($ugID, 4);
  1735. $uIDArray[$uID] .= "r:";
  1736. } else {
  1737. $gID = substr($ugID, 4);
  1738. $gIDArray[$gID] .= "r:";
  1739. }
  1740. }
  1741. }
  1742. if (is_array($args['collectionReadVersions'])) {
  1743. foreach ($args['collectionReadVersions'] as $ugID) {
  1744. if (strpos($ugID, 'uID') > -1) {
  1745. $uID = substr($ugID, 4);
  1746. $uIDArray[$uID] .= "rv:";
  1747. } else {
  1748. $gID = substr($ugID, 4);
  1749. $gIDArray[$gID] .= "rv:";
  1750. }
  1751. }
  1752. }
  1753. if (is_array($args['collectionWrite'])) {
  1754. foreach($args['collectionWrite'] as $ugID) {
  1755. if (strpos($ugID, 'uID') > -1) {
  1756. $uID = substr($ugID, 4);
  1757. $uIDArray[$uID] .= "wa:db:";
  1758. } else {
  1759. $gID = substr($ugID, 4);
  1760. $gIDArray[$gID] .= "wa:db:";
  1761. }
  1762. }
  1763. }
  1764. if (is_array($args['collectionApprove'])) {
  1765. foreach($args['collectionApprove'] as $ugID) {
  1766. if (strpos($ugID, 'uID') > -1) {
  1767. $uID = substr($ugID, 4);
  1768. $uIDArray[$uID] .= "av:";
  1769. } else {
  1770. $gID = substr($ugID, 4);
  1771. $gIDArray[$gID] .= "av:";
  1772. }
  1773. }
  1774. }
  1775. if (is_array($args['collectionDelete'])) {
  1776. foreach($args['collectionDelete'] as $ugID) {
  1777. if (strpos($ugID, 'uID') > -1) {
  1778. $uID = substr($ugID, 4);
  1779. $uIDArray[$uID] .= "dc:";
  1780. } else {
  1781. $gID = substr($ugID, 4);
  1782. $gIDArray[$gID] .= "dc:";
  1783. }
  1784. }
  1785. }
  1786. if (is_array($args['collectionAddSubContent'])) {
  1787. foreach($args['collectionAddSubContent'] as $ugID) {
  1788. if (strpos($ugID, 'uID') > -1) {
  1789. $uID = substr($ugID, 4);
  1790. $uIDArray[$uID] .= "as:";
  1791. } else {
  1792. $gID = substr($ugID, 4);
  1793. $gIDArray[$gID] .= "as:";
  1794. }
  1795. }
  1796. }
  1797. if (is_array($args['collectionAdmin'])) {
  1798. foreach($args['collectionAdmin'] as $ugID) {
  1799. if (strpos($ugID, 'uID') > -1) {
  1800. $uID = substr($ugID, 4);
  1801. $uIDArray[$uID] .= "adm:";
  1802. } else {
  1803. $gID = substr($ugID, 4);
  1804. $gIDArray[$gID] .= "adm:";
  1805. }
  1806. }
  1807. }
  1808. $gCTArray = array();
  1809. $uCTArray = array();
  1810. if (is_array($args['collectionAddSubCollection'])) {
  1811. foreach($args['collectionAddSubCollection'] as $ctID => $ugArray) {
  1812. // this gets us the collection type that particular groups/users are given access to
  1813. foreach($ugArray as $ugID) {
  1814. if (strpos($ugID, 'uID') > -1) {
  1815. $uID = substr($ugID, 4);
  1816. $uCTArray[$uID][] = $ctID;
  1817. } else {
  1818. $gID = substr($ugID, 4);
  1819. $gCTArray[$gID][] = $ctID;
  1820. }
  1821. }
  1822. }
  1823. }
  1824. // now that we've gone through this and created an array of IDs, we're going to delete all permissions for this particular block
  1825. // in the database, before we add them back in
  1826. $db = Loader::db();
  1827. // now we iterate through, and add the permissions
  1828. $dt = Loader::helper('form/date_time');
  1829. $dh = Loader::helper('date');
  1830. foreach ($gIDArray as $gID => $perms) {
  1831. $cgStartDate = $dh->getSystemDateTime($dt->translate('cgStartDate_gID:' . $gID, $args));
  1832. $cgEndDate = $dh->getSystemDateTime($dt->translate('cgEndDate_gID:' . $gID, $args));
  1833. // since this can now be either groups or users, we have prepended gID or uID to each gID value
  1834. // we have to trim the trailing colon, if there is one
  1835. $permissions = (strrpos($perms, ':') == (strlen($perms) - 1)) ? substr($perms, 0, strlen($perms) - 1) : $perms;
  1836. $startDate = ($cgStartDate) ? $cgStartDate : null;
  1837. $endDate = ($cgEndDate) ? $cgEndDate : null;
  1838. $v = array($this->cID, $gID, $permissions, $startDate, $endDate);
  1839. $q = "insert into PagePermissions (cID, gID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  1840. $r = $db->prepare($q);
  1841. $res = $db->execute($r, $v);
  1842. }
  1843. // iterate through and add user-level permissions
  1844. foreach ($uIDArray as $uID => $perms) {
  1845. // since this can now be either groups or users, we have prepended gID or uID to each gID value
  1846. // we have to trim the trailing colon, if there is one
  1847. $permissions = (strrpos($perms, ':') == (strlen($perms) - 1)) ? substr($perms, 0, strlen($perms) - 1) : $perms;
  1848. $startDate = ($args['cgStartDate_uID:' . $uID]) ? $args['cgStartDate_uID:' . $uID] : null;
  1849. $endDate = ($args['cgEndDate_uID:' . $uID]) ? $args['cgEndDate_uID:' . $uID] : null;
  1850. $v = array($this->cID, $uID, $permissions, $startDate, $endDate);
  1851. $q = "insert into PagePermissions (cID, uID, cgPermissions, cgStartDate, cgEndDate) values (?, ?, ?, ?, ?)";
  1852. $r = $db->prepare($q);
  1853. $res = $db->execute($r, $v);
  1854. }
  1855. foreach($uCTArray as $uID => $uCTs) {
  1856. foreach($uCTs as $ctID) {
  1857. $v = array($this->cID, $uID, $ctID);
  1858. $q = "insert into PagePermissionPageTypes (cID, uID, ctID) values (?, ?, ?)";
  1859. $r = $db->query($q, $v);
  1860. }
  1861. }
  1862. foreach($gCTArray as $gID => $gCTs) {
  1863. foreach($gCTs as $ctID) {
  1864. $v = array($this->cID, $gID, $ctID);
  1865. $q = "insert into PagePermissionPageTypes (cID, gID, ctID) values (?, ?, ?)";
  1866. $r = $db->query($q, $v);
  1867. }
  1868. }
  1869. // now, if we're updating the permissions for a collection that has sub-collections, which inherit their
  1870. // permissions from the area of the site, we need to change their pointers
  1871. //we have to update the existing collection with the info for the new
  1872. //as well as all collections beneath it that are set to inherit from this parent
  1873. $this->updateGroupsSubCollection($this->getCollectionID());
  1874. Cache::delete("page_permission_set_guest", $this->getCollectionID());
  1875. }
  1876. function _associateMasterCollectionBlocks($newCID, $masterCID) {
  1877. $mc = Page::getByID($masterCID, 'ACTIVE');
  1878. $nc = Page::getByID($newCID, 'RECENT');
  1879. $db = Loader::db();
  1880. $mcID = $mc->getCollectionID();
  1881. $mcvID = $mc->getVersionID();
  1882. $q = "select CollectionVersionBlocks.arHandle, BlockTypes.btCopyWhenPropagate, CollectionVersionBlocks.cbOverrideAreaPermissions, CollectionVersionBlocks.bID from CollectionVersionBlocks inner join Blocks on Blocks.bID = CollectionVersionBlocks.bID inner join BlockTypes on Blocks.btID = BlockTypes.btID where CollectionVersionBlocks.cID = '$mcID' and CollectionVersionBlocks.cvID = '{$mcvID}' order by CollectionVersionBlocks.cbDisplayOrder asc";
  1883. // ok. This function takes two IDs, the ID of the newly created virgin collection, and the ID of the crusty master collection
  1884. // who will impart his wisdom to the his young learner, by duplicating his various blocks, as well as their permissions, for the
  1885. // new collection
  1886. //$q = "select CollectionBlocks.cbAreaName, Blocks.bID, Blocks.bName, Blocks.bFilename, Blocks.btID, Blocks.uID, BlockTypes.btClassname, BlockTypes.btTablename from CollectionBlocks left join BlockTypes on (Blocks.btID = BlockTypes.btID) inner join Blocks on (CollectionBlocks.bID = Blocks.bID) where CollectionBlocks.cID = '$masterCID' order by CollectionBlocks.cbDisplayOrder asc";
  1887. //$q = "select CollectionVersionBlocks.cbAreaName, Blocks.bID, Blocks.bName, Blocks.bFilename, Blocks.btID, Blocks.uID, BlockTypes.btClassname, BlockTypes.btTablename from CollectionBlocks left join BlockTypes on (Blocks.btID = BlockTypes.btID) inner join Blocks on (CollectionBlocks.bID = Blocks.bID) where CollectionBlocks.cID = '$masterCID' order by CollectionBlocks.cbDisplayOrder asc";
  1888. $r = $db->query($q);
  1889. if ($r) {
  1890. while ($row = $r->fetchRow()) {
  1891. $b = Block::getByID($row['bID'], $mc, $row['arHandle']);
  1892. if ($row['btCopyWhenPropagate']) {
  1893. $b->duplicate($nc);
  1894. } else {
  1895. $b->alias($nc);
  1896. }
  1897. }
  1898. $r->free();
  1899. }
  1900. }
  1901. function _associateMasterCollectionAttributes($newCID, $masterCID) {
  1902. $mc = Page::getByID($masterCID, 'ACTIVE');
  1903. $nc = Page::getByID($newCID, 'RECENT');
  1904. $db = Loader::db();
  1905. $mcID = $mc->getCollectionID();
  1906. $mcvID = $mc->getVersionID();
  1907. $q = "select * from CollectionAttributeValues where cID = ?";
  1908. $r = $db->query($q, array($mcID));
  1909. if ($r) {
  1910. while ($row = $r->fetchRow()) {
  1911. $db->Execute('insert into CollectionAttributeValues (cID, cvID, akID, avID) values (?, ?, ?, ?)', array(
  1912. $nc->getCollectionID(), $nc->getVersionID(), $row['akID'], $row['avID']
  1913. ));
  1914. }
  1915. $r->free();
  1916. }
  1917. }
  1918. /**
  1919. * Adds the home page to the system. Typically used only by the installation program.
  1920. * @return page
  1921. **/
  1922. public static function addHomePage() {
  1923. // creates the home page of the site
  1924. Loader::model('collection_types');
  1925. $dh = Loader::helper('date');
  1926. $db = Loader::db();
  1927. // we use to hard code the home page page type into the system
  1928. // but now we're not going to do that
  1929. //$db->query("insert into PageTypes (ctID, ctHandle, ctName) values (?, ?, ?)", array(HOME_CTID, HOME_HANDLE, HOME_NAME));
  1930. $cParentID = 0;
  1931. $handle = HOME_HANDLE;
  1932. $uID = HOME_UID;
  1933. $name = HOME_NAME;
  1934. $data['name'] = HOME_NAME;
  1935. $data['handle'] = $handle;
  1936. $data['uID'] = $uID;
  1937. $data['cID'] = HOME_CID;
  1938. $cobj = parent::add($data);
  1939. $cID = $cobj->getCollectionID();
  1940. //$ctID = HOME_CTID;
  1941. $ctID = 0;
  1942. $cDate = $dh->getSystemDateTime();
  1943. $cDatePublic = $dh->getSystemDateTime();
  1944. $v = array($cID, $ctID, $cParentID, $uID, 'OVERRIDE', 1, 1, 0);
  1945. $q = "insert into Pages (cID, ctID, cParentID, uID, cInheritPermissionsFrom, cOverrideTemplatePermissions, cInheritPermissionsFromCID, cDisplayOrder) values (?, ?, ?, ?, ?, ?, ?, ?)";
  1946. $r = $db->prepare($q);
  1947. $res = $db->execute($r, $v);
  1948. $pc = Page::getByID($cID, 'RECENT');
  1949. return $pc;
  1950. }
  1951. /**
  1952. * Adds a new page of a certain type, using a passed associate array to setup value. $data may contain any or all of the following:
  1953. * "uID": User ID of the page's owner
  1954. * "pkgID": Package ID the page belongs to
  1955. * "cName": The name of the page
  1956. * "cHandle": The handle of the page as used in the path
  1957. * "cDatePublic": The date assigned to the page
  1958. * @param collectiontype $ct
  1959. * @param array $data
  1960. * @return page
  1961. **/
  1962. public function add($ct, $data) {
  1963. $db = Loader::db();
  1964. $txt = Loader::helper('text');
  1965. // the passed collection is the parent collection
  1966. $cParentID = $this->getCollectionID();
  1967. $u = new User();
  1968. if (isset($data['uID'])) {
  1969. $uID = $data['uID'];
  1970. } else {
  1971. $uID = $u->getUserID();
  1972. $data['uID'] = $uID;
  1973. }
  1974. if (isset($data['pkgID'])) {
  1975. $pkgID = $data['pkgID'];
  1976. } else if ($ct->getPackageID() > 0) {
  1977. $pkgID = $ct->getPackageID();
  1978. } else {
  1979. $pkgID = 0;
  1980. }
  1981. if (isset($data['cName'])) {
  1982. $data['name'] = $data['cName'];
  1983. }
  1984. if (!$data['cHandle']) {
  1985. // make the handle out of the title
  1986. $handle = $txt->sanitizeFileSystem($data['name']);
  1987. } else {
  1988. $handle = $txt->sanitizeFileSystem($data['cHandle']);
  1989. }
  1990. $data['handle'] = $handle;
  1991. $dh = Loader::helper('date');
  1992. $cDate = $dh->getSystemDateTime();
  1993. $cDatePublic = ($data['cDatePublic']) ? $data['cDatePublic'] : null;
  1994. parent::refreshCache();
  1995. $cobj = parent::add($data);
  1996. $cID = $cobj->getCollectionID();
  1997. $ctID = $ct->getCollectionTypeID();
  1998. if (!$ctID) {
  1999. $ctID = 0;
  2000. }
  2001. $q = "select cID from Pages where ctID = '$ctID' and cIsTemplate = '1'";
  2002. $masterCID = $db->getOne($q);
  2003. //$this->rescanChildrenDisplayOrder();
  2004. $cDisplayOrder = $this->getNextSubPageDisplayOrder();
  2005. $cInheritPermissionsFromCID = ($this->overrideTemplatePermissions()) ? $this->getPermissionsCollectionID() : $masterCID;
  2006. $cInheritPermissionsFrom = ($this->overrideTemplatePermissions()) ? "PARENT" : "TEMPLATE";
  2007. $ptID = $this->getCollectionThemeID();
  2008. $v = array($cID, $ctID, $cParentID, $uID, $cInheritPermissionsFrom, $this->overrideTemplatePermissions(), $cInheritPermissionsFromCID, $cDisplayOrder, $ptID, $pkgID);
  2009. $q = "insert into Pages (cID, ctID, cParentID, uID, cInheritPermissionsFrom, cOverrideTemplatePermissions, cInheritPermissionsFromCID, cDisplayOrder, ptID, pkgID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
  2010. $r = $db->prepare($q);
  2011. $res = $db->execute($r, $v);
  2012. $newCID = $cID;
  2013. if ($res) {
  2014. // Collection added with no problem -- update cChildren on parrent
  2015. Loader::model('page_statistics');
  2016. PageStatistics::incrementParents($newCID);
  2017. if ($r) {
  2018. // now that we know the insert operation was a success, we need to see if the collection type we're adding has a master collection associated with it
  2019. if ($masterCID) {
  2020. $this->_associateMasterCollectionBlocks($newCID, $masterCID);
  2021. $this->_associateMasterCollectionAttributes($newCID, $masterCID);
  2022. }
  2023. }
  2024. $pc = Page::getByID($newCID, 'RECENT');
  2025. // run any internal event we have for page addition
  2026. Events::fire('on_page_add', $pc);
  2027. $pc->rescanCollectionPath();
  2028. }
  2029. return $pc;
  2030. }
  2031. public function addToPageCache($content) {
  2032. Cache::set('page_content', $this->getCollectionID(), $content, $this->getCollectionFullPageCachingLifetimeValue());
  2033. }
  2034. public function getFromPageCache() {
  2035. return Cache::get('page_content', $this->getCollectionID());
  2036. }
  2037. public function renderFromCache() {
  2038. $content = Cache::get('page_content', $this->getCollectionID());
  2039. if ($content != false) {
  2040. print $content;
  2041. exit;
  2042. }
  2043. }
  2044. public function getCollectionFullPageCaching() {
  2045. return $this->cCacheFullPageContent;
  2046. }
  2047. public function getCollectionFullPageCachingLifetime() {
  2048. return $this->cCacheFullPageContentOverrideLifetime;
  2049. }
  2050. public function getCollectionFullPageCachingLifetimeCustomValue() {
  2051. return $this->cCacheFullPageContentLifetimeCustom;
  2052. }
  2053. public function getCollectionFullPageCachingLifetimeValue() {
  2054. if ($this->cCacheFullPageContentOverrideLifetime == 'default') {
  2055. $lifetime = CACHE_LIFETIME;
  2056. } else if ($this->cCacheFullPageContentOverrideLifetime == 'custom') {
  2057. $lifetime = $this->cCacheFullPageContentLifetimeCustom * 60;
  2058. } else if ($this->cCacheFullPageContentOverrideLifetime == 'forever') {
  2059. $lifetime = 31536000; // 1 year
  2060. } else {
  2061. if (FULL_PAGE_CACHE_LIFETIME == 'custom') {
  2062. $lifetime = Config::get('FULL_PAGE_CACHE_LIFETIME_CUSTOM') * 60;
  2063. } else if (FULL_PAGE_CACHE_LIFETIME == 'forever') {
  2064. $lifetime = 31536000; // 1 year
  2065. } else {
  2066. $lifetime = CACHE_LIFETIME;
  2067. }
  2068. }
  2069. return $lifetime;
  2070. }
  2071. public function supportsPageCache($blocks, $controller = false) {
  2072. $u = new User();
  2073. $allowedControllerActions = array('view');
  2074. if (is_object($controller)) {
  2075. if (!in_array($controller->getTask(), $allowedControllerActions)) {
  2076. return false;
  2077. }
  2078. }
  2079. if ($this->cCacheFullPageContent == 0) {
  2080. return false;
  2081. }
  2082. if ($u->isRegistered() || $_SERVER['REQUEST_METHOD'] == 'POST') {
  2083. return false;
  2084. }
  2085. // test get variables
  2086. $allowedGetVars = array('cid');
  2087. if (is_array($_GET)) {
  2088. foreach($_GET as $key => $value) {
  2089. if (!in_array(strtolower($key), $allowedGetVars)) {
  2090. return false;
  2091. }
  2092. }
  2093. }
  2094. if ($this->cCacheFullPageContent == 1 || FULL_PAGE_CACHE_GLOBAL === 'all') {
  2095. // this cache page at the page level
  2096. // this overrides any global settings
  2097. return true;
  2098. }
  2099. if (FULL_PAGE_CACHE_GLOBAL !== 'blocks') {
  2100. // we are NOT specifically caching this page, and we don't
  2101. return false;
  2102. }
  2103. if ($this->isGeneratedCollection()) {
  2104. return false;
  2105. }
  2106. if (is_array($blocks)) {
  2107. foreach($blocks as $b) {
  2108. $controller = $b->getInstance();
  2109. if (!$controller->cacheBlockOutput()) {
  2110. return false;
  2111. }
  2112. }
  2113. }
  2114. return true;
  2115. }
  2116. public function addStatic($data) {
  2117. $db = Loader::db();
  2118. $cParentID = $this->getCollectionID();
  2119. if (isset($data['pkgID'])) {
  2120. $pkgID = $data['pkgID'];
  2121. } else {
  2122. $pkgID = 0;
  2123. }
  2124. $handle = $data['handle'];
  2125. $cName = $data['name'];
  2126. $cFilename = $data['filename'];
  2127. $uID = USER_SUPER_ID;
  2128. $data['uID'] = $uID;
  2129. $cIsSystemPage = 0;
  2130. parent::refreshCache();
  2131. $cobj = parent::add($data);
  2132. $cID = $cobj->getCollectionID();
  2133. $this->rescanChildrenDisplayOrder();
  2134. $cDisplayOrder = $this->getNextSubPageDisplayOrder();
  2135. // These get set to parent by default here, but they can be overridden later
  2136. $cInheritPermissionsFromCID = $this->getPermissionsCollectionID();
  2137. $cInheritPermissionsFrom = 'PARENT';
  2138. $v = array($cID, $cFilename, $cParentID, $cInheritPermissionsFrom, $this->overrideTemplatePermissions(), $cInheritPermissionsFromCID, $cDisplayOrder, $cIsSystemPage, $uID, $pkgID);
  2139. $q = "insert into Pages (cID, cFilename, cParentID, cInheritPermissionsFrom, cOverrideTemplatePermissions, cInheritPermissionsFromCID, cDisplayOrder, cIsSystemPage, uID, pkgID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
  2140. $r = $db->prepare($q);
  2141. $res = $db->execute($r, $v);
  2142. if ($res) {
  2143. // Collection added with no problem -- update cChildren on parrent
  2144. Loader::model('page_statistics');
  2145. PageStatistics::incrementParents($cID);
  2146. }
  2147. $pc = Page::getByID($cID);
  2148. $pc->rescanCollectionPath();
  2149. return $pc;
  2150. }
  2151. function getPagePaths() {
  2152. $db = Loader::db();
  2153. $q = "select ppID, cPath, ppIsCanonical from PagePaths where cID = {$this->cID}";
  2154. $r = $db->query($q, $v);
  2155. $paths = array();
  2156. if ($r) {
  2157. while ($row = $r->fetchRow()) {
  2158. $paths[] = $row;
  2159. }
  2160. $r->free();
  2161. }
  2162. return $paths;
  2163. }
  2164. /*
  2165. * returns an instance of the current page object
  2166. *
  2167. */
  2168. public static function getCurrentPage() {
  2169. $req = Request::get();
  2170. $current = $req->getCurrentPage();
  2171. if (is_object($current)) {
  2172. return $current;
  2173. } else {
  2174. global $c;
  2175. return $c;
  2176. }
  2177. }
  2178. }