PageRenderTime 206ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/administrator/components/com_contenthistory/helpers/contenthistory.php

https://bitbucket.org/ke2083/transfans.co.uk-website
PHP | 384 lines | 212 code | 47 blank | 125 comment | 35 complexity | 3529e10754d9e8f9c00d3d604ffeec81 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Administrator
  4. * @subpackage com_contenthistory
  5. *
  6. * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. defined('_JEXEC') or die;
  10. /**
  11. * Categories helper.
  12. *
  13. * @since 3.2
  14. */
  15. class ContenthistoryHelper
  16. {
  17. /**
  18. * Method to put all field names, including nested ones, in a single array for easy lookup.
  19. *
  20. * @param stdClass $object Standard class object that may contain one level of nested objects.
  21. *
  22. * @return array Associative array of all field names, including ones in a nested object.
  23. *
  24. * @since 3.2
  25. */
  26. public static function createObjectArray($object)
  27. {
  28. $result = array();
  29. if ($object === null)
  30. {
  31. return $result;
  32. }
  33. foreach ($object as $name => $value)
  34. {
  35. $result[$name] = $value;
  36. if (is_object($value))
  37. {
  38. foreach ($value as $subName => $subValue)
  39. {
  40. $result[$subName] = $subValue;
  41. }
  42. }
  43. }
  44. return $result;
  45. }
  46. /**
  47. * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column.
  48. *
  49. * @param stdClass $jsonString Standard class object that may contain one or more JSON-encoded fields.
  50. *
  51. * @return stdClass Object with any JSON-encoded fields unpacked.
  52. *
  53. * @since 3.2
  54. */
  55. public static function decodeFields($jsonString)
  56. {
  57. $object = json_decode($jsonString);
  58. if (is_object($object))
  59. {
  60. foreach ($object as $name => $value)
  61. {
  62. if ($subObject = json_decode($value))
  63. {
  64. $object->$name = $subObject;
  65. }
  66. }
  67. }
  68. return $object;
  69. }
  70. /**
  71. * Method to get field labels for the fields in the JSON-encoded object.
  72. * First we see if we can find translatable labels for the fields in the object.
  73. * We translate any we can find and return an array in the format object->name => label.
  74. *
  75. * @param stdClass $object Standard class object in the format name->value.
  76. * @param JTableContenttype $typesTable Table object with content history options.
  77. *
  78. * @return stdClass Contains two associative arrays.
  79. * $formValues->labels in the format name => label (for example, 'id' => 'Article ID').
  80. * $formValues->values in the format name => value (for example, 'state' => 'Published'.
  81. * This translates the text from the selected option in the form.
  82. *
  83. * @since 3.2
  84. */
  85. public static function getFormValues($object, JTableContenttype $typesTable)
  86. {
  87. $labels = array();
  88. $values = array();
  89. $expandedObjectArray = static::createObjectArray($object);
  90. static::loadLanguageFiles($typesTable->type_alias);
  91. if ($formFile = static::getFormFile($typesTable))
  92. {
  93. if ($xml = simplexml_load_file($formFile))
  94. {
  95. // Now we need to get all of the labels from the form
  96. $fieldArray = $xml->xpath('//field');
  97. $fieldArray = array_merge($fieldArray, $xml->xpath('//fields'));
  98. foreach ($fieldArray as $field)
  99. {
  100. if ($label = (string) $field->attributes()->label)
  101. {
  102. $labels[(string) $field->attributes()->name] = JText::_($label);
  103. }
  104. }
  105. // Get values for any list type fields
  106. $listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]');
  107. foreach ($listFieldArray as $field)
  108. {
  109. $name = (string) $field->attributes()->name;
  110. if (isset($expandedObjectArray[$name]))
  111. {
  112. $optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]');
  113. $valueText = null;
  114. if (is_array($optionFieldArray) && count($optionFieldArray))
  115. {
  116. $valueText = trim((string) $optionFieldArray[0]);
  117. }
  118. $values[(string) $field->attributes()->name] = JText::_($valueText);
  119. }
  120. }
  121. }
  122. }
  123. $result = new stdClass;
  124. $result->labels = $labels;
  125. $result->values = $values;
  126. return $result;
  127. }
  128. /**
  129. * Method to get the XML form file for this component. Used to get translated field names for history preview.
  130. *
  131. * @param JTableContenttype $typesTable Table object with content history options.
  132. *
  133. * @return mixed JModel object if successful, false if no model found.
  134. *
  135. * @since 3.2
  136. */
  137. public static function getFormFile(JTableContenttype $typesTable)
  138. {
  139. $result = false;
  140. jimport('joomla.filesystem.file');
  141. jimport('joomla.filesystem.folder');
  142. // First, see if we have a file name in the $typesTable
  143. $options = json_decode($typesTable->content_history_options);
  144. if (is_object($options) && isset($options->formFile) && JFile::exists(JPATH_ROOT . '/' . $options->formFile))
  145. {
  146. $result = JPATH_ROOT . '/' . $options->formFile;
  147. }
  148. else
  149. {
  150. $aliasArray = explode('.', $typesTable->type_alias);
  151. if (count($aliasArray) == 2)
  152. {
  153. $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0];
  154. $path = JFolder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/');
  155. $file = JFile::makeSafe($aliasArray[1] . '.xml');
  156. $result = JFile::exists($path . $file) ? $path . $file : false;
  157. }
  158. }
  159. return $result;
  160. }
  161. /**
  162. * Method to query the database using values from lookup objects.
  163. *
  164. * @param stdClass $lookup The std object with the values needed to do the query.
  165. * @param mixed $value The value used to find the matching title or name. Typically the id.
  166. *
  167. * @return mixed Value from database (for example, name or title) on success, false on failure.
  168. *
  169. * @since 3.2
  170. */
  171. public static function getLookupValue($lookup, $value)
  172. {
  173. $result = false;
  174. if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn)&& isset($lookup->displayColumn))
  175. {
  176. $db = JFactory::getDbo();
  177. $query = $db->getQuery(true);
  178. $query->select($db->quoteName($lookup->displayColumn))
  179. ->from($db->quoteName($lookup->targetTable))
  180. ->where($db->quoteName($lookup->targetColumn) . ' = ' . $db->quote($value));
  181. $db->setQuery($query);
  182. try
  183. {
  184. $result = $db->loadResult();
  185. }
  186. catch (Exception $e)
  187. {
  188. // Ignore any errors and just return false
  189. return false;
  190. }
  191. }
  192. return $result;
  193. }
  194. /**
  195. * Method to remove fields from the object based on values entered in the #__content_types table.
  196. *
  197. * @param stdClass $object Object to be passed to view layout file.
  198. * @param JTableContenttype $typeTable Table object with content history options.
  199. *
  200. * @return stdClass object with hidden fields removed.
  201. *
  202. * @since 3.2
  203. */
  204. public static function hideFields($object, JTableContenttype $typeTable)
  205. {
  206. if ($options = json_decode($typeTable->content_history_options))
  207. {
  208. if (isset($options->hideFields) && is_array($options->hideFields))
  209. {
  210. foreach ($options->hideFields as $field)
  211. {
  212. unset($object->$field);
  213. }
  214. }
  215. }
  216. return $object;
  217. }
  218. /**
  219. * Method to load the language files for the component whose history is being viewed.
  220. *
  221. * @param string $typeAlias The type alias, for example 'com_content.article'.
  222. *
  223. * @return void
  224. *
  225. * @since 3.2
  226. */
  227. public static function loadLanguageFiles($typeAlias)
  228. {
  229. $aliasArray = explode('.', $typeAlias);
  230. if (is_array($aliasArray) && count($aliasArray) == 2)
  231. {
  232. $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0];
  233. $lang = JFactory::getLanguage();
  234. /**
  235. * Loading language file from the administrator/language directory then
  236. * loading language file from the administrator/components/extension/language directory
  237. */
  238. $lang->load($component, JPATH_ADMINISTRATOR, null, false, true)
  239. || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true);
  240. // Force loading of backend global language file
  241. $lang->load('joomla', JPath::clean(JPATH_ADMINISTRATOR), null, false, true);
  242. }
  243. }
  244. /**
  245. * Method to create object to pass to the layout. Format is as follows:
  246. * field is std object with name, value.
  247. *
  248. * Value can be a std object with name, value pairs.
  249. *
  250. * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep.
  251. * @param stdClass $formValues Standard class of label and value in an associative array.
  252. *
  253. * @return stdClass Object with translated labels where available
  254. *
  255. * @since 3.2
  256. */
  257. public static function mergeLabels($object, $formValues)
  258. {
  259. $result = new stdClass;
  260. if ($object === null)
  261. {
  262. return $result;
  263. }
  264. $labelsArray = $formValues->labels;
  265. $valuesArray = $formValues->values;
  266. foreach ($object as $name => $value)
  267. {
  268. $result->$name = new stdClass;
  269. $result->$name->name = $name;
  270. $result->$name->value = isset($valuesArray[$name]) ? $valuesArray[$name] : $value;
  271. $result->$name->label = isset($labelsArray[$name]) ? $labelsArray[$name] : $name;
  272. if (is_object($value))
  273. {
  274. $subObject = new stdClass;
  275. foreach ($value as $subName => $subValue)
  276. {
  277. $subObject->$subName = new stdClass;
  278. $subObject->$subName->name = $subName;
  279. $subObject->$subName->value = isset($valuesArray[$subName]) ? $valuesArray[$subName] : $subValue;
  280. $subObject->$subName->label = isset($labelsArray[$subName]) ? $labelsArray[$subName] : $subName;
  281. $result->$name->value = $subObject;
  282. }
  283. }
  284. }
  285. return $result;
  286. }
  287. /**
  288. * Method to prepare the object for the preview and compare views.
  289. *
  290. * @param JTableContenthistory $table Table object loaded with data.
  291. *
  292. * @return stdClass Object ready for the views.
  293. *
  294. * @since 3.2
  295. */
  296. public static function prepareData(JTableContenthistory $table)
  297. {
  298. $object = static::decodeFields($table->version_data);
  299. $typesTable = JTable::getInstance('Contenttype');
  300. $typesTable->load(array('type_id' => $table->ucm_type_id));
  301. $formValues = static::getFormValues($object, $typesTable);
  302. $object = static::mergeLabels($object, $formValues);
  303. $object = static::hideFields($object, $typesTable);
  304. $object = static::processLookupFields($object, $typesTable);
  305. return $object;
  306. }
  307. /**
  308. * Method to process any lookup values found in the content_history_options column for this table.
  309. * This allows category title and user name to be displayed instead of the id column.
  310. *
  311. * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep.
  312. * @param JTableContenttype $typesTable Table object loaded with data.
  313. *
  314. * @return stdClass Object with lookup values inserted.
  315. *
  316. * @since 3.2
  317. */
  318. public static function processLookupFields($object, JTableContenttype $typesTable)
  319. {
  320. if ($options = json_decode($typesTable->content_history_options))
  321. {
  322. if (isset($options->displayLookup) && is_array($options->displayLookup))
  323. {
  324. foreach ($options->displayLookup as $lookup)
  325. {
  326. $sourceColumn = isset($lookup->sourceColumn) ? $lookup->sourceColumn : false;
  327. $sourceValue = isset($object->$sourceColumn->value) ? $object->$sourceColumn->value : false;
  328. if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue)))
  329. {
  330. $object->$sourceColumn->value = $lookupValue;
  331. }
  332. }
  333. }
  334. }
  335. return $object;
  336. }
  337. }