1<?php 2/** 3 * Joomla! Content Management System 4 * 5 * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. 6 * @license GNU General Public License version 2 or later; see LICENSE.txt 7 */ 8 9namespace Joomla\CMS\Form\Field; 10 11defined('JPATH_PLATFORM') or die; 12 13use Joomla\CMS\Factory; 14use Joomla\CMS\Form\FormHelper; 15 16FormHelper::loadFieldClass('groupedlist'); 17 18/** 19 * Chrome Styles field. 20 * 21 * @since 3.0 22 */ 23class ChromestyleField extends \JFormFieldGroupedList 24{ 25 /** 26 * The form field type. 27 * 28 * @var string 29 * @since 3.0 30 */ 31 public $type = 'ChromeStyle'; 32 33 /** 34 * The client ID. 35 * 36 * @var integer 37 * @since 3.2 38 */ 39 protected $clientId; 40 41 /** 42 * Method to get certain otherwise inaccessible properties from the form field object. 43 * 44 * @param string $name The property name for which to get the value. 45 * 46 * @return mixed The property value or null. 47 * 48 * @since 3.2 49 */ 50 public function __get($name) 51 { 52 switch ($name) 53 { 54 case 'clientId': 55 return $this->clientId; 56 } 57 58 return parent::__get($name); 59 } 60 61 /** 62 * Method to set certain otherwise inaccessible properties of the form field object. 63 * 64 * @param string $name The property name for which to get the value. 65 * @param mixed $value The value of the property. 66 * 67 * @return void 68 * 69 * @since 3.2 70 */ 71 public function __set($name, $value) 72 { 73 switch ($name) 74 { 75 case 'clientId': 76 $this->clientId = (string) $value; 77 break; 78 79 default: 80 parent::__set($name, $value); 81 } 82 } 83 84 /** 85 * Method to attach a JForm object to the field. 86 * 87 * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. 88 * @param mixed $value The form field value to validate. 89 * @param string $group The field name group control value. This acts as an array container for the field. 90 * For example if the field has name="foo" and the group value is set to "bar" then the 91 * full field name would end up being "bar[foo]". 92 * 93 * @return boolean True on success. 94 * 95 * @see JFormField::setup() 96 * @since 3.2 97 */ 98 public function setup(\SimpleXMLElement $element, $value, $group = null) 99 { 100 $result = parent::setup($element, $value, $group); 101 102 if ($result === true) 103 { 104 // Get the client id. 105 $clientId = $this->element['client_id']; 106 107 if (!isset($clientId)) 108 { 109 $clientName = $this->element['client']; 110 111 if (isset($clientName)) 112 { 113 $client = \JApplicationHelper::getClientInfo($clientName, true); 114 $clientId = $client->id; 115 } 116 } 117 118 if (!isset($clientId) && $this->form instanceof \JForm) 119 { 120 $clientId = $this->form->getValue('client_id'); 121 } 122 123 $this->clientId = (int) $clientId; 124 } 125 126 return $result; 127 } 128 129 130 /** 131 * Method to get the list of template chrome style options 132 * grouped by template. 133 * 134 * @return array The field option objects as a nested array in groups. 135 * 136 * @since 3.0 137 */ 138 protected function getGroups() 139 { 140 $groups = array(); 141 142 // Add Module Style Field 143 $tmp = '---' . \JText::_('JLIB_FORM_VALUE_FROM_TEMPLATE') . '---'; 144 $groups[$tmp][] = \JHtml::_('select.option', '0', \JText::_('JLIB_FORM_VALUE_INHERITED')); 145 146 $templateStyles = $this->getTemplateModuleStyles(); 147 148 // Create one new option object for each available style, grouped by templates 149 foreach ($templateStyles as $template => $styles) 150 { 151 $template = ucfirst($template); 152 $groups[$template] = array(); 153 154 foreach ($styles as $style) 155 { 156 $tmp = \JHtml::_('select.option', $template . '-' . $style, $style); 157 $groups[$template][] = $tmp; 158 } 159 } 160 161 reset($groups); 162 163 return $groups; 164 } 165 166 /** 167 * Method to get the templates module styles. 168 * 169 * @return array The array of styles, grouped by templates. 170 * 171 * @since 3.0 172 */ 173 protected function getTemplateModuleStyles() 174 { 175 $moduleStyles = array(); 176 177 $templates = array($this->getSystemTemplate()); 178 $templates = array_merge($templates, $this->getTemplates()); 179 $path = JPATH_ADMINISTRATOR; 180 181 if ($this->clientId === 0) 182 { 183 $path = JPATH_SITE; 184 } 185 186 foreach ($templates as $template) 187 { 188 $modulesFilePath = $path . '/templates/' . $template->element . '/html/modules.php'; 189 190 // Is there modules.php for that template? 191 if (file_exists($modulesFilePath)) 192 { 193 $modulesFileData = file_get_contents($modulesFilePath); 194 195 preg_match_all('/function[\s\t]*modChrome\_([a-z0-9\-\_]*)[\s\t]*\(/i', $modulesFileData, $styles); 196 197 if (!array_key_exists($template->element, $moduleStyles)) 198 { 199 $moduleStyles[$template->element] = array(); 200 } 201 202 $moduleStyles[$template->element] = $styles[1]; 203 } 204 } 205 206 return $moduleStyles; 207 } 208 209 /** 210 * Method to get the system template as an object. 211 * 212 * @return \stdClass The object of system template. 213 * 214 * @since 3.0 215 */ 216 protected function getSystemTemplate() 217 { 218 $template = new \stdClass; 219 $template->element = 'system'; 220 $template->name = 'system'; 221 222 return $template; 223 } 224 225 /** 226 * Return a list of templates 227 * 228 * @return array List of templates 229 * 230 * @since 3.2.1 231 */ 232 protected function getTemplates() 233 { 234 $db = Factory::getDbo(); 235 236 // Get the database object and a new query object. 237 $query = $db->getQuery(true); 238 239 // Build the query. 240 $query->select('element, name') 241 ->from('#__extensions') 242 ->where('client_id = ' . $this->clientId) 243 ->where('type = ' . $db->quote('template')) 244 ->where('enabled = 1'); 245 246 // Set the query and load the templates. 247 $db->setQuery($query); 248 249 return $db->loadObjectList('element'); 250 } 251} 252