PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/campsite/src/classes/ArticleData.php

https://github.com/joechrysler/Campsite
PHP | 350 lines | 261 code | 28 blank | 61 comment | 36 complexity | 1ccdea3492074b7d12856a8e6de66a10 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'].'/classes/DatabaseObject.php');
  9. require_once($GLOBALS['g_campsiteDir'].'/classes/ArticleTypeField.php');
  10. require_once($GLOBALS['g_campsiteDir'].'/classes/ArticleType.php');
  11. /**
  12. * @package Campsite
  13. */
  14. class ArticleData extends DatabaseObject {
  15. var $m_columnNames = array('NrArticle', 'IdLanguage');
  16. var $m_keyColumnNames = array('NrArticle', 'IdLanguage');
  17. var $m_dbTableName;
  18. var $m_articleTypeName;
  19. private $m_articleTypeObject = null;
  20. /**
  21. * An article type is a dynamic table that is created for an article
  22. * to allow different publications to display their content in different
  23. * ways.
  24. *
  25. * @param string $p_articleType
  26. * @param int $p_articleNumber
  27. * @param int $p_languageId
  28. */
  29. public function ArticleData($p_articleType, $p_articleNumber, $p_languageId)
  30. {
  31. $this->m_articleTypeName = $p_articleType;
  32. $this->m_dbTableName = 'X'.$p_articleType;
  33. if (empty($this->m_articleTypeName)) {
  34. return;
  35. }
  36. // Get user-defined values.
  37. $dbColumns = $this->getUserDefinedColumns(true);
  38. foreach ($dbColumns as $columnMetaData) {
  39. $this->m_columnNames[] = $columnMetaData->getName();
  40. }
  41. parent::DatabaseObject($this->m_columnNames);
  42. $this->m_data['NrArticle'] = $p_articleNumber;
  43. $this->m_data['IdLanguage'] = $p_languageId;
  44. if ($this->keyValuesExist()) {
  45. $this->fetch();
  46. }
  47. } // constructor
  48. public function getFieldValue($p_property, $p_forceFetchFromDatabase = false)
  49. {
  50. $dbColumnName = 'F'.$p_property;
  51. return parent::getProperty($dbColumnName, $p_forceFetchFromDatabase);
  52. }
  53. /**
  54. * Gets the translation for a given language; default language is the
  55. * session language. If no translation is set for that language, we
  56. * return the dbTableName.
  57. *
  58. * @param int p_lang
  59. *
  60. * @return string
  61. */
  62. public function getDisplayName($p_lang = 0)
  63. {
  64. if (!$p_lang) {
  65. $lang = camp_session_get('LoginLanguageId', 1);
  66. } else {
  67. $lang = $p_lang;
  68. }
  69. $aObj = new ArticleType($this->m_articleTypeName);
  70. $translations = $aObj->getTranslations();
  71. if (!isset($translations[$lang])) return substr($aObj->getTableName(), 1);
  72. return $translations[$lang];
  73. } // fn getDisplayName
  74. public function setProperty($p_dbColumnName, $p_value, $p_commit = true, $p_isSql = false)
  75. {
  76. if (!in_array($p_dbColumnName, $this->m_columnNames)) {
  77. return false;
  78. }
  79. $articleField = new ArticleTypeField($this->m_articleTypeName, substr($p_dbColumnName, 1));
  80. if ($articleField->getType() == ArticleTypeField::TYPE_BODY) {
  81. // Replace <span class="subhead"> ... </span> with <!** Title> ... <!** EndTitle>
  82. $text = preg_replace_callback("/(<\s*span[^>]*class\s*=\s*[\"']campsite_subhead[\"'][^>]*>|<\s*span|<\s*\/\s*span\s*>)/i",
  83. array('ArticleData', "TransformSubheads"), $p_value);
  84. // Replace <a href="campsite_internal_link?IdPublication=1&..." ...> ... </a>
  85. // with <!** Link Internal IdPublication=1&...> ... <!** EndLink>
  86. $text = preg_replace_callback("/(<\s*a\s*(((href\s*=\s*[\"'](\\/campsite\\/)?campsite_internal_link[?][\w&=;]*[\"'])|(\w+\s*=\s*['\"][_\w]*['\"]))+[\s]*)*[\s\w\"']*>)|(<\s*\/a\s*>)/i",
  87. array('ArticleData', "TransformInternalLinks"), $text);
  88. // Replace <img id=".." src=".." alt=".." title=".." align="..">
  89. // with <!** Image [image_template_id] align=".." alt=".." sub="..">
  90. $idAttr = "(id\s*=\s*\"[^\"]*\")";
  91. $srcAttr = "(src\s*=\s*\"[^\"]*\")";
  92. $altAttr = "(alt\s*=\s*\"[^\"]*\")";
  93. $subAttr = "(title\s*=\s*\"[^\"]*\")";
  94. $alignAttr = "(align\s*=\s*\"[^\"]*\")";
  95. $widthAttr = "(width\s*=\s*\"[^\"]*\")";
  96. $heightAttr = "(height\s*=\s*\"[^\"]*\")";
  97. $otherAttr = "(\w+\s*=\s*\"[^\"]*\")*";
  98. $pattern = "/<\s*img\s*(($idAttr|$srcAttr|$altAttr|$subAttr|$alignAttr|$widthAttr|$heightAttr|$otherAttr)\s*)*\/>/i";
  99. $p_value = preg_replace_callback($pattern, array($this, "transformImageTags"), $text);
  100. }
  101. if ($articleField->getType() == ArticleTypeField::TYPE_SWITCH) {
  102. return parent::setProperty($p_dbColumnName, (int)($p_value == 'on'), $p_commit);
  103. }
  104. return parent::setProperty($p_dbColumnName, $p_value, $p_commit, $p_isSql);
  105. }
  106. /**
  107. * Copy the row in the database.
  108. * @param int $p_destArticleNumber
  109. * @return void
  110. */
  111. public function copy($p_destArticleNumber)
  112. {
  113. global $g_ado_db;
  114. $tmpData = $this->m_data;
  115. unset($tmpData['NrArticle']);
  116. foreach ($tmpData as $key => $data) {
  117. $tmpData[$key] = "'".$data."'";
  118. }
  119. $queryStr = 'INSERT IGNORE INTO '.$this->m_dbTableName
  120. .'(NrArticle,'.implode(',', array_keys($this->m_columnNames)).')'
  121. .' VALUES ('.$p_destArticleNumber.','.implode(',', $tmpData).')';
  122. $g_ado_db->Execute($queryStr);
  123. } // fn copy
  124. /**
  125. * Return an array of ArticleTypeField objects.
  126. *
  127. * @param p_showAll boolean
  128. *
  129. * @return array
  130. */
  131. public function getUserDefinedColumns($p_showAll = false, $p_skipCache = false)
  132. {
  133. if (empty($this->m_articleTypeName)) {
  134. return array();
  135. }
  136. if (is_null($this->m_articleTypeObject)) {
  137. $this->m_articleTypeObject = new ArticleType($this->m_articleTypeName);
  138. }
  139. return $this->m_articleTypeObject->getUserDefinedColumns(null, $p_showAll, $p_skipCache);
  140. } // fn getUserDefinedColumns
  141. /**
  142. * Copy the row in the database.
  143. * @param int $p_destArticleNumber
  144. * @param int $p_destLanguageId
  145. * @return void
  146. */
  147. public function copyToExistingRecord($p_destArticleNumber, $p_destLanguageId = null)
  148. {
  149. global $g_ado_db;
  150. $tmpData = $this->m_data;
  151. unset($tmpData['NrArticle']);
  152. unset($tmpData['IdLanguage']);
  153. $setQuery = array();
  154. foreach ($tmpData as $key => $data) {
  155. $setQuery[] = $key."='".mysql_real_escape_string($data)."'";
  156. }
  157. $queryStr = 'UPDATE '.$this->m_dbTableName.' SET '.implode(',', $setQuery)
  158. ." WHERE NrArticle=$p_destArticleNumber ";
  159. if (!is_null($p_destLanguageId)) {
  160. $queryStr .= " AND IdLanguage=".$p_destLanguageId;
  161. } else {
  162. $queryStr .= " AND IdLanguage=".$this->m_data['IdLanguage'];
  163. }
  164. $g_ado_db->Execute($queryStr);
  165. } // fn copyToExistingRecord
  166. public static function TransformSubheads($match) {
  167. static $spanCounter = -1;
  168. // This matches '<span class="campsite_subhead">'
  169. if (preg_match("/<\s*span[^>]*class\s*=\s*[\"']campsite_subhead[\"'][^>]*>/i", $match[0])) {
  170. $spanCounter = 1;
  171. return "<!** Title>";
  172. }
  173. // This matches '<span'
  174. elseif (($spanCounter >= 0) && preg_match("/<\s*span/i", $match[0])) {
  175. $spanCounter += 1;
  176. }
  177. // This matches '</span>'
  178. elseif (($spanCounter >= 0) && preg_match("/<\s*\/\s*span\s*>/i", $match[0])) {
  179. $spanCounter -= 1;
  180. }
  181. if ($spanCounter == 0) {
  182. $spanCounter = -1;
  183. return "<!** EndTitle>";
  184. }
  185. return $match[0];
  186. } // fn TransformSubheads
  187. /**
  188. * This function is a callback for preg_replace_callback().
  189. * It will replace <a href="campsite_internal_link?...">...</a>
  190. * with <!** Link Internal ...> ... <!** EndLink>
  191. * @param array p_match
  192. * @return string
  193. */
  194. public static function TransformInternalLinks($p_match) {
  195. static $internalLinkCounter = 0;
  196. static $internalLinkStartTag = 0;
  197. // This matches anchor links
  198. $anchorStartRegex = "/<\s*a\s*(name\s*=\s*[\"']\w+[\"'])+[\s]*>/i";
  199. if (preg_match($anchorStartRegex, $p_match[0])) {
  200. // Leave the HTML tag as is
  201. return $p_match[0];
  202. }
  203. // This matches '<a href="campsite_internal_link?IdPublication=1&..." ...>'
  204. $internalLinkStartRegex = "/<\s*a\s*(((href\s*=\s*[\"'](\\/campsite\\/)?campsite_internal_link[?][\w&=;]*[\"'])|(\w+\s*=\s*['\"][_\w]*['\"]))[\s]*)*[\s\w\"']*>/i";
  205. // This matches '</a>'
  206. $internalLinkEndRegex = "/<\s*\/a\s*>/i";
  207. if (preg_match($internalLinkEndRegex, $p_match[0])) {
  208. // Check if we are closing an internal link
  209. if ($internalLinkCounter > 0) {
  210. $internalLinkCounter = 0;
  211. // Make sure the starting link was not blank (a blank
  212. // indicates it was a link to no where)
  213. if ($internalLinkStartTag != "") {
  214. // Replace the HTML tag with a template tag
  215. $retval = "<!** EndLink>";
  216. $internalLinkStartTag = "";
  217. return $retval;
  218. } else {
  219. // The starting link was blank, so we return blank for the
  220. // ending link.
  221. return "";
  222. }
  223. } else {
  224. // Leave the HTML tag as is (for external links).
  225. return '</a>';
  226. }
  227. } elseif (preg_match($internalLinkStartRegex, $p_match[0])) {
  228. // Get the URL
  229. preg_match("/href\s*=\s*[\"'](\\/campsite\\/)?(campsite_internal_link[?][\w&=;]*)[\"']/i", $p_match[0], $url);
  230. $url = isset($url[2]) ? $url[2] : '';
  231. $parsedUrl = parse_url($url);
  232. $parsedUrl = str_replace("&amp;", "&", $parsedUrl);
  233. $retval = "";
  234. // It's possible that there isnt a query string - in which case
  235. // its a link to no where, so we remove it ($retval is empty
  236. // string).
  237. if (isset($parsedUrl["query"])) {
  238. // Get the target, if there is one
  239. preg_match("/target\s*=\s*[\"']([_\w]*)[\"']/i", $p_match[0], $target);
  240. $target = isset($target[1]) ? $target[1] : null;
  241. // Replace the HTML tag with a template tag
  242. $retval = "<!** Link Internal ".$parsedUrl["query"];
  243. if (!is_null($target)) {
  244. $retval .= " TARGET ".$target;
  245. }
  246. $retval .= ">";
  247. }
  248. // Mark that we are now inside an internal link.
  249. $internalLinkCounter = 1;
  250. // Remember the starting link tag
  251. $internalLinkStartTag = $retval;
  252. return $retval;
  253. }
  254. } // fn TransformInternalLinks
  255. /**
  256. * This function is a callback for preg_replace_callback().
  257. * It will replace <img src="http://[hostname]/[image_dir]/cms-image-000000001.jpg" align="center" alt="alternate text" sub="caption text" id="5">
  258. * with <!** Image [image_template_id] align=CENTER alt="alternate text" sub="caption text">
  259. * @param array p_match
  260. * @return string
  261. */
  262. public function transformImageTags($p_match) {
  263. array_shift($p_match);
  264. $attrs = array();
  265. foreach ($p_match as $attr) {
  266. $attr = explode('=', $attr);
  267. if (isset($attr[0]) && !empty($attr[0])) {
  268. $attrName = trim(strtolower($attr[0]));
  269. $attrValue = isset($attr[1]) ? $attr[1] : '';
  270. // Strip out the quotes
  271. $attrValue = str_replace('"', '', $attrValue);
  272. $attrs[$attrName] = $attrValue;
  273. }
  274. }
  275. if (!isset($attrs['id'])) {
  276. return '';
  277. } else {
  278. if (strpos($attrs['id'], '_')) {
  279. list($templateId, $imageRatio) = explode('_', $attrs['id']);
  280. } else {
  281. $templateId = $attrs['id'];
  282. }
  283. $articleImage = new ArticleImage($this->m_data['NrArticle'], null, $templateId);
  284. if (!$articleImage->exists()) {
  285. return '';
  286. }
  287. }
  288. $alignTag = '';
  289. if (isset($attrs['align'])) {
  290. $alignTag = 'align="'.$attrs['align'].'"';
  291. }
  292. $altTag = '';
  293. if (isset($attrs['alt']) && strlen($attrs['alt']) > 0) {
  294. $altTag = 'alt="'.$attrs['alt'].'"';
  295. }
  296. $captionTag = '';
  297. if (isset($attrs['title']) && strlen($attrs['title']) > 0) {
  298. $captionTag = 'sub="'.$attrs['title'].'"';
  299. }
  300. if (isset($attrs['width']) && strlen($attrs['width']) > 0) {
  301. $widthTag = 'width="'.$attrs['width'].'"';
  302. }
  303. if (isset($attrs['height']) && strlen($attrs['height']) > 0) {
  304. $heightTag = 'height="'.$attrs['height'].'"';
  305. }
  306. $ratioTag = '';
  307. if (isset($imageRatio) && ($imageRatio > 0 && $imageRatio < 100)) {
  308. $ratioTag = 'ratio="'.$imageRatio.'"';
  309. }
  310. $imageTag = "<!** Image $templateId $alignTag $altTag $captionTag $widthTag $heightTag $ratioTag>";
  311. return $imageTag;
  312. } // fn TransformImageTags
  313. } // class ArticleData
  314. ?>