diff --git a/wire/core/Pagefile.php b/wire/core/Pagefile.php index 368971aa..c33d87f3 100644 --- a/wire/core/Pagefile.php +++ b/wire/core/Pagefile.php @@ -198,13 +198,16 @@ class Pagefile extends WireData { /** * Set a description, optionally parsing JSON language-specific descriptions to separate properties * - * @param string $value + * @param string|array $value * @param Page|Language Langage to set it for. Omit to determine automatically. * @return $this * */ protected function setDescription($value, Page $language = null) { + /** @var Languages $languages */ + $languages = $this->wire('languages'); + /** @var Language|null $language */ $field = $this->field; @@ -216,27 +219,43 @@ class Pagefile extends WireData { $name .= $language->id; } parent::set($name, $value); + if($name != 'description' && $this->isChanged($name)) $this->trackChange('description'); return $this; } - // check if it contains JSON? - $first = substr($value, 0, 1); - $last = substr($value, -1); - if(($first == '{' && $last == '}') || ($first == '[' && $last == ']')) { - $values = json_decode($value, true); + if(is_array($value)) { + $values = $value; } else { - $values = array(); + // check if it contains JSON? + $first = substr($value, 0, 1); + $last = substr($value, -1); + if(($first == '{' && $last == '}') || ($first == '[' && $last == ']')) { + $values = json_decode($value, true); + } else { + $values = array(); + } } + + $numChanges = 0; if($values && count($values)) { $n = 0; foreach($values as $id => $v) { // first item is always default language. this ensures description will still // work even if language support is later uninstalled. - if($noLang && $n > 0) continue; - $name = $n > 0 ? "description$id" : "description"; - parent::set($name, $v); + if($noLang && $n > 0) break; $n++; + if(ctype_digit("$id")) { + $id = (int) $id; + if(!$id) $id = ''; + $name = $n > 0 ? "description$id" : "description"; + } else if($languages) { + $language = $languages->get($id); // i.e. "default" or "es" + if(!$language->id) continue; + $name = $language->isDefault() ? "description" : "description$language->id"; + } + parent::set($name, $v); + if($this->isChanged($name)) $numChanges++; } } else { // no JSON values so assume regular language description @@ -244,11 +263,15 @@ class Pagefile extends WireData { $language = $languages ? $this->wire('user')->language : null; if($languages && $language && !$noLang && !$language->isDefault()) { - parent::set("description$language", $value); + $name = "description$language->id"; } else { - parent::set("description", $value); + $name = "description"; } + parent::set($name, $value); + if($this->isChanged($name)) $numChanges++; } + + if($numChanges && !$this->isChanged('description')) $this->trackChange('description'); return $this; } @@ -277,17 +300,31 @@ class Pagefile extends WireData { * #pw-group-common * #pw-group-manipulation * - * @param null|bool|Language + * @param null|bool|Language|array * - To GET in current user language: Omit arguments or specify null. * - To GET in another language: Specify a Language name, id or object. * - To GET in all languages as a JSON string: Specify boolean true (if LanguageSupport not installed, regular string returned). + * - To GET in all languages as an array indexed by language name: Specify boolean true for both arguments. * - To SET for a language: Specify a language name, id or object, plus the $value as the 2nd argument. * - To SET in all languages as a JSON string: Specify boolean true, plus the JSON string $value as the 2nd argument (internal use only). + * - To SET in all languages as an array: Specify the array here, indexed by language ID or name, and omit 2nd argument. * @param null|string $value Specify only when you are setting (single language) rather than getting a value. * @return string * */ public function description($language = null, $value = null) { + + if($language === true && $value === true) { + // return all in array indexed by language name + /** @var Languages $languages */ + $languages = $this->wire('languages'); + if(!$languages) return array('default' => parent::get('description')); + $value = array(); + foreach($languages as $language) { + $value[$language->name] = (string) parent::get("description" . ($language->isDefault() ? '' : $language->id)); + } + return $value; + } if(!is_null($value)) { // set description mode @@ -300,6 +337,13 @@ class Pagefile extends WireData { } return $value; } + + if(is_array($language)) { + // set all from array, then return description in current language + $this->setDescription($language); + $language = null; + $value = null; + } if((is_string($language) || is_int($language)) && $this->wire('languages')) { // convert named or ID'd languages to Language object diff --git a/wire/modules/Fieldtype/FieldtypeFile.module b/wire/modules/Fieldtype/FieldtypeFile.module index c3b88195..04cb305e 100644 --- a/wire/modules/Fieldtype/FieldtypeFile.module +++ b/wire/modules/Fieldtype/FieldtypeFile.module @@ -252,13 +252,21 @@ class FieldtypeFile extends FieldtypeMulti { } public function ___exportValue(Page $page, Field $field, $value, array $options = array()) { + $pagefiles = $value; $value = $this->sleepValue($page, $field, $value); $exportValue = array(); + $defaults = array( + 'noJSON' => false, // no JSON for exported file descriptions or other properties (use array instead) + ); + if(!isset($options['FieldtypeFile'])) $options['FieldtypeFile'] = array(); + $options['FieldtypeFile'] = array_merge($defaults, $options['FieldtypeFile']); + foreach($value as $k => $v) { /** @var Pagefile $pagefile */ $pagefile = $pagefiles->get($v['data']); $a = array('url' => $pagefile->httpUrl()); + if(!empty($options['system'])) { unset($v['created'], $v['modified']); $exportKey = $v['data']; @@ -267,12 +275,69 @@ class FieldtypeFile extends FieldtypeMulti { $a['filesize'] = $pagefile->filesize(); $exportKey = $k; } + unset($v['data']); + + if($options['FieldtypeFile']['noJSON']) { + // export version 2 for exported description uses array value for multi-language, rather than JSON string + if(!isset($v['description'])) $v['description'] = ''; + $v['description'] = $this->exportDescription($v['description'], $options); + } + $exportValue[$exportKey] = array_merge($a, $v); } + return $exportValue; } + /** + * Export description value to array (multi-language, indexed by lang name) or string (non-multi-language) + * + * @param string|array $value + * @return array|string + * + */ + protected function exportDescription($value) { + + /** @var Languages $languages */ + $languages = $this->wire('languages'); + + if(is_string($value)) { + if(strpos($value, '[') !== 0 && strpos($value, '{') !== 0) return $value; + $a = json_decode($value, true); + if(!is_array($a)) return $value; + } else if(is_array($value)) { + $a = $value; + } else { + $a = array(); + } + + if(!$languages) { + $value = count($a) ? (string) reset($a) : ''; // return first/default + return $value; + } + + $description = array(); + + // ensure value present for every language, even if blank + foreach($languages as $language) { + $description[$language->name] = ''; + } + + foreach($a as $langKey => $langVal) { + if(ctype_digit("$langKey")) $langKey = (int) $langKey; + if(empty($langKey)) { + $langKey = 'default'; + } else { + $langKey = $languages->get($langKey)->name; + if(empty($langKey)) continue; + } + $description[$langKey] = $langVal; + } + + return $description; + } + public function getBlankValue(Page $page, Field $field) { $pagefiles = $this->wire(new Pagefiles($page)); $pagefiles->setField($field); diff --git a/wire/modules/Fieldtype/FieldtypeImage.module b/wire/modules/Fieldtype/FieldtypeImage.module index 840cc81d..418561d6 100644 --- a/wire/modules/Fieldtype/FieldtypeImage.module +++ b/wire/modules/Fieldtype/FieldtypeImage.module @@ -77,6 +77,27 @@ class FieldtypeImage extends FieldtypeFile { $value[$k]['height'] = $img->height(); } } + + if(!empty($options['FieldtypeImage'])) { + $o = $options['FieldtypeImage']; + if(!empty($o['variations'])) { + // include URLs to image variations + foreach($value as $k => $v) { + if(empty($options['system'])) { + $img = $pagefiles->get($v['name']); + } else { + $img = $pagefiles->get($k); + } + $variations = array(); + foreach($img->getVariations() as $variation) { + $variations[$variation->name] = $variation->httpUrl(); + } + $value[$k]['variations'] = $variations; + + } + } + } + return $value; }