PageRenderTime 33ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/campsite/src/classes/Issue.php

https://github.com/joechrysler/Campsite
PHP | 1069 lines | 657 code | 105 blank | 307 comment | 98 complexity | de6e20d41f9825ddb3e505a584001eec MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @package Campsite
  4. */
  5. /**
  6. * Includes
  7. */
  8. require_once($GLOBALS['g_campsiteDir'].'/db_connect.php');
  9. require_once($GLOBALS['g_campsiteDir'].'/classes/DatabaseObject.php');
  10. require_once($GLOBALS['g_campsiteDir'].'/classes/DbObjectArray.php');
  11. require_once($GLOBALS['g_campsiteDir'].'/classes/SQLSelectClause.php');
  12. require_once($GLOBALS['g_campsiteDir'].'/classes/Log.php');
  13. require_once($GLOBALS['g_campsiteDir'].'/classes/Language.php');
  14. require_once($GLOBALS['g_campsiteDir'].'/classes/Section.php');
  15. require_once($GLOBALS['g_campsiteDir'].'/classes/IssuePublish.php');
  16. require_once($GLOBALS['g_campsiteDir'].'/classes/CampCacheList.php');
  17. require_once($GLOBALS['g_campsiteDir'].'/template_engine/classes/CampTemplate.php');
  18. /**
  19. * @package Campsite
  20. */
  21. class Issue extends DatabaseObject {
  22. var $m_dbTableName = 'Issues';
  23. var $m_keyColumnNames = array('IdPublication', 'Number', 'IdLanguage');
  24. var $m_columnNames = array(
  25. 'IdPublication',
  26. 'Number',
  27. 'IdLanguage',
  28. 'Name',
  29. 'PublicationDate',
  30. 'Published',
  31. 'IssueTplId',
  32. 'SectionTplId',
  33. 'ArticleTplId',
  34. 'ShortName');
  35. var $m_languageName = null;
  36. /**
  37. * A publication has Issues, Issues have Sections and Articles.
  38. * @param int $p_publicationId
  39. * @param int $p_languageId
  40. * @param int $p_issueNumber
  41. */
  42. public function Issue($p_publicationId = null, $p_languageId = null,
  43. $p_issueNumber = null)
  44. {
  45. parent::DatabaseObject($this->m_columnNames);
  46. $this->m_data['IdPublication'] = $p_publicationId;
  47. $this->m_data['IdLanguage'] = $p_languageId;
  48. $this->m_data['Number'] = $p_issueNumber;
  49. if ($this->keyValuesExist()) {
  50. $this->fetch();
  51. }
  52. } // constructor
  53. /**
  54. * Create an issue.
  55. * @param string $p_shortName
  56. * @param array $p_values
  57. * @return boolean
  58. */
  59. public function create($p_shortName, $p_values = null)
  60. {
  61. $tmpValues = array('ShortName' => $p_shortName);
  62. if (!is_null($p_values)) {
  63. $tmpValues = array_merge($p_values, $tmpValues);
  64. }
  65. $success = parent::create($tmpValues);
  66. if ($success) {
  67. if (function_exists("camp_load_translation_strings")) {
  68. camp_load_translation_strings("api");
  69. }
  70. $logtext = getGS('Issue "$1" ($2) added in publication $3',
  71. $this->m_data['Name'], $this->m_data['Number'],
  72. $this->m_data['IdPublication']);
  73. Log::Message($logtext, null, 11);
  74. }
  75. return $success;
  76. } // fn create
  77. /**
  78. * Delete the Issue, and optionally all sections and articles contained within it.
  79. * @param boolean $p_deleteSections
  80. * @param boolean $p_deleteArticles
  81. * @return int
  82. * Return the number of articles deleted.
  83. */
  84. public function delete($p_deleteSections = true, $p_deleteArticles = true)
  85. {
  86. global $g_ado_db;
  87. // Delete all scheduled publishing events
  88. IssuePublish::OnIssueDelete($this->m_data['IdPublication'], $this->m_data['Number'], $this->m_data['IdLanguage']);
  89. $articlesDeleted = 0;
  90. if ($p_deleteSections) {
  91. $sections = Section::GetSections($this->m_data['IdPublication'], $this->m_data['Number'], $this->m_data['IdLanguage']);
  92. foreach ($sections as $section) {
  93. $articlesDeleted += $section->delete($p_deleteArticles);
  94. }
  95. }
  96. $tmpData = $this->m_data;
  97. $success = parent::delete();
  98. if ($success) {
  99. if (function_exists("camp_load_translation_strings")) {
  100. camp_load_translation_strings("api");
  101. }
  102. $logtext = getGS('Issue "$1" ($2) from publication $3 deleted',
  103. $tmpData['Name'], $tmpData['Number'],
  104. $tmpData['IdPublication']);
  105. Log::Message($logtext, null, 12);
  106. }
  107. return $articlesDeleted;
  108. } // fn delete
  109. /**
  110. * Copy this issue and all sections.
  111. * @param int $p_destPublicationId
  112. * @param int $p_destIssueId
  113. * @param int $p_destLanguageId
  114. * @return Issue
  115. */
  116. private function __copy($p_destPublicationId, $p_destIssueId, $p_destLanguageId)
  117. {
  118. // Copy the issue
  119. $newIssue = new Issue($p_destPublicationId, $p_destLanguageId, $p_destIssueId);
  120. $columns = array();
  121. $columns['Name'] = mysql_real_escape_string($this->getName());
  122. $columns['IssueTplId'] = $this->m_data['IssueTplId'];
  123. $columns['SectionTplId'] = $this->m_data['SectionTplId'];
  124. $columns['ArticleTplId'] = $this->m_data['ArticleTplId'];
  125. $created = $newIssue->create($p_destIssueId, $columns);
  126. if ($created) {
  127. // Copy the sections in the issue
  128. $sections = Section::GetSections($this->m_data['IdPublication'],
  129. $this->m_data['Number'],
  130. $this->m_data['IdLanguage']);
  131. foreach ($sections as $section) {
  132. $section->copy($p_destPublicationId, $p_destIssueId, $p_destLanguageId, null, false);
  133. }
  134. return $newIssue;
  135. } else {
  136. return null;
  137. }
  138. } // fn __copy
  139. /**
  140. * Create a copy of this issue. You can use this to:
  141. * 1) Translate an issue. In this case do:
  142. * $issue->copy(null, $issue->getIssueNumber(), $destinationLanguage);
  143. * 2) Duplicate all translations of an issue within a publication:
  144. * $issue->copy();
  145. * 3) Copy an issue to another publication:
  146. * $issue->copy($destinationPublication);
  147. * Note: All sections will be copied, but not the articles.
  148. *
  149. * @param int $p_destPublicationId
  150. * (optional) Specify the destination publication.
  151. * Default is this issue's publication ID.
  152. * @param int $p_destIssueId
  153. * (optional) Specify the destination issue ID.
  154. * If not specified, a new one will be generated.
  155. * @param int $p_destLanguageId
  156. * (optional) Use this if you want the copy to be a translation of the current issue.
  157. * Default is to copy all translations of this issue.
  158. * @return mixed
  159. * An array of Issues, a single Issue, or null on error.
  160. */
  161. public function copy($p_destPublicationId = null, $p_destIssueId = null,
  162. $p_destLanguageId = null)
  163. {
  164. global $g_ado_db;
  165. if (is_null($p_destPublicationId)) {
  166. $p_destPublicationId = $this->m_data['IdPublication'];
  167. }
  168. if (is_null($p_destIssueId)) {
  169. $p_destIssueId = Issue::GetUnusedIssueId($this->m_data['IdPublication']);
  170. }
  171. if (is_null($p_destLanguageId)) {
  172. $queryStr = 'SELECT * FROM Issues '
  173. .' WHERE IdPublication='.$this->m_data['IdPublication']
  174. .' AND Number='.$this->m_data['Number'];
  175. $srcIssues = DbObjectArray::Create('Issue', $queryStr);
  176. // Copy all translations of this issue.
  177. $newIssues = array();
  178. foreach ($srcIssues as $issue) {
  179. $newIssues[] = $issue->__copy($p_destPublicationId, $p_destIssueId, $issue->getLanguageId());
  180. }
  181. return $newIssues;
  182. } else {
  183. // Translate the issue.
  184. return $this->__copy($p_destPublicationId, $p_destIssueId, $p_destLanguageId);
  185. }
  186. } // fn copy
  187. /**
  188. * Return the publication ID of the publication that contains this issue.
  189. * @return int
  190. */
  191. public function getPublicationId()
  192. {
  193. return $this->m_data['IdPublication'];
  194. } // fn getPublicationId
  195. /**
  196. * Return the language ID of the issue.
  197. * @return int
  198. */
  199. public function getLanguageId()
  200. {
  201. return $this->m_data['IdLanguage'];
  202. } // fn getLanguageId
  203. /**
  204. * Changing an issue's language will change the section language as well.
  205. *
  206. * @param int $p_value
  207. */
  208. public function setLanguageId($p_value)
  209. {
  210. global $g_ado_db;
  211. $sql = "UPDATE Sections SET IdLanguage=$p_value"
  212. ." WHERE IdPublication=".$this->m_data['IdPublication']
  213. ." AND NrIssue=".$this->m_data['Number']
  214. ." AND IdLanguage=".$this->m_data['IdLanguage'];
  215. $success = $g_ado_db->Execute($sql);
  216. if ($success) {
  217. $this->setProperty('IdLanguage', $p_value);
  218. }
  219. } // fn setLanguageId
  220. /**
  221. * A simple way to get the name of the language the article is
  222. * written in. The value is cached in case there are multiple
  223. * calls to this function.
  224. *
  225. * @return string
  226. */
  227. public function getLanguageName()
  228. {
  229. if (is_null($this->m_languageName)) {
  230. $language = new Language($this->m_data['IdLanguage']);
  231. $this->m_languageName = $language->getNativeName();
  232. }
  233. return $this->m_languageName;
  234. } // fn getLanguageName
  235. /**
  236. * @return int
  237. */
  238. public function getIssueNumber()
  239. {
  240. return $this->m_data['Number'];
  241. } // fn getIssueNumber
  242. /**
  243. * Get the name of the issue.
  244. * @return string
  245. */
  246. public function getName()
  247. {
  248. return $this->m_data['Name'];
  249. } // fn getName
  250. /**
  251. * Set the name of the issue.
  252. * @param string
  253. * @return boolean
  254. */
  255. public function setName($p_value)
  256. {
  257. return $this->setProperty('Name', $p_value);
  258. } // fn setName
  259. /**
  260. * Get the string used for the URL to this issue.
  261. * @return string
  262. */
  263. public function getUrlName()
  264. {
  265. return $this->m_data['ShortName'];
  266. } // fn getUrlName
  267. /**
  268. * Set the string used in the URL to access this Issue.
  269. *
  270. * @return boolean
  271. */
  272. public function setUrlName($p_value)
  273. {
  274. return $this->setProperty('ShortName', $p_value);
  275. } // fn setUrlName
  276. /**
  277. * Get the default template ID used for articles in this issue.
  278. * @return int
  279. */
  280. public function getArticleTemplateId()
  281. {
  282. return $this->m_data['ArticleTplId'];
  283. } // fn getArticleTemplateId
  284. /**
  285. * Set the default template ID used for articles in this issue.
  286. *
  287. * @param int $p_value
  288. */
  289. public function setArticleTemplateId($p_value)
  290. {
  291. if (is_numeric($p_value)) {
  292. return $this->setProperty('ArticleTplId', $p_value);
  293. }
  294. } // fn setArticleTemplateId
  295. /**
  296. * Get the default template ID used for sections in this issue.
  297. * @return int
  298. */
  299. public function getSectionTemplateId()
  300. {
  301. return $this->m_data['SectionTplId'];
  302. } // fn getSectionTemplateId
  303. /**
  304. * Set the default template ID used for sections in this issue.
  305. *
  306. * @param int $p_value
  307. */
  308. public function setSectionTemplateId($p_value)
  309. {
  310. if (is_numeric($p_value)) {
  311. return $this->setProperty('SectionTplId', $p_value);
  312. }
  313. } // fn setSectionTemplateId
  314. /**
  315. * Get the template ID used for this issue.
  316. * @return int
  317. */
  318. public function getIssueTemplateId()
  319. {
  320. return $this->m_data['IssueTplId'];
  321. } // fn getIssueTemplateId
  322. /**
  323. * Set the template ID used for this issue.
  324. *
  325. * @param int $p_value
  326. */
  327. public function setIssueTemplateId($p_value)
  328. {
  329. if (is_numeric($p_value)) {
  330. return $this->setProperty('IssueTplId', $p_value);
  331. }
  332. } // fn setIssueTemplateId
  333. /**
  334. * Returns true if the issue was published
  335. *
  336. * @return boolean
  337. */
  338. public function isPublished() {
  339. return $this->m_data['Published'] == 'Y';
  340. }
  341. /**
  342. * Return the current state in the workflow:
  343. * 'Y' if the issue is published, 'N' if it is not published.
  344. *
  345. * @return string
  346. */
  347. public function getWorkflowStatus()
  348. {
  349. return $this->m_data['Published'];
  350. } // fn getWorkflowStatus
  351. /**
  352. * Set the workflow state of the issue.
  353. *
  354. * @param string $p_value
  355. * Can be NULL, 'Y', 'N', TRUE, or FALSE.
  356. * If set to NULL, the current value will be reversed.
  357. *
  358. * @return void
  359. */
  360. public function setWorkflowStatus($p_value = null)
  361. {
  362. $doPublish = null;
  363. if (is_null($p_value)) {
  364. if ($this->m_data['Published'] == 'Y') {
  365. $doPublish = false;
  366. } else {
  367. $doPublish = true;
  368. }
  369. } else {
  370. if (is_string($p_value)) {
  371. $p_value = strtoupper($p_value);
  372. }
  373. if (($this->m_data['Published'] == 'N') && (($p_value == 'Y') || ($p_value === true))) {
  374. $doPublish = true;
  375. } elseif (($this->m_data['Published'] == 'Y') && (($p_value == 'N') || ($p_value === false))) {
  376. $doPublish = false;
  377. }
  378. }
  379. if (!is_null($doPublish)) {
  380. Article::OnIssuePublish($this->getPublicationId(), $this->getLanguageId(),
  381. $this->getIssueNumber(), $doPublish);
  382. if ($doPublish) {
  383. $this->setProperty('Published', 'Y', true);
  384. $this->setProperty('PublicationDate', 'NOW()', true, true);
  385. } else {
  386. $this->setProperty('Published', 'N', true);
  387. }
  388. // Log message
  389. if (function_exists("camp_load_translation_strings")) {
  390. camp_load_translation_strings("api");
  391. }
  392. if ($this->getWorkflowStatus() == 'Y') {
  393. $status = getGS('Published');
  394. } else {
  395. $status = getGS('Not published');
  396. }
  397. $logtext = getGS('Issue $1 changed status to $2',
  398. $this->m_data['Number'].'. '.$this->m_data['Name'].' ('.$this->getLanguageName().')',
  399. $status);
  400. Log::Message($logtext, null, 14);
  401. }
  402. } // fn setWorkflowStatus
  403. /**
  404. * Get publication date in the form YYYY-MM-DD HH:MM:SS
  405. *
  406. * @return string
  407. */
  408. public function getPublicationDate()
  409. {
  410. return $this->m_data['PublicationDate'];
  411. } // fn getPublicationDate
  412. /**
  413. * Set the publication date. Given value should be in the form
  414. * YYYY-MM-DD HH:MM:SS.
  415. *
  416. * @param string $p_value
  417. */
  418. public function setPublicationDate($p_value)
  419. {
  420. if (is_string($p_value)) {
  421. return $this->setProperty('PublicationDate', $p_value);
  422. }
  423. } // fn setPublicationDate
  424. /**
  425. * Get all the languages to which this issue has been translated.
  426. *
  427. * @param boolean $p_getUnusedLanguagesOnly
  428. * Reverses the search and finds only those languages which this
  429. * issue has not been translated into.
  430. * @param boolean $p_excludeCurrent
  431. * If true, exclude the current language from the list.
  432. * @param array $p_order
  433. * The array of order directives in the format:
  434. * array('field'=>field_name, 'dir'=>order_direction)
  435. * field_name can take one of the following values:
  436. * bynumber, byname, byenglish_name, bycode
  437. * order_direction can take one of the following values:
  438. * asc, desc
  439. * @param boolean $p_allIssues
  440. * If true return all the languages in which all issues of the
  441. * publication were translated.
  442. * @return array
  443. * Return an array of Language objects.
  444. */
  445. public function getLanguages($p_getUnusedLanguagesOnly = false,
  446. $p_excludeCurrent = false, array $p_order = array(), $p_allIssues = false,
  447. $p_published = false)
  448. {
  449. $tmpLanguage = new Language();
  450. $columnNames = $tmpLanguage->getColumnNames(true);
  451. if ($p_getUnusedLanguagesOnly) {
  452. $queryStr = "SELECT ".implode(',', $columnNames)
  453. ." FROM Languages LEFT JOIN Issues "
  454. ." ON Issues.IdPublication = ".$this->m_data['IdPublication'];
  455. if (!$p_allIssues) {
  456. $queryStr .= " AND Issues.Number = ".$this->m_data['Number'];
  457. }
  458. if ($p_published) {
  459. $queryStr .= " AND Issues.Published = 'Y'";
  460. }
  461. $queryStr .= " AND Issues.IdLanguage = Languages.Id "
  462. ." WHERE Issues.IdPublication IS NULL";
  463. } else {
  464. $queryStr = "SELECT ".implode(',', $columnNames)
  465. ." FROM Languages, Issues "
  466. ." WHERE Issues.IdPublication = ".$this->m_data['IdPublication'];
  467. if (!$p_allIssues) {
  468. $queryStr .= " AND Issues.Number = ".$this->m_data['Number'];
  469. }
  470. $queryStr .= " AND Issues.IdLanguage = Languages.Id ";
  471. if ($p_excludeCurrent) {
  472. $queryStr .= " AND Languages.Id != " . $this->m_data['IdLanguage'];
  473. }
  474. if ($p_published) {
  475. $queryStr .= " AND Issues.Published = 'Y'";
  476. }
  477. }
  478. list($languagesKey) = $tmpLanguage->getKeyColumnNames();
  479. $queryStr .= " GROUP BY $languagesKey";
  480. $order = Issue::ProcessLanguageListOrder($p_order);
  481. foreach ($order as $orderDesc) {
  482. $sqlOrder[] = $orderDesc['field'] . ' ' . $orderDesc['dir'];
  483. }
  484. if (count($sqlOrder) > 0) {
  485. $queryStr .= ' ORDER BY ' . implode(', ', $sqlOrder);
  486. }
  487. $languages = DbObjectArray::Create('Language', $queryStr);
  488. return $languages;
  489. } // fn getLanguages
  490. /**
  491. * Get all the issues in the given publication as return them as an array
  492. * of Issue objects.
  493. *
  494. * @param int $p_publicationId
  495. * The publication ID.
  496. *
  497. * @param int $p_languageId
  498. * (Optional) Only return issues with this language.
  499. *
  500. * @param int $p_issueId
  501. * (Optional) Only return issues with this Issue ID.
  502. *
  503. * @param string $p_urlName
  504. * (Optional) Only return issues that match this URL Name.
  505. *
  506. * @param int $p_preferredLanguage
  507. * (Optional) List this language before others. This will override any 'ORDER BY' sql
  508. * options you have.
  509. *
  510. * @param array $p_sqlOptions
  511. *
  512. * @return array
  513. */
  514. public static function GetIssues($p_publicationId = null,
  515. $p_languageId = null,
  516. $p_issueNumber = null,
  517. $p_urlName = null,
  518. $p_preferredLanguage = null,
  519. $p_publishedOnly = false,
  520. $p_sqlOptions = null, $p_skipCache = false)
  521. {
  522. global $g_ado_db;
  523. if (!$p_skipCache && CampCache::IsEnabled()) {
  524. $paramsArray['publication_id'] = (is_null($p_publicationId)) ? 'null' : $p_publicationId;
  525. $paramsArray['language_id'] = (is_null($p_languageId)) ? 'null' : $p_languageId;
  526. $paramsArray['issue_number'] = (is_null($p_issueNumber)) ? 'null' : $p_issueNumber;
  527. $paramsArray['url_name'] = (is_null($p_urlName)) ? 'null' : $p_urlName;
  528. $paramsArray['preferred_language'] = (is_null($p_preferredLanguage)) ? 'null' : $p_preferredLanguage;
  529. $paramsArray['published_only'] = $p_publishedOnly ? 'true' : 'false';
  530. $paramsArray['sql_options'] = (is_null($p_sqlOptions)) ? 'null' : $p_sqlOptions;
  531. $cacheListObj = new CampCacheList($paramsArray, __METHOD__);
  532. $issuesList = $cacheListObj->fetchFromCache();
  533. if ($issuesList !== false && is_array($issuesList)) {
  534. return $issuesList;
  535. }
  536. }
  537. $tmpIssue = new Issue();
  538. $columnNames = $tmpIssue->getColumnNames(true);
  539. $queryStr = 'SELECT '.implode(',', $columnNames);
  540. if (!is_null($p_preferredLanguage)) {
  541. $queryStr .= ", abs(IdLanguage-$p_preferredLanguage) as LanguageOrder";
  542. $p_sqlOptions['ORDER BY'] = array('Number' => 'DESC', 'LanguageOrder' => 'ASC');
  543. }
  544. // We have to display the language name so oftern that we might
  545. // as well fetch it by default.
  546. $queryStr .= ', Languages.OrigName as LanguageName';
  547. $queryStr .= ' FROM Issues, Languages ';
  548. $whereClause = array();
  549. $whereClause[] = "Issues.IdLanguage=Languages.Id";
  550. if (!is_null($p_publicationId)) {
  551. $whereClause[] = "Issues.IdPublication=$p_publicationId";
  552. }
  553. if (!is_null($p_languageId)) {
  554. $whereClause[] = "Issues.IdLanguage=$p_languageId";
  555. }
  556. if (!is_null($p_issueNumber)) {
  557. $whereClause[] = "Issues.Number=$p_issueNumber";
  558. }
  559. if (!is_null($p_urlName)) {
  560. $whereClause[] = "Issues.ShortName='".$g_ado_db->escape($p_urlName)."'";
  561. }
  562. if ($p_publishedOnly) {
  563. $whereClause[] = "Issues.Published = 'Y'";
  564. }
  565. if (count($whereClause) > 0) {
  566. $queryStr .= ' WHERE '.implode(' AND ', $whereClause);
  567. }
  568. $queryStr = DatabaseObject::ProcessOptions($queryStr, $p_sqlOptions);
  569. $issues = array();
  570. $rows = $g_ado_db->GetAll($queryStr);
  571. if (is_array($rows)) {
  572. foreach ($rows as $row) {
  573. $tmpObj = new Issue();
  574. $tmpObj->fetch($row);
  575. $tmpObj->m_languageName = $row['LanguageName'];
  576. $issues[] = $tmpObj;
  577. }
  578. }
  579. if (!$p_skipCache && CampCache::IsEnabled()) {
  580. $cacheListObj->storeInCache($issues);
  581. }
  582. return $issues;
  583. } // fn GetIssues
  584. /**
  585. * Return the total number of issues in the database.
  586. *
  587. * @param int $p_publicationId
  588. * If specified, return the total number of issues in the given publication.
  589. *
  590. * @return int
  591. */
  592. public static function GetNumIssues($p_publicationId = null)
  593. {
  594. global $g_ado_db;
  595. $queryStr = 'SELECT COUNT(*) FROM Issues ';
  596. if (is_numeric($p_publicationId)) {
  597. $queryStr .= " WHERE IdPublication=$p_publicationId";
  598. }
  599. $total = $g_ado_db->GetOne($queryStr);
  600. return $total;
  601. } // fn GetNumIssues
  602. /**
  603. * Return an issue number that is not in use.
  604. * @param int $p_publicationId
  605. * @return int
  606. */
  607. public static function GetUnusedIssueId($p_publicationId)
  608. {
  609. global $g_ado_db;
  610. $queryStr = "SELECT MAX(Number) + 1 FROM Issues "
  611. ." WHERE IdPublication=$p_publicationId";
  612. $number = $g_ado_db->GetOne($queryStr);
  613. return $number;
  614. } // fn GetUnusedIssueId
  615. /**
  616. * Returns the last published issue for the given publication / language.
  617. * Returns null if no issue was found.
  618. *
  619. * @param int $p_publicationId
  620. * @param int $p_languageId
  621. * @return mixed
  622. */
  623. public static function GetCurrentIssue($p_publicationId, $p_languageId = null)
  624. {
  625. global $g_ado_db;
  626. if (CampCache::IsEnabled()) {
  627. $paramString = $p_publicationId . '_';
  628. $paramString.= (is_null($p_languageId)) ? 'null_' : $p_languageId . '_';
  629. $cacheKey = __CLASS__ . '_CurrentIssue_' . $paramString;
  630. $issue = CampCache::singleton()->fetch($cacheKey);
  631. if ($issue !== false && is_object($issue)) {
  632. return $issue;
  633. }
  634. }
  635. $queryStr = "SELECT Number, IdLanguage FROM Issues WHERE Published = 'Y' AND "
  636. . "IdPublication = $p_publicationId";
  637. if (!is_null($p_languageId)) {
  638. $queryStr .= " AND IdLanguage = $p_languageId";
  639. }
  640. $queryStr .= " ORDER BY Number DESC LIMIT 0, 1";
  641. $result = $g_ado_db->GetRow($queryStr);
  642. if (is_null($result)) {
  643. return null;
  644. }
  645. $issue = new Issue($p_publicationId, $result['IdLanguage'], $result['Number']);
  646. if (CampCache::IsEnabled()) {
  647. CampCache::singleton()->store($cacheKey, $issue);
  648. }
  649. return $issue;
  650. } // fn GetCurrentIssue
  651. /**
  652. * Return the last Issue created in this publication or NULL if there
  653. * are no previous issues.
  654. *
  655. * @param int $p_publicationId
  656. * @return Issue
  657. */
  658. public static function GetLastCreatedIssue($p_publicationId)
  659. {
  660. global $g_ado_db;
  661. $queryStr = "SELECT MAX(Number) FROM Issues WHERE IdPublication=$p_publicationId";
  662. $maxIssueNumber = $g_ado_db->GetOne($queryStr);
  663. if (empty($maxIssueNumber)) {
  664. return null;
  665. }
  666. $queryStr = "SELECT IdLanguage FROM Issues WHERE IdPublication=$p_publicationId AND Number=$maxIssueNumber";
  667. $idLanguage = $g_ado_db->GetOne($queryStr);
  668. $issue = new Issue($p_publicationId, $idLanguage, $maxIssueNumber);
  669. return $issue;
  670. } // fn GetLastCreatedIssue
  671. /**
  672. * @param int $p_publicationId
  673. *
  674. * @param int $p_languageId
  675. *
  676. * @param int $p_skipCache
  677. *
  678. *
  679. * @return mixed
  680. * array of issue publication dates
  681. * null if query does not match any issue
  682. */
  683. public static function GetPublicationDates($p_publicationId,
  684. $p_languageId,
  685. $p_skipCache = false)
  686. {
  687. global $g_ado_db;
  688. $queryStr = 'SELECT Number FROM Issues '
  689. . 'WHERE IdPublication = ' . $p_publicationId . ' AND '
  690. . 'IdLanguage = ' . $p_languageId . " AND Published = 'Y'";
  691. $rows = $g_ado_db->GetAll($queryStr);
  692. $dates = array();
  693. if (is_array($rows)) {
  694. foreach ($rows as $row) {
  695. $tmpObj = new Issue($p_publicationId, $p_languageId,
  696. $row['Number']);
  697. if ($tmpObj->exists()) {
  698. $dates[] = $tmpObj->getPublicationDate();
  699. }
  700. }
  701. }
  702. if (empty($dates)) {
  703. return null;
  704. }
  705. return array_unique($dates);
  706. } // fn GetPublicationDates
  707. /**
  708. * Gets an issues list based on the given parameters.
  709. *
  710. * @param array $p_parameters
  711. * An array of ComparisonOperation objects
  712. * @param string $p_order
  713. * An array of columns and directions to order by
  714. * @param integer $p_start
  715. * The record number to start the list
  716. * @param integer $p_limit
  717. * The offset. How many records from $p_start will be retrieved.
  718. * @param integer $p_count
  719. * The total count of the elements; this count is computed without
  720. * applying the start ($p_start) and limit parameters ($p_limit)
  721. *
  722. * @return array $issuesList
  723. * An array of Issue objects
  724. */
  725. public static function GetList(array $p_parameters, $p_order = null,
  726. $p_start = 0, $p_limit = 0, &$p_count, $p_skipCache = false)
  727. {
  728. global $g_ado_db;
  729. if (!$p_skipCache && CampCache::IsEnabled()) {
  730. $paramsArray['parameters'] = serialize($p_parameters);
  731. $paramsArray['order'] = (is_null($p_order)) ? 'null' : $p_order;
  732. $paramsArray['start'] = $p_start;
  733. $paramsArray['limit'] = $p_limit;
  734. $cacheListObj = new CampCacheList($paramsArray, __METHOD__);
  735. $issuesList = $cacheListObj->fetchFromCache();
  736. if ($issuesList !== false && is_array($issuesList)) {
  737. return $issuesList;
  738. }
  739. }
  740. $hasPublicationId = false;
  741. $selectClauseObj = new SQLSelectClause();
  742. $countClauseObj = new SQLSelectClause();
  743. // sets the where conditions
  744. foreach ($p_parameters as $param) {
  745. $comparisonOperation = self::ProcessListParameters($param);
  746. if (empty($comparisonOperation)) {
  747. break;
  748. }
  749. if (strpos($comparisonOperation['left'], 'IdPublication') !== false) {
  750. $hasPublicationId = true;
  751. }
  752. $whereCondition = $comparisonOperation['left'] . ' '
  753. . $comparisonOperation['symbol'] . " '"
  754. . $comparisonOperation['right'] . "' ";
  755. $selectClauseObj->addWhere($whereCondition);
  756. $countClauseObj->addWhere($whereCondition);
  757. }
  758. // validates whether publication identifier was given
  759. if ($hasPublicationId == false) {
  760. CampTemplate::singleton()->trigger_error('missed parameter Publication '
  761. .'Identifier in statement list_topics');
  762. return;
  763. }
  764. // sets the columns to be fetched
  765. $tmpIssue = new Issue();
  766. $columnNames = $tmpIssue->getColumnNames(true);
  767. foreach ($columnNames as $columnName) {
  768. $selectClauseObj->addColumn($columnName);
  769. }
  770. $countClauseObj->addColumn('COUNT(*)');
  771. // sets the main table for the query
  772. $selectClauseObj->setTable($tmpIssue->getDbTableName());
  773. $countClauseObj->setTable($tmpIssue->getDbTableName());
  774. unset($tmpIssue);
  775. if (is_array($p_order)) {
  776. $order = Issue::ProcessListOrder($p_order);
  777. // sets the order condition if any
  778. foreach ($order as $orderDesc) {
  779. $orderField = $orderDesc['field'];
  780. $orderDirection = $orderDesc['dir'];
  781. $selectClauseObj->addOrderBy($orderField . ' ' . $orderDirection);
  782. }
  783. }
  784. $selectClauseObj->addGroupField('Number');
  785. $selectClauseObj->addGroupField('IdLanguage');
  786. // sets the limit
  787. $selectClauseObj->setLimit($p_start, $p_limit);
  788. // builds the query and executes it
  789. $selectQuery = $selectClauseObj->buildQuery();
  790. $countQuery = $countClauseObj->buildQuery();
  791. $issues = $g_ado_db->GetAll($selectQuery);
  792. if (is_array($issues)) {
  793. $p_count = $g_ado_db->GetOne($countQuery);
  794. // builds the array of issue objects
  795. $issuesList = array();
  796. foreach ($issues as $issue) {
  797. $issObj = new Issue($issue['IdPublication'],
  798. $issue['IdLanguage'],
  799. $issue['Number']);
  800. if ($issObj->exists()) {
  801. $issuesList[] = $issObj;
  802. }
  803. }
  804. } else {
  805. $issuesList = array();
  806. $p_count = 0;
  807. }
  808. if (!$p_skipCache && CampCache::IsEnabled()) {
  809. $cacheListObj->storeInCache($issuesList);
  810. }
  811. return $issuesList;
  812. } // fn GetList
  813. /**
  814. * Processes a paremeter (condition) coming from template tags.
  815. *
  816. * @param array $p_param
  817. * The array of parameters
  818. *
  819. * @return array $comparisonOperation
  820. * The array containing processed values of the condition
  821. */
  822. private static function ProcessListParameters($p_param)
  823. {
  824. $comparisonOperation = array();
  825. switch (strtolower($p_param->getLeftOperand())) {
  826. case 'year':
  827. case 'publish_year':
  828. $comparisonOperation['left'] = 'YEAR(PublicationDate)';
  829. break;
  830. case 'mon_nr':
  831. case 'publish_month':
  832. $comparisonOperation['left'] = 'MONTH(PublicationDate)';
  833. break;
  834. case 'mday':
  835. case 'publish_mday':
  836. $comparisonOperation['left'] = 'DAYOFMONTH(PublicationDate)';
  837. break;
  838. case 'yday':
  839. $comparisonOperation['left'] = 'DAYOFYEAR(PublicationDate)';
  840. break;
  841. case 'wday':
  842. $comparisonOperation['left'] = 'DAYOFWEEK(PublicationDate)';
  843. break;
  844. case 'hour':
  845. $comparisonOperation['left'] = 'HOUR(PublicationDate)';
  846. break;
  847. case 'min':
  848. $comparisonOperation['left'] = 'MINUTE(PublicationDate)';
  849. break;
  850. case 'sec':
  851. $comparisonOperation['left'] = 'SECOND(PublicationDate)';
  852. break;
  853. case 'name':
  854. $comparisonOperation['left'] = 'Name';
  855. break;
  856. case 'number':
  857. $comparisonOperation['left'] = 'Number';
  858. break;
  859. case 'publish_date':
  860. case 'publicationdate':
  861. $comparisonOperation['left'] = 'DATE(PublicationDate)';
  862. break;
  863. case 'idpublication':
  864. $comparisonOperation['left'] = 'IdPublication';
  865. break;
  866. case 'idlanguage':
  867. $comparisonOperation['left'] = 'IdLanguage';
  868. break;
  869. case 'published':
  870. if (strtolower($p_param->getRightOperand()) == 'true') {
  871. $comparisonOperation['left'] = 'Published';
  872. $comparisonOperation['symbol'] = '=';
  873. $comparisonOperation['right'] = 'Y';
  874. return $comparisonOperation;
  875. }
  876. break;
  877. }
  878. if (isset($comparisonOperation['left'])) {
  879. $operatorObj = $p_param->getOperator();
  880. $comparisonOperation['right'] = $p_param->getRightOperand();
  881. $comparisonOperation['symbol'] = $operatorObj->getSymbol('sql');
  882. }
  883. return $comparisonOperation;
  884. } // fn ProcessListParameters
  885. /**
  886. * Processes an order directive coming from template tags.
  887. *
  888. * @param array $p_order
  889. * The array of order directives
  890. *
  891. * @return array
  892. * The array containing processed values of the condition
  893. */
  894. private static function ProcessListOrder(array $p_order)
  895. {
  896. $order = array();
  897. foreach ($p_order as $orderDesc) {
  898. $field = $orderDesc['field'];
  899. $direction = $orderDesc['dir'];
  900. $dbField = null;
  901. switch (strtolower($field)) {
  902. case 'bynumber':
  903. $dbField = 'Number';
  904. break;
  905. case 'byname':
  906. $dbField = 'Name';
  907. break;
  908. case 'bydate':
  909. case 'bycreationdate':
  910. case 'bypublishdate':
  911. $dbField = 'PublicationDate';
  912. break;
  913. }
  914. if (!is_null($dbField)) {
  915. $direction = !empty($direction) ? $direction : 'asc';
  916. }
  917. $order[] = array('field'=>$dbField, 'dir'=>$direction);
  918. }
  919. return $order;
  920. }
  921. /**
  922. * Processes an order directive for the issue translations list.
  923. *
  924. * @param array $p_order
  925. * The array of order directives in the format:
  926. * array('field'=>field_name, 'dir'=>order_direction)
  927. * field_name can take one of the following values:
  928. * bynumber, byname, byenglish_name, bycode
  929. * order_direction can take one of the following values:
  930. * asc, desc
  931. *
  932. * @return array
  933. * The array containing processed values of the condition
  934. */
  935. private static function ProcessLanguageListOrder(array $p_order)
  936. {
  937. $order = array();
  938. foreach ($p_order as $orderDesc) {
  939. $field = $orderDesc['field'];
  940. $direction = $orderDesc['dir'];
  941. $dbField = null;
  942. switch (strtolower($field)) {
  943. case 'bynumber':
  944. $dbField = 'Languages.Id';
  945. break;
  946. case 'byname':
  947. $dbField = 'Languages.OrigName';
  948. break;
  949. case 'byenglish_name':
  950. $dbField = 'Languages.Name';
  951. break;
  952. case 'bycode':
  953. $dbField = 'Languages.Code';
  954. break;
  955. }
  956. if (!is_null($dbField)) {
  957. $direction = !empty($direction) ? $direction : 'asc';
  958. }
  959. $order[] = array('field'=>$dbField, 'dir'=>$direction);
  960. }
  961. return $order;
  962. }
  963. } // class Issue
  964. ?>