PageRenderTime 58ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

/public_html/wire/modules/LanguageSupport/LanguagesPageFieldValue.php

https://bitbucket.org/thomas1151/mats
PHP | 248 lines | 113 code | 33 blank | 102 comment | 28 complexity | e530a68d9cdea5731a9e887fa789aa84 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php namespace ProcessWire;
  2. /**
  3. * Serves as a multi-language value placeholder for field values that contain a value in more than one language.
  4. *
  5. * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
  6. * https://processwire.com
  7. *
  8. */
  9. class LanguagesPageFieldValue extends Wire implements LanguagesValueInterface, \IteratorAggregate {
  10. /**
  11. * Inherit default language value when blank
  12. *
  13. */
  14. const langBlankInheritDefault = 0;
  15. /**
  16. * Don't inherit any value when blank
  17. *
  18. */
  19. const langBlankInheritNone = 1;
  20. /**
  21. * Values per language indexed by language ID
  22. *
  23. */
  24. protected $data = array();
  25. /**
  26. * Cached ID of default language page
  27. *
  28. */
  29. protected $defaultLanguagePageID = 0;
  30. /**
  31. * @var LanguageSupport|null
  32. *
  33. */
  34. protected $languageSupport = null;
  35. /**
  36. * Reference to Field that this value is for
  37. *
  38. */
  39. protected $field;
  40. /**
  41. * Reference to Page that this value is for
  42. *
  43. * @var Page
  44. *
  45. */
  46. protected $page;
  47. /**
  48. * Construct the multi language value
  49. *
  50. * @param Page $page
  51. * @param Field $field
  52. * @param array|string $values
  53. *
  54. */
  55. public function __construct(Page $page, Field $field, $values = null) { // #98
  56. $page->wire($this);
  57. $this->setPage($page);
  58. $this->setField($field);
  59. $this->languageSupport = $this->wire('modules')->get('LanguageSupport');
  60. $this->defaultLanguagePageID = $this->languageSupport->defaultLanguagePageID;
  61. if(!is_array($values)) {
  62. $values = array('data' => $values);
  63. }
  64. $this->importArray($values);
  65. }
  66. /**
  67. * Import array of language values
  68. *
  69. * Indexes may be:
  70. * - “data123” where 123 is language ID or “data” for default language
  71. * - "en” language name (may be any language name)
  72. * - “123” language ID
  73. *
  74. * One index style must be used, you may not combine multiple.
  75. *
  76. * #pw-internal
  77. *
  78. * @param array $values
  79. *
  80. */
  81. public function importArray(array $values) {
  82. reset($values);
  83. $testKey = key($values);
  84. if($testKey === null) return;
  85. if(strpos($testKey, 'data') !== 0) {
  86. // array does not use "data123" indexes, so work with language ID or language name indexes
  87. // and convert to "data123" indexes
  88. $_values = array();
  89. foreach($values as $key => $value) {
  90. if(ctype_digit("$key")) $key = (int) $key;
  91. $language = $this->wire('languages')->get($key);
  92. if($language && $language->id) {
  93. $dataKey = $language->isDefault() ? "data" : "data$language->id";
  94. $_values[$dataKey] = $value;
  95. }
  96. }
  97. if(count($_values)) $values = $_values;
  98. }
  99. if(array_key_exists('data', $values)) {
  100. if(is_null($values['data'])) $values['data'] = '';
  101. $this->data[$this->defaultLanguagePageID] = $values['data'];
  102. }
  103. foreach($this->languageSupport->otherLanguagePageIDs as $id) {
  104. $key = 'data' . $id;
  105. $value = empty($values[$key]) ? '' : $values[$key];
  106. $this->data[$id] = $value;
  107. }
  108. }
  109. /**
  110. * Sets the value for a given language
  111. *
  112. * @param int|Language|string $languageID Language object, id, or name
  113. * @param mixed $value
  114. * @return $this
  115. *
  116. */
  117. public function setLanguageValue($languageID, $value) {
  118. if(is_object($languageID) && $languageID instanceof Language) $languageID = $languageID->id;
  119. if(is_string($languageID) && !ctype_digit("$languageID")) $languageID = $this->wire('languages')->get($languageID)->id;
  120. $existingValue = isset($this->data[$languageID]) ? $this->data[$languageID] : '';
  121. if($value instanceof LanguagesPageFieldValue) {
  122. // to avoid potential recursion
  123. $value = $value->getLanguageValue($languageID);
  124. }
  125. if($value !== $existingValue) {
  126. $this->trackChange('data', $existingValue, $value);
  127. $this->trackChange('data' . $languageID, $existingValue, $value);
  128. }
  129. $this->data[(int)$languageID] = $value;
  130. return $this;
  131. }
  132. /**
  133. * Given an Inputfield with multi language values, this grabs and populates the language values from it
  134. *
  135. * @param Inputfield $inputfield
  136. *
  137. */
  138. public function setFromInputfield(Inputfield $inputfield) {
  139. foreach($this->wire('languages') as $language) {
  140. if($language->isDefault) {
  141. $key = 'value';
  142. } else {
  143. $key = 'value' . $language->id;
  144. }
  145. $this->setLanguageValue($language->id, $inputfield->$key);
  146. }
  147. }
  148. /**
  149. * Given a language, returns the value in that language
  150. *
  151. * @param Language|int|string Language object, id, or name
  152. * @return int
  153. *
  154. */
  155. public function getLanguageValue($languageID) {
  156. if(is_object($languageID) && $languageID instanceof Language) $languageID = $languageID->id;
  157. if(is_string($languageID) && !ctype_digit("$languageID")) $languageID = $this->wire('languages')->get($languageID)->id;
  158. $languageID = (int) $languageID;
  159. return isset($this->data[$languageID]) ? $this->data[$languageID] : '';
  160. }
  161. /**
  162. * Returns the value in the default language
  163. *
  164. */
  165. public function getDefaultValue() {
  166. return $this->data[$this->defaultLanguagePageID];
  167. }
  168. /**
  169. * The string value is the value in the current user's language
  170. *
  171. */
  172. public function __toString() {
  173. return $this->wire('hooks')->isHooked('LanguagesPageFieldValue::getStringValue()') ? $this->__call('getStringValue', array()) : $this->___getStringValue();
  174. }
  175. protected function ___getStringValue() {
  176. $language = $this->wire('user')->language;
  177. $defaultValue = (string) $this->data[$this->defaultLanguagePageID];
  178. if(!$language || !$language->id || $language->isDefault()) return $defaultValue;
  179. $languageValue = (string) (empty($this->data[$language->id]) ? '' : $this->data[$language->id]);
  180. if(!strlen($languageValue)) {
  181. // value is blank
  182. if($this->field) {
  183. if($this->field->langBlankInherit == self::langBlankInheritDefault) {
  184. // inherit value from default language
  185. $languageValue = $defaultValue;
  186. }
  187. }
  188. }
  189. return $languageValue;
  190. }
  191. public function setField(Field $field) {
  192. $this->field = $field;
  193. }
  194. public function setPage(Page $page) {
  195. $this->page = $page;
  196. }
  197. public function __debugInfo() {
  198. $info = parent::__debugInfo();
  199. foreach($this->wire('languages') as $language) {
  200. $info[$language->name] = isset($this->data[$language->id]) ? $this->data[$language->id] : '';
  201. }
  202. return $info;
  203. }
  204. /**
  205. * Allows iteration of the languages values
  206. *
  207. * Fulfills \IteratorAggregate interface.
  208. *
  209. * @return ArrayObject
  210. *
  211. */
  212. public function getIterator() {
  213. return new \ArrayObject($this->data);
  214. }
  215. }