PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/pivotx_2.2.5-sqlite/pivotx/objects.php

http://pivotx-sqlite.googlecode.com/
PHP | 2403 lines | 1863 code | 240 blank | 300 comment | 124 complexity | ea19077f3dfc4f78f132908cecf41260 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. // ---------------------------------------------------------------------------
  3. //
  4. // PIVOTX - LICENSE:
  5. //
  6. // This file is part of PivotX. PivotX and all its parts are licensed under
  7. // the GPL version 2. see: http://docs.pivotx.net/doku.php?id=help_about_gpl
  8. // for more information.
  9. //
  10. // $Id: objects.php 3501 2011-02-11 08:48:13Z hansfn $
  11. //
  12. // ---------------------------------------------------------------------------
  13. /**
  14. * Takes care of all configuration settings. The configuration is stored in
  15. * pivotx/db/ser_config.php, but is completely accessible through this object.
  16. * Saving is automagical and only when something has changed.
  17. *
  18. */
  19. class Config {
  20. var $configfile;
  21. function Config($sites_path = '') {
  22. $this->configfile = dirname(__FILE__) . '/' . $sites_path . 'db/ser_config.php';
  23. $this->data = loadSerialize($this->configfile, true);
  24. if (count($this->data)<5) {
  25. // hmm, couldn't find the data.. Perhaps try to import it from old Pivot 1.x
  26. $this->readOld();
  27. $this->save();
  28. }
  29. $this->checkConfig();
  30. }
  31. /**
  32. * Check if all required fields in the config are set. If not, we add them.
  33. *
  34. */
  35. function checkConfig() {
  36. $mustsave = false;
  37. $default = getDefaultConfig();
  38. foreach($default as $key=>$value) {
  39. if (!isset($this->data[$key])) {
  40. $this->data[$key] = $value;
  41. $mustsave = true;
  42. }
  43. }
  44. // Seperate check for 'server_spam_key' since it is different for all PivotX install
  45. if (!isset($this->data['server_spam_key']) || empty($this->data['server_spam_key'])) {
  46. $server_spam_key = '';
  47. $possible_server_keys = array('SERVER_SIGNATURE','SERVER_ADDR','PHP_SELF','DOCUMENT_ROOT');
  48. foreach ($possible_server_keys as $key) {
  49. if (isset($_SERVER[$key])) {
  50. $server_spam_key .= $_SERVER[$key];
  51. }
  52. }
  53. $server_spam_key .= time();
  54. $this->data['server_spam_key'] = md5($server_spam_key);
  55. $mustsave = true;
  56. }
  57. if ($mustsave) {
  58. $this->save();
  59. }
  60. // If there's a file called 'pivotxdebugmode.txt', we'll enable debugging
  61. if (file_exists(dirname(__FILE__)."/pivotxdebugmode.txt")) {
  62. $this->data['debug'] = 1;
  63. }
  64. }
  65. /**
  66. * If the config file is missing, we check if there's a pivot 1.x config
  67. * file that we can use. This function does some comversions to get it up
  68. * to date, and sets it in $this->data
  69. *
  70. */
  71. function readOld() {
  72. global $pivotx_path;
  73. // If the old config file doesn't exist or it isn't readable, we return false..
  74. if (!file_exists($pivotx_path.'pv_cfg_settings.php') || (!is_readable($pivotx_path.'pv_cfg_settings.php'))) {
  75. return false;
  76. }
  77. // get the config file
  78. $fh = file($pivotx_path.'pv_cfg_settings.php');
  79. foreach ($fh as $fh_this) {
  80. @list($name, $val) = explode("!", $fh_this);
  81. $Cfg[trim($name)] = trim($val);
  82. }
  83. //GetUserInfo();
  84. //ExpandSessions();
  85. @$Cfg['ping_urls']=str_replace("|", "\n", $Cfg['ping_urls']);
  86. @$Cfg['default_introduction']=str_replace("|", "\n", $Cfg['default_introduction']);
  87. if (!isset($Cfg['selfreg'])) { $Cfg['selfreg']= 0; }
  88. if (!isset($Cfg['xmlrpc'])) { $Cfg['xmlrpc']= 0; }
  89. if (!isset($Cfg['hashcash'])) { $Cfg['hashcash']= 0; }
  90. if (!isset($Cfg['spamquiz'])) { $Cfg['spamquiz']= 0; }
  91. if (!isset($Cfg['hardened_trackback'])) { $Cfg['hardened_trackback']= 0; }
  92. if (!isset($Cfg['moderate_comments'])) { $Cfg['moderate_comments']= 0; }
  93. if (!isset($Cfg['lastcomm_amount_max'])) { $Cfg['lastcomm_amount_max'] = 60; }
  94. if (!isset($Cfg['tag_cache_timeout'])) { $Cfg['tag_cache_timeout'] = 60; }
  95. if (!isset($Cfg['tag_flickr_enabled'])) { $Cfg['tag_flickr_enabled'] = 1; }
  96. if (!isset($Cfg['tag_flickr_amount'])) { $Cfg['tag_flickr_amount'] = 6; }
  97. if (!isset($Cfg['tag_fetcher_enabled'])) { $Cfg['tag_fetcher_enabled'] = 1; }
  98. if (!isset($Cfg['tag_fetcher_amount'])) { $Cfg['tag_fetcher_amount'] = 10; }
  99. if (!isset($Cfg['tag_min_font'])) { $Cfg['tag_min_font'] = 9; }
  100. if (!isset($Cfg['tag_max_font'])) { $Cfg['tag_max_font'] = 42; }
  101. if(!isset($Cfg['server_spam_key'])) {
  102. $key = $_SERVER['SERVER_SIGNATURE'].$_SERVER['SERVER_ADDR'].$_SERVER['SCRIPT_URI'].$_SERVER['DOCUMENT_ROOT'].time();
  103. $Cfg['server_spam_key'] = md5($key);
  104. }
  105. // Remove stuff we don't need:
  106. unset($Cfg['session_length']);
  107. unset($Cfg['sessions']);
  108. unset($Cfg['users']);
  109. unset($Cfg['userfields']);
  110. unset($Cfg['<?php']);
  111. unset($Cfg['?>']);
  112. foreach ($Cfg as $key => $val) {
  113. if ( (strpos($key,'uf-')===0) || (strpos($key,'user-')===0) ) {
  114. unset($Cfg[$key]);
  115. }
  116. }
  117. $this->data = $Cfg;
  118. }
  119. /**
  120. * Save the config to disk.
  121. *
  122. */
  123. function save() {
  124. if (is_array($this->data)) {
  125. ksort($this->data);
  126. }
  127. saveSerialize($this->configfile, $this->data);
  128. }
  129. /**
  130. * Return the entire config as a big array.. It's probable better to use
  131. * $PIVOTX['config']->get() if you only need one or few items.
  132. *
  133. * @see $this->get
  134. * @return array
  135. */
  136. function getConfigArray() {
  137. return $this->data;
  138. }
  139. /**
  140. * Sets a configuration value, and then saves it.
  141. *
  142. * @param string $key
  143. * @param unknown_type $value
  144. */
  145. function set($key, $value) {
  146. // Empty checkboxes are passed by jQuery as string 'undefined', but we want to store them as integer '0'
  147. if ($value==="undefined") { $value=0; }
  148. // Offline configuration is not saved in the normal configuration file
  149. if (substr($key,0,8) == 'offline_') {
  150. PivotxOffline::setConfig(substr($key,8),$value);
  151. return;
  152. }
  153. // Only set (and save) if the value has actually changed.
  154. if (empty($this->data[safeString($key)]) || $value !== $this->data[safeString($key)] ) {
  155. $this->data[safeString($key)] = $value;
  156. $this->save();
  157. }
  158. }
  159. /**
  160. * Delete a configuration value. Use with extreme caution. Saves the
  161. * configuration afterwards
  162. *
  163. * @param string $key
  164. */
  165. function del($key) {
  166. // Old pre PivotX 2.0 configuration didn't use safe_string
  167. // on the key - we are handling it here.
  168. if (isset($this->data[safeString($key)])) {
  169. unset($this->data[safeString($key)]);
  170. } else {
  171. unset($this->data[$key]);
  172. }
  173. $this->save();
  174. }
  175. /**
  176. * Gets a single value from the configuration.
  177. *
  178. * @param string $key
  179. * @return string
  180. */
  181. function get($key) {
  182. if (isset($this->data[$key])) {
  183. return $this->data[$key];
  184. } else {
  185. return false;
  186. }
  187. }
  188. }
  189. /**
  190. * Since PHP4 doesn't allow class constants, we define the userlevels as
  191. * global constants.
  192. */
  193. define("PIVOTX_UL_NOBODY", -1);
  194. define("PIVOTX_UL_MOBLOGGER", 0);
  195. define("PIVOTX_UL_NORMAL", 1);
  196. define("PIVOTX_UL_ADVANCED", 2);
  197. define("PIVOTX_UL_ADMIN", 3);
  198. define("PIVOTX_UL_SUPERADMIN", 4);
  199. /**
  200. * Portable PHP password hashing framework (phpass) for PivotX:
  201. *
  202. * The framework can be completely disabled by setting "disable_phpass" to 1
  203. * in the advanced configuration. This is not recommended. If it is disabled,
  204. * a salted md5 sum is used for password hashing.
  205. *
  206. * 1) The standard log2 number of iterations for password stretching. This
  207. * should be increased from time to time to counteract increases in the speed
  208. * and power of computers available to crack the hashes. However, since the
  209. * current hashing algorithms aren't capable of running in parallell in PHP,
  210. * it shouldn't be increased too often. (It should never exceed 31.)
  211. */
  212. define('PIVOTX_PASSWORD_HASH_COUNT', 9);
  213. /**
  214. * 2) By default, portable hashes are used for maximum portability. Portable
  215. * hashes can be disabled by setting "password_non_portable_hashes"
  216. * to 1 in the advanced configuration. Non-portable hashes are more secure,
  217. * but can be a problem on shared hosting or if you need to move your site
  218. * between different servers.
  219. */
  220. define('PIVOTX_PASSWORD_PORTABLE_HASHES', true);
  221. /**
  222. * This Class handles all operations with regard to users: adding, deleting,
  223. * getting info, etc.
  224. *
  225. */
  226. class Users {
  227. /**
  228. * Initialisation
  229. *
  230. */
  231. function Users() {
  232. global $PIVOTX;
  233. $this->data = loadSerialize($PIVOTX['paths']['db_path'] . "ser_users.php", true);
  234. if ($this->count()<1) {
  235. // hmm, couldn't find the data.. Perhaps try to import it from old Pivot 1.x
  236. $this->readOld();
  237. $this->save();
  238. }
  239. // Make sure the users are sorted as intended.
  240. uasort($this->data, array($this, 'sort'));
  241. }
  242. function readOld() {
  243. global $pivotx_path;
  244. // If the old config file doesn't exist or it isn't readable, we return false..
  245. if (!file_exists($pivotx_path.'pv_cfg_settings.php') || (!is_readable($pivotx_path.'pv_cfg_settings.php'))) {
  246. return false;
  247. }
  248. // get the config file
  249. $fh = file($pivotx_path.'pv_cfg_settings.php');
  250. foreach ($fh as $fh_this) {
  251. @list($name, $val) = explode("!", $fh_this);
  252. $Cfg[trim($name)] = trim($val);
  253. }
  254. if(isset($Cfg['users'])) {
  255. foreach(explode('|', trim($Cfg['users'])) as $inc => $user){
  256. $userdata = array();
  257. $userdata['username'] = $user;
  258. foreach(explode('|-|' , $Cfg['user-' . $user]) as $var => $val){
  259. list($Nvar, $Nval) = explode('|', $val);
  260. if ($Nvar == 'nick') {
  261. $userdata['nickname'] = $Nval;
  262. } elseif ($Nvar == 'pass') {
  263. $userdata['md5_pass'] = $Nval;
  264. } else {
  265. $userdata[$Nvar] = $Nval;
  266. }
  267. }
  268. list($userdata['language']) = explode("_",$userdata['language']);
  269. $this->addUser($userdata);
  270. }
  271. }
  272. }
  273. /**
  274. * Get the count of users
  275. *
  276. * @return int
  277. */
  278. function count() {
  279. return ( is_array($this->data) && count($this->data) );
  280. }
  281. /**
  282. * Print a comprehensible representation of the users
  283. *
  284. */
  285. function print_r() {
  286. echo "<pre>\n";
  287. print_r($this->data);
  288. echo "</pre>\n";
  289. }
  290. /**
  291. * Add a user to Pivot
  292. *
  293. * @param array $user
  294. */
  295. function addUser($user) {
  296. global $PIVOTX;
  297. // Make sure the username is OK..
  298. $user['username'] = strtolower(safeString($user['username']));
  299. if ($this->getUser($user['username'])!==false) {
  300. // this username is already taken..
  301. return false;
  302. }
  303. $newuser = array(
  304. 'username' => $user['username'],
  305. 'email' => $user['email'],
  306. 'userlevel' => $user['userlevel'],
  307. 'nickname' => $user['nickname'],
  308. 'language' => $user['language'],
  309. 'image' => $user['image'],
  310. 'text_processing' => $user['text_processing']
  311. );
  312. if (!isset($user['pass1']) && isset($user['md5_pass'])) {
  313. // User comes from old (1.x) config so we don't have the clear text password.
  314. $newuser['password'] = $user['md5_pass'];
  315. $newuser['salt'] = '';
  316. } else {
  317. $newuser = $this->hashPassword($newuser, $user['pass1']);
  318. }
  319. $this->data[] = $newuser;
  320. $this->save();
  321. }
  322. function deleteUser($username) {
  323. foreach($this->data as $key=>$user) {
  324. if ($username == $user['username']) {
  325. unset($this->data[$key]);
  326. }
  327. }
  328. $this->save();
  329. }
  330. /**
  331. * Update a given property of a user
  332. *
  333. * @param string $username
  334. * @param array $properties
  335. * @see $this->save
  336. */
  337. function updateUser($username, $properties) {
  338. // Select the correct user
  339. foreach ($this->data as $key=>$user) {
  340. if ($username == $user['username']) {
  341. // Set the properties
  342. foreach($properties as $property => $value) {
  343. switch ($property) {
  344. case "email":
  345. case "nickname":
  346. case "language":
  347. case "text_processing":
  348. case "lastseen":
  349. case "userlevel":
  350. case "image":
  351. $this->data[$key][$property] = $value;
  352. break;
  353. case "reset_id":
  354. if ($value!="") {
  355. $this->data[$key][$property] = $value;
  356. } else {
  357. unset($this->data[$key][$property]);
  358. }
  359. break;
  360. case "pass1":
  361. if ( ($value!="") && ($value!="******")) {
  362. $this->data[$key] = $this->hashPassword($user, $value);
  363. }
  364. default:
  365. break;
  366. }
  367. }
  368. }
  369. }
  370. $this->save();
  371. }
  372. /**
  373. * Saves the Users to the filesystem.
  374. *
  375. */
  376. function save() {
  377. global $PIVOTX;
  378. // Make sure the users are sorted as intended.
  379. uasort($this->data, array($this, 'sort'));
  380. saveSerialize($PIVOTX['paths']['db_path'] . "ser_users.php", $this->data);
  381. }
  382. /**
  383. * Check if a given password matches the one stored.
  384. *
  385. * @param string $username
  386. * @param string $password
  387. * @return boolean
  388. */
  389. function checkPassword($username, $password) {
  390. global $PIVOTX;
  391. foreach($this->data as $user) {
  392. if ($username==$user['username']) {
  393. if ($user['salt'] == 'phpass') {
  394. require_once($PIVOTX['paths']['pivotx_path'] . 'includes/PasswordHash.php');
  395. // We don't really need to set portability correctly when checking
  396. // the password (since the hashing method is stored in the hash),
  397. // but it's clearer to use the same code everywhere.
  398. if ($PIVOTX['config']->get('password_non_portable_hashes')) {
  399. $portable = false;
  400. } else {
  401. $portable = PIVOTX_PASSWORD_PORTABLE_HASHES;
  402. }
  403. $phpass = new PasswordHash(PIVOTX_PASSWORD_HASH_COUNT, $portable);
  404. return $phpass->CheckPassword($password, $user['password']);
  405. } else {
  406. if (md5($password . $user['salt']) == $user['password']) {
  407. return true;
  408. }
  409. }
  410. break;
  411. }
  412. }
  413. return false;
  414. }
  415. /**
  416. * Hash a given password (for a given user).
  417. *
  418. * @param array $user
  419. * @param string $password
  420. * @return boolean
  421. */
  422. function hashPassword($user, $password) {
  423. global $PIVOTX;
  424. if (!$PIVOTX['config']->get('disable_phpass')) {
  425. require_once($PIVOTX['paths']['pivotx_path'] . 'includes/PasswordHash.php');
  426. if ($PIVOTX['config']->get('password_non_portable_hashes')) {
  427. $portable = false;
  428. } else {
  429. $portable = PIVOTX_PASSWORD_PORTABLE_HASHES;
  430. }
  431. $phpass = new PasswordHash(PIVOTX_PASSWORD_HASH_COUNT, $portable);
  432. $user['salt'] = 'phpass';
  433. $user['password'] = $phpass->HashPassword($password);
  434. } else {
  435. $user['salt'] = md5(rand(1,999999) . mktime());
  436. $user['password'] = md5( $password . $user['salt']);
  437. }
  438. return $user;
  439. }
  440. /**
  441. * Check if a given $username is a user.
  442. *
  443. * @param string $name
  444. * @return boolean
  445. */
  446. function isUser($username) {
  447. if ($this->getUser($username) === false) {
  448. return false;
  449. } else {
  450. return true;
  451. }
  452. }
  453. /**
  454. * Get the specifics for a given user by its username.
  455. *
  456. * @param string $username
  457. * @return array
  458. */
  459. function getUser($username) {
  460. foreach($this->data as $user) {
  461. if ( ($username==$user['username']) ) {
  462. return $user;
  463. }
  464. }
  465. return false;
  466. }
  467. /**
  468. * Get the specifics for a given user by its nickname.
  469. *
  470. * @param string $username
  471. * @return array
  472. */
  473. function getUserByNickname($username) {
  474. foreach($this->data as $user) {
  475. if ( strtolower($username) == strtolower($user['nickname']) ) {
  476. return $user;
  477. }
  478. }
  479. return false;
  480. }
  481. /**
  482. * Get a list of the Usernames
  483. *
  484. * @return array
  485. */
  486. function getUsernames() {
  487. $res = array();
  488. foreach($this->data as $user) {
  489. $res[]=$user['username'];
  490. }
  491. return $res;
  492. }
  493. /**
  494. * Get a list of the Users Nicknames
  495. *
  496. * @return array
  497. */
  498. function getUserNicknames() {
  499. $res = array();
  500. foreach($this->data as $user) {
  501. $res[ $user['username'] ] = $user['nickname'];
  502. }
  503. return $res;
  504. }
  505. /**
  506. * Get a list of the Users Email adresses
  507. *
  508. * @return array
  509. */
  510. function getUserEmail() {
  511. $res = array();
  512. foreach($this->data as $user) {
  513. $res[ $user['username'] ] = $user['email'];
  514. }
  515. return $res;
  516. }
  517. /**
  518. * Get all users as an array
  519. *
  520. * @return array
  521. */
  522. function getUsers() {
  523. return $this->data;
  524. }
  525. /**
  526. * Determines if $currentuser (or 'the current user', if left empty) is allowed
  527. * to edit a page or entry that's owned by $contentowner.
  528. *
  529. * @param string $contentowner
  530. * @param string $currentuser
  531. * @return boolean
  532. */
  533. function allowEdit($contenttype, $contentowner="", $currentuser="") {
  534. global $PIVOTX;
  535. // Default to the current logged in user.
  536. if (empty($currentuser)) {
  537. $currentuser = $PIVOTX['session']->currentUsername();
  538. }
  539. // Fetch the current user..
  540. $currentuser = $PIVOTX['users']->getUser( $currentuser );
  541. $currentuserlevel = (!$currentuser?PIVOTX_UL_NOBODY:$currentuser['userlevel']);
  542. // Always allow editing for superadmins - no matter content type.
  543. if ($currentuserlevel==PIVOTX_UL_SUPERADMIN) {
  544. return true;
  545. }
  546. // Fetch the owner..
  547. $contentowner = $PIVOTX['users']->getUser( $contentowner );
  548. $contentownerlevel = (!$contentowner?PIVOTX_UL_NOBODY:$contentowner['userlevel']);
  549. // Now run the checks for different content types
  550. if ($contenttype == 'chapter') {
  551. // Only sdministrator and superadmins can add, edit and delete chapters.
  552. if ($currentuserlevel>=PIVOTX_UL_ADMIN) {
  553. return true;
  554. }
  555. } else if (($contenttype == 'entry') || ($contenttype == 'page')) {
  556. // Get the value (if any) of allow_edit_for_own_userlevel setting
  557. $allowsamelevel = getDefault( $PIVOTX['config']->get('allow_edit_for_own_userlevel'), PIVOTX_UL_SUPERADMIN);
  558. if ($contentowner['username']==$currentuser['username']) {
  559. // Always allow editing of your own content..
  560. return true;
  561. } else if ($currentuserlevel > $contentownerlevel) {
  562. // Allow editing content for items owned by lower levels.
  563. return true;
  564. } else if ( ($currentuserlevel == $contentownerlevel) && ( $currentuserlevel >= $allowsamelevel) ) {
  565. // Allow if userlevel is the same, and greater than or equal to $allowsamelevel
  566. return true;
  567. }
  568. } else if (($contenttype == 'comment') || ($contenttype == 'trackback')) {
  569. if ($contentowner['username']==$currentuser['username']) {
  570. // Always allow editing of comments/trackback on your own entries.
  571. return true;
  572. } else if ($currentuserlevel >= PIVOTX_UL_ADVANCED) {
  573. return true;
  574. }
  575. } else {
  576. debug('Unknown content type');
  577. }
  578. // Disallow editing
  579. return false;
  580. }
  581. /**
  582. * Sort the users based on string comparison of username.
  583. *
  584. * @param array $a
  585. * @param array $b
  586. * @return int
  587. */
  588. function sort($a, $b) {
  589. global $PIVOTX;
  590. return strcmp($a['username'],$b['username']);
  591. }
  592. }
  593. /**
  594. * This class deals with the Weblogs.
  595. *
  596. */
  597. class Weblogs {
  598. var $default;
  599. var $current;
  600. /**
  601. * Initialisation
  602. *
  603. * @return Weblogs
  604. */
  605. function Weblogs() {
  606. global $PIVOTX;
  607. $this->data = loadSerialize($PIVOTX['paths']['db_path'] . "ser_weblogs.php", true);
  608. if ($this->count()<1) {
  609. // hmm, couldn't find the data.. Perhaps try to import it from old Pivot 1.x
  610. $this->readOld();
  611. $this->save();
  612. }
  613. if ($this->count()<1) {
  614. // No weblogs, create one from scratch
  615. $this->add('weblog', __('My weblog'), 'pivotxdefault');
  616. }
  617. foreach ($this->data as $key => $weblog) {
  618. // Unset '$subkey' weblog -> compensates for an old bug
  619. if (!empty($this->data[$key]['sub_weblog']['$subkey'])) {
  620. unset($this->data[$key]['sub_weblog']['$subkey']);
  621. }
  622. // Make sure all categories are arrays.
  623. foreach ($weblog['sub_weblog'] as $subkey => $subweblog) {
  624. if (!is_array($subweblog['categories'])) {
  625. $this->data[$key]['sub_weblog'][$subkey]['categories'] = array($subweblog['categories']);
  626. }
  627. }
  628. // Set the correct link to the weblog.
  629. if (empty($this->data[$key]['site_url'])) {
  630. $this->data[$key]['site_url'] = "";
  631. }
  632. $this->data[$key]['link'] = $this->_getLink($key, $this->data[$key]['site_url']);
  633. // Set the 'categories' for the combined subweblogs..
  634. $this->data[$key]['categories'] = $this->getCategories($key);
  635. }
  636. // Make sure the weblogs are sorted as intended.
  637. uasort($this->data, array($this, 'sort'));
  638. // Set default weblog either as specified by the root in the config
  639. // or just by selecting the first in the weblo
  640. list($type, $root) = explode(":", $PIVOTX['config']->get('root'));
  641. if ($type=="w" && !empty($root) && isset($this->data[$root]) ) {
  642. $this->default = $root;
  643. } else {
  644. // Nothing to do but fall back to the first available weblog..
  645. reset($this->data);
  646. $this->default = key($this->data);
  647. }
  648. }
  649. /**
  650. * Return all weblogs as an array
  651. *
  652. * @return array
  653. */
  654. function getWeblogs() {
  655. return $this->data;
  656. }
  657. /**
  658. * Returns an array with the weblog names.
  659. *
  660. * @return array
  661. */
  662. function getWeblogNames() {
  663. $names = array();
  664. foreach($this->data as $name=>$data) {
  665. $names[] = $name;
  666. }
  667. return $names;
  668. }
  669. /**
  670. * Check if a given $name is a weblog.
  671. *
  672. * @param string $name
  673. * @return boolean
  674. */
  675. function isWeblog($weblogname) {
  676. foreach ($this->data as $name=>$data) {
  677. if ($weblogname==$name) { return true; }
  678. }
  679. return false;
  680. }
  681. /**
  682. * Return the weblogs that have the given category or categories assigned
  683. * to them.
  684. *
  685. * @param array $categories
  686. */
  687. function getWeblogsWithCat($categories) {
  688. // $cats might be a string with one cat, if so, convert to array
  689. if (is_string($categories)) {
  690. $categories= array($categories);
  691. }
  692. $res=array();
  693. // search every weblog for all cats
  694. foreach ($this->data as $key => $weblog) {
  695. $weblogcategories = $this->getCategories($key);
  696. foreach ($categories as $cat) {
  697. if (in_array($cat, $weblogcategories)) {
  698. $res[]=$key;
  699. }
  700. }
  701. }
  702. return array_unique($res);
  703. }
  704. /**
  705. * Get the categories from a certain weblog.
  706. *
  707. * @param string $weblogname
  708. * @return array
  709. */
  710. function getCategories($weblogname='') {
  711. // if no weblogname was given, use the 'current'..
  712. if (empty($weblogname)) { $weblogname = $this->getCurrent(); }
  713. $results = array();
  714. // Group the categories from the subweblogs together..
  715. foreach ($this->data[$weblogname]['sub_weblog'] as $key=>$sub) {
  716. $cats = $sub['categories'];
  717. // $cats might be a string with one cat, if so, convert to array
  718. if (is_string($cats)) {
  719. $cats= array($cats);
  720. }
  721. // Add them to results
  722. foreach($cats as $cat) {
  723. $results[] = $cat;
  724. }
  725. }
  726. return array_unique($results);
  727. }
  728. /**
  729. * Returns the given weblog as an array. If no weblogname was given, use
  730. * the current weblog.
  731. *
  732. * @param string $weblogname
  733. * @return array
  734. */
  735. function getWeblog($weblogname='') {
  736. // if no weblogname was given, use the 'current'..
  737. if (empty($weblogname)) { $weblogname = $this->getCurrent(); }
  738. return $this->data[$weblogname];
  739. }
  740. /**
  741. * Return a subweblog as an array
  742. *
  743. * @param string $weblogname
  744. * @return array
  745. */
  746. function getSubweblog($weblogname='', $subweblogname) {
  747. // if no weblogname was given, use the 'current'..
  748. if (empty($weblogname)) { $weblogname = $this->getCurrent(); }
  749. return $this->data[$weblogname]['sub_weblog'][$subweblogname];
  750. }
  751. /**
  752. * Return the subweblogs of a given weblog as an array. It does this
  753. * by grabbing all [[weblog]] and [[ subweblog ]] tags from the templates
  754. * in the same folder as the template that was selected as the frontpage
  755. * template. Updates the subweblog info in the weblogs object.
  756. *
  757. * @param string $weblogname
  758. * @return array
  759. */
  760. function getSubweblogs($weblogname='') {
  761. global $PIVOTX;
  762. // if no weblogname was given, use the 'current'..
  763. if (empty($weblogname)) {
  764. $weblogname = $this->getCurrent();
  765. }
  766. $results = array();
  767. $weblog = $this->getWeblog($weblogname);
  768. $dirname = dirname($weblog['front_template']);
  769. if ( !is_dir($PIVOTX['paths']['templates_path'] . $dirname) || !is_readable($PIVOTX['paths']['templates_path'] . $dirname) ) {
  770. debug("Template folder $dirname doesn't exist or isn't readable");
  771. return array();
  772. }
  773. $dir = dir($PIVOTX['paths']['templates_path'] . $dirname);
  774. // Iterate through the files in the folder..
  775. while (false !== ($filename = $dir->read())) {
  776. $ext = getExtension($filename);
  777. if (in_array($ext, array('html', 'htm', 'tpl'))) {
  778. $template_html = loadTemplate($dirname . "/" . $filename);
  779. preg_match_all("/\[\[\s?(sub)?weblog([: ])(.*)?\]\]/mUi", $template_html, $matches);
  780. foreach($matches[3] as $key=>$match) {
  781. // if $matches[2][$key] was a ':', we know it's an old pivot 1.x style [[ subweblog:name ]]
  782. // We also must handle optional arguments to the subweblog.
  783. if ($matches[2][$key]==":") {
  784. $name = explode(':',$match);
  785. $results[] = trim($name[0]);
  786. } else {
  787. preg_match("/name=['\"]([^'\"]*)/mi", $match, $name);
  788. if ($name[1]!="") {
  789. $results[] = $name[1];
  790. }
  791. }
  792. }
  793. }
  794. }
  795. $dir->close();
  796. $results = array_unique($results);
  797. // Remove any subweblogs that no longer exists from the weblog data.
  798. $updated = false;
  799. foreach ($this->data[$weblogname]['sub_weblog'] as $name => $value) {
  800. if (!in_array($name,$results)) {
  801. unset($this->data[$weblogname]['sub_weblog'][$name]);
  802. $updated = true;
  803. }
  804. }
  805. if ($updated) {
  806. $this->save();
  807. }
  808. return $results;
  809. }
  810. /**
  811. * Sets a given weblog as 'current' and returns false if the weblog
  812. * doesn't exist.
  813. *
  814. * @param string $weblogname
  815. * @return boolean
  816. */
  817. function setCurrent($weblogname='') {
  818. global $PIVOTX;
  819. $exists = true;
  820. if ( !isset($this->data[$weblogname]) ) {
  821. $exists = false;
  822. $weblogname = '';
  823. }
  824. if (empty($weblogname)) {
  825. $this->current = $this->default;
  826. } else {
  827. $this->current = $weblogname;
  828. }
  829. return $exists;
  830. }
  831. /**
  832. * Sets a given weblog as 'current' based on a given category and returns false
  833. * if no matching weblog could be set.
  834. *
  835. * @param string $weblogname
  836. * @return boolean
  837. */
  838. function setCurrentFromCategory($categories) {
  839. // $cats might be a string with concatenated categories..
  840. if (strpos($categories, ",") > 0 ) {
  841. $categories = explode(",", $categories);
  842. $categories = array_map('trim', $categories);
  843. }
  844. // $cats might be a string with one cat, if so, convert to array
  845. if (is_string($categories)) {
  846. $categories= array($categories);
  847. }
  848. // Check categories in current weblog first (if set) and then the
  849. // default weblog
  850. if (!empty($this->current)) {
  851. $weblogcategories = $this->data[$this->current]['categories'];
  852. foreach ($categories as $cat) {
  853. if (in_array($cat, $weblogcategories)) {
  854. return true;
  855. }
  856. }
  857. } else {
  858. $weblogcategories = $this->data[$this->default]['categories'];
  859. foreach ($categories as $cat) {
  860. if (in_array($cat, $weblogcategories)) {
  861. $this->setCurrent($this->default);
  862. return true;
  863. }
  864. }
  865. }
  866. $skip_weblogs = array($this->current, $this->default);
  867. // search every weblog for all cats
  868. foreach ($this->data as $key => $weblog) {
  869. // Skip current and default since we checked them above
  870. if (in_array($key, $skip_weblogs)) {
  871. continue;
  872. }
  873. $weblogcategories = $this->getCategories($key);
  874. foreach ($categories as $cat) {
  875. if (in_array($cat, $weblogcategories)) {
  876. $this->setCurrent($key);
  877. return true;
  878. }
  879. }
  880. }
  881. return false;
  882. }
  883. /**
  884. * Gets the currently active weblog.
  885. *
  886. * @return
  887. */
  888. function getCurrent() {
  889. // Set the current weblog, just to be sure.
  890. if (empty($this->current)) { $this->setCurrent(""); }
  891. return $this->current;
  892. }
  893. /**
  894. * Gets the default weblog.
  895. *
  896. * @return
  897. */
  898. function getDefault() {
  899. return $this->default;
  900. }
  901. /**
  902. * Add a new weblog, based on $theme. returns the internal name used for
  903. * the weblog.
  904. *
  905. * @param string $internal
  906. * @param string $name
  907. * @param string $theme
  908. * @return string
  909. */
  910. function add($internal, $name, $theme) {
  911. if ( ($internal=="") || isset($this->data[$internal])) {
  912. // Make a new 'name'..
  913. for($i=1;$i<1000;$i++) {
  914. if (!isset($this->data[$internal . "_" . $i])) {
  915. $internal = $internal . "_" . $i;
  916. break;
  917. }
  918. }
  919. }
  920. if ($theme=="blank") {
  921. $this->data[$internal]['name']=$name;
  922. $this->save();
  923. } else if ($theme=="pivotxdefault") {
  924. $weblog = getDefaultWeblog();
  925. $weblog['name'] = $name;
  926. if (empty($weblog['sortorder'])) { $weblog['sortorder'] = 10; }
  927. $this->data[$internal] = $weblog;
  928. $this->save();
  929. } else {
  930. $weblog = loadSerialize($theme, true);
  931. $weblog['name'] = $name;
  932. if (empty($weblog['sortorder'])) { $weblog['sortorder'] = 10; }
  933. $this->data[$internal] = $weblog;
  934. $this->save();
  935. }
  936. return $internal;
  937. }
  938. /**
  939. * Delete a weblog
  940. *
  941. * @param string $weblogname
  942. */
  943. function delete($weblogname) {
  944. unset($this->data[$weblogname]);
  945. $this->save();
  946. }
  947. /**
  948. * Export a weblog as a theme file. The file is saved in the same folder as
  949. * the weblog's frontpage template.
  950. *
  951. * @param string $weblogname
  952. */
  953. function export($weblogname) {
  954. $weblog = $this->data[$weblogname];
  955. $filename = dirname("./templates/".$weblog['front_template'])."/".$weblogname.".theme";
  956. saveSerialize($filename, $weblog);
  957. }
  958. /**
  959. * Read old weblogs data..
  960. */
  961. function readOld() {
  962. $oldweblogs = loadSerialize(dirname(__FILE__)."/pv_cfg_weblogs.php", true);
  963. // Looping over old weblogs. For each old weblog, add a new one with
  964. // defaults values and then override the ones already set in the
  965. // old config. This way we remove settings no longer present in
  966. // PivotX. We also make sure the categories are all 'safe strings'..
  967. if(is_array($oldweblogs)) {
  968. foreach($oldweblogs as $weblogkey => $weblog) {
  969. $newweblogkey = safeString($weblogkey,true);
  970. $this->add($newweblogkey, $oldweblogs[$weblogkey]['name'], 'pivotxdefault');
  971. foreach ($this->data[$newweblogkey] as $key => $value) {
  972. if (isset($weblog[$key])) {
  973. $this->data[$newweblogkey][$key] = $weblog[$key];
  974. }
  975. }
  976. foreach($this->data[$newweblogkey]['sub_weblog'] as $subweblogkey => $subweblog) {
  977. foreach($subweblog['categories'] as $categorykey => $category) {
  978. $this->data[$newweblogkey]['sub_weblog'][$subweblogkey]['categories'][$categorykey] =
  979. safeString($category, true);
  980. }
  981. }
  982. foreach($this->data[$newweblogkey]['categories'] as $categorykey => $category) {
  983. $this->data[$newweblogkey]['categories'][$categorykey] = safeString($category, true);
  984. }
  985. }
  986. }
  987. }
  988. /**
  989. * Get the count of weblogs
  990. *
  991. * @return int
  992. */
  993. function count() {
  994. return ( is_array($this->data) && count($this->data) );
  995. }
  996. /**
  997. * Sets a property of a given weblog
  998. *
  999. * @param string $weblogname
  1000. * @param string $key
  1001. * @param string $value
  1002. */
  1003. function set($weblogname, $key, $value) {
  1004. if (isset($this->data[$weblogname])) {
  1005. if (strpos($key, "#")>0) {
  1006. // we're setting something in a subweblog
  1007. // we get these as linkdump#categories = linkdump,books,movies
  1008. list($sub, $key) = explode("#", str_replace("[]", "", $key));
  1009. if (strpos($value, ",")>0) {
  1010. $value = explode(",", $value);
  1011. }
  1012. $this->data[$weblogname]['sub_weblog'][$sub][$key] = $value;
  1013. // we must update the list of categories for the weblog
  1014. $categories = array();
  1015. foreach ($this->data[$weblogname]['sub_weblog'] as $subweblog) {
  1016. $categories = array_merge($categories,$subweblog['categories']);
  1017. }
  1018. $this->data[$weblogname]['categories'] = array_unique($categories);
  1019. } else {
  1020. if ($key == 'site_url') {
  1021. $this->data[$weblogname]['link'] = $this->_getLink($weblogname, $value);
  1022. }
  1023. $this->data[$weblogname][$key] = $value;
  1024. }
  1025. $this->save();
  1026. } else {
  1027. debug('tried to set a setting without passing a weblogname, or non-existing weblog');
  1028. }
  1029. }
  1030. /**
  1031. * Gets a property of a given weblog
  1032. *
  1033. * @param string $weblogname
  1034. * @param string $key
  1035. */
  1036. function get($weblogname, $key) {
  1037. if ($weblogname=="") {
  1038. $weblogname = $this->getCurrent();
  1039. }
  1040. if (empty($this->data[$weblogname])) {
  1041. debug("Weblog '$weblogname' doesn't exist!");
  1042. $weblogname = key($this->data);
  1043. }
  1044. return $this->data[$weblogname][$key];
  1045. }
  1046. /**
  1047. * Calculates the link for a given weblog
  1048. *
  1049. * @param string $value
  1050. * @param string $weblogname
  1051. */
  1052. function _getLink($weblogname, $value) {
  1053. global $PIVOTX;
  1054. $link = trim($value);
  1055. if ($link == '') {
  1056. if ($PIVOTX['config']->get('mod_rewrite')==0) {
  1057. $link = $PIVOTX['paths']['site_url'] . '?w=' . $weblogname;
  1058. } else {
  1059. $prefix = getDefault( $PIVOTX['config']->get('localised_weblog_prefix'), "weblog");
  1060. $link = $PIVOTX['paths']['site_url'] . $prefix . "/" . $weblogname;
  1061. }
  1062. } else {
  1063. $ext = getExtension(basename($link));
  1064. if ($ext == '') {
  1065. $link = addTrailingSlash($link);
  1066. }
  1067. }
  1068. return $link;
  1069. }
  1070. /**
  1071. * Save the weblogs to disk
  1072. *
  1073. */
  1074. function save() {
  1075. global $PIVOTX;
  1076. saveSerialize($PIVOTX['paths']['db_path'] . "ser_weblogs.php", $this->data);
  1077. }
  1078. /**
  1079. * Sort the weblogs based on string comparison of name.
  1080. *
  1081. * @param array $a
  1082. * @param array $b
  1083. * @return int
  1084. */
  1085. function sort($a, $b) {
  1086. global $PIVOTX;
  1087. if ( (empty($a['sortorder']) && empty($b['sortorder'])) || ($a['sortorder'] == $b['sortorder']) ) {
  1088. return strcmp($a['name'],$b['name']);
  1089. } else {
  1090. return ($a['sortorder'] < $b['sortorder']) ? -1 : 1;
  1091. }
  1092. }
  1093. }
  1094. /**
  1095. * This class deals with the categories
  1096. *
  1097. */
  1098. class Categories {
  1099. /**
  1100. * Initialisation
  1101. *
  1102. * @return Categories
  1103. */
  1104. function Categories() {
  1105. global $PIVOTX;
  1106. $this->data = loadSerialize($PIVOTX['paths']['db_path']."ser_categories.php", true);
  1107. if ($this->count()<1) {
  1108. // hmm, couldn't find the data.. Perhaps try to import it from old Pivot 1.x
  1109. $this->readOld();
  1110. $this->saveCategories();
  1111. }
  1112. if ($this->count()<1) {
  1113. // if there still are no categories, load the defaults
  1114. $this->data = getDefaultCategories();
  1115. $this->saveCategories();
  1116. }
  1117. // Make sure the categories are sorted as intended.
  1118. usort($this->data, array($this, 'sort'));
  1119. }
  1120. /**
  1121. * Get the count of categories
  1122. *
  1123. * @return int
  1124. */
  1125. function count() {
  1126. return ( is_array($this->data) && count($this->data) );
  1127. }
  1128. function readOld() {
  1129. global $pivotx_path;
  1130. // If the old config file doesn't exist or it isn't readable, we return false..
  1131. if (!file_exists($pivotx_path.'pv_cfg_settings.php') || (!is_readable($pivotx_path.'pv_cfg_settings.php'))) {
  1132. return false;
  1133. }
  1134. // get the config file
  1135. $fh = file($pivotx_path.'pv_cfg_settings.php');
  1136. foreach ($fh as $fh_this) {
  1137. @list($name, $val) = explode("!", $fh_this);
  1138. $Cfg[trim($name)] = trim($val);
  1139. }
  1140. //GetUserInfo();
  1141. //ExpandSessions();
  1142. $catnames = explode("|",$Cfg['cats']);
  1143. // Check which categories are "hidden"..
  1144. if (isset($Cfg['cats-searchexclusion'])) {
  1145. $hiddenarray = explode('|', strtolower($Cfg['cats-searchexclusion']));
  1146. } else {
  1147. $hiddenarray = array();
  1148. }
  1149. // Check the category order..
  1150. if (isset($Cfg['cats-order'])) {
  1151. $temp = explode('|-|', strtolower($Cfg['cats-order']));
  1152. foreach($temp as $item) {
  1153. list($catname, $order) = explode("|", $item);
  1154. $orderarray[strtolower($catname)] = $order;
  1155. }
  1156. } else {
  1157. $orderarray = array();
  1158. }
  1159. $cats = array();
  1160. foreach ($catnames as $cat) {
  1161. // Skip empty category names.
  1162. $catname = trim($cat);
  1163. if ($catname == '') {
  1164. continue;
  1165. }
  1166. $catname = strtolower($catname);
  1167. if (isset($Cfg['cat-'.$cat])) {
  1168. $users = explode('|', strtolower($Cfg['cat-'.$cat]));
  1169. } else {
  1170. $users = array();
  1171. }
  1172. // Make sure the users are 'safe strings'
  1173. foreach($users as $key=>$user) {
  1174. $users[$key] = safeString($user, true);
  1175. }
  1176. $cats[] = array (
  1177. 'name' => safeString($catname, true),
  1178. 'display' => $cat,
  1179. 'users' => $users,
  1180. 'hidden' => (in_array($catname, $hiddenarray)) ? 1 : 0,
  1181. 'order' => (isset($orderarray[$catname])) ? $orderarray[$catname] : 110,
  1182. );
  1183. }
  1184. $this->data = $cats;
  1185. }
  1186. /**
  1187. * change the settings for an existing category, or modify an existing one.
  1188. *
  1189. * @param string $name
  1190. * @param array $cat
  1191. */
  1192. function setCategory($name, $cat) {
  1193. $name = strtolower(safeString($name));
  1194. $cat['name'] = strtolower(safeString($cat['name']));
  1195. foreach($this->data as $key=>$val) {
  1196. if ($name==$val['name']) {
  1197. $this->data[$key] = $cat;
  1198. $this->saveCategories();
  1199. return;
  1200. }
  1201. }
  1202. // Otherwise it must be a new one, let's add it:
  1203. if(!empty($cat['name'])){
  1204. $this->data[] = $cat;
  1205. $this->saveCategories();
  1206. }
  1207. }
  1208. /**
  1209. * Save the categories to disk
  1210. *
  1211. */
  1212. function saveCategories() {
  1213. global $PIVOTX;
  1214. // If $this->data is empty, make it an empty array.
  1215. if (empty($this->data)) {
  1216. $this->data = array();
  1217. }
  1218. usort($this->data, array($this, 'sort'));
  1219. saveSerialize($PIVOTX['paths']['db_path'] . "ser_categories.php", $this->data);
  1220. }
  1221. /**
  1222. * Get an array with all the categories. We filter the users to make sure we only
  1223. * return users that still exist
  1224. *
  1225. * @return array
  1226. */
  1227. function getCategories() {
  1228. global $PIVOTX;
  1229. $results = $this->data;
  1230. $users = $PIVOTX['users']->getUsernames();
  1231. // Filter only existing users..
  1232. foreach ($results as $key=>$value) {
  1233. // Categories doesn't have to be assigned to any users.
  1234. if (isset($results[$key]['users']) && is_array($results[$key]['users'])) {
  1235. $results[$key]['users'] = array_intersect($results[$key]['users'], $users);
  1236. } else {
  1237. $results[$key]['users'] = array();
  1238. }
  1239. }
  1240. return $results;
  1241. }
  1242. /**
  1243. * Get a list of categories the user is allowed to post into
  1244. */
  1245. function allowedCategories($username) {
  1246. $allowed = array();
  1247. foreach($this->data as $cat) {
  1248. if (in_array($username, $cat['users'])) {
  1249. $allowed[$cat['name']] = $cat['name'];
  1250. }
  1251. }
  1252. return $allowed;
  1253. }
  1254. /**
  1255. * Allow a user to post in this category
  1256. *
  1257. * @param string $catname
  1258. * @param string $username
  1259. */
  1260. function allowUser($catname, $username) {
  1261. // Loop through all available categories
  1262. foreach($this->data as $key=>$cat) {
  1263. if ($cat['name']==$catname) {
  1264. // Add the username
  1265. $this->data[$key]['users'][] = $username;
  1266. // But remove duplicates
  1267. $this->data[$key]['users'] = array_unique($this->data[$key]['users']);
  1268. }
  1269. }
  1270. }
  1271. /**
  1272. * Disallow a user to post in this category
  1273. *
  1274. * @param string $catname
  1275. * @param string $username
  1276. */
  1277. function disallowUser($catname, $username) {
  1278. // Loop through all available categories
  1279. foreach($this->data as $key=>$cat) {
  1280. if ($cat['name']==$catname) {
  1281. // Loop through the users, and remove $username if present.
  1282. foreach($cat['users'] as $userkey=>$catuser){
  1283. if ($catuser==$username) {
  1284. unset($this->data[$key]['users'][$userkey]);
  1285. }
  1286. }
  1287. }
  1288. }
  1289. }
  1290. /**
  1291. * Get a single category
  1292. *
  1293. * @param string $name
  1294. * @return array
  1295. */
  1296. function getCategory($name) {
  1297. foreach($this->data as $key=>$cat) {
  1298. if ($cat['name']==$name) {
  1299. return $cat;
  1300. }
  1301. }
  1302. return array();
  1303. }
  1304. /**
  1305. * Get a list of all category names
  1306. *
  1307. * @return array
  1308. */
  1309. function getCategorynames() {
  1310. $names = array();
  1311. foreach($this->data as $cat) {
  1312. $names[]=$cat['name'];
  1313. }
  1314. return $names;
  1315. }
  1316. /**
  1317. * Check if a given $name is a category.
  1318. *
  1319. * @param string $name
  1320. * @return boolean
  1321. */
  1322. function isCategory($name) {
  1323. foreach($this->data as $cat) {
  1324. if($name==$cat['name']) { return true; }
  1325. }
  1326. return false;
  1327. }
  1328. /**
  1329. * Get a list of all category names in which we should NOT search
  1330. *
  1331. * @return array
  1332. */
  1333. function getSearchCategorynames() {
  1334. $names = array();
  1335. foreach($this->data as $cat) {
  1336. if ($cat['hidden']!=1) {
  1337. $names[]=$cat['name'];
  1338. }
  1339. }
  1340. return $names;
  1341. }
  1342. /**
  1343. * Delete a single category
  1344. *
  1345. * @param string $name
  1346. */
  1347. function deleteCategory($name) {
  1348. global $PIVOTX;
  1349. foreach($this->data as $key=>$cat) {
  1350. if ($cat['name']==$name) {
  1351. unset($this->data[$key]);
  1352. $this->saveCategories();
  1353. break;
  1354. }
  1355. }
  1356. // Remove it from all weblogs as well.
  1357. $weblogs = $PIVOTX['weblogs']->getWeblogs();
  1358. foreach($weblogs as $weblogkey=>$weblog) {
  1359. foreach($weblog['sub_weblog'] as $subweblogkey=>$subweblog) {
  1360. foreach($subweblog['categories'] as $catkey => $cat) {
  1361. if ($cat==$name) {
  1362. unset($weblogs[$weblogkey]['sub_weblog'][$subweblogkey]['categories'][$catkey]);
  1363. }
  1364. }
  1365. }
  1366. foreach($weblogs[$weblogkey]['categories'] as $catkey => $cat) {
  1367. if ($cat==$name) {
  1368. unset($weblogs[$weblogkey]['categories'][$catkey]);
  1369. }
  1370. }
  1371. }
  1372. $PIVOTX['weblogs']->data = $weblogs;
  1373. $PIVOTX['weblogs']->save();
  1374. }
  1375. /**
  1376. * Sort the categories based on the order and string comparison
  1377. * of display name if order is identical.
  1378. *
  1379. * @param array $a
  1380. * @param array $b
  1381. * @return int
  1382. */
  1383. function sort($a, $b) {
  1384. global $PIVOTX;
  1385. if ($PIVOTX['config']->get('sort_categories_by_alphabet')==true) {
  1386. // If we set 'sort_categories_by_alphabet' to true, always sort by alphabet..
  1387. return strcmp($a['display'],$b['display']);
  1388. } else if ($a['order'] == $b['order']) {
  1389. // Else sort by alphabet, if order is the same..
  1390. return strcmp($a['display'],$b['display']);
  1391. } else {
  1392. // else sort by order..
  1393. return ($a['order'] < $b['order']) ? -1 : 1;
  1394. }
  1395. }
  1396. }
  1397. /**
  1398. * This class deals with Sessions: logging in, logging out, saving sessions
  1399. * and performing checks for required userlevels.
  1400. *
  1401. * This class protects the cookie/session against standard XSS attacks and
  1402. * sidejacking.

Large files files are truncated, but you can click here to view the full file