PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

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

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