Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php namespace ProcessWire;

require_once(dirname(__FILE__) . '/FieldtypeLanguageInterface.php'); 

/**
 * Multi-language capable text field
 *
 * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
 * https://processwire.com
 *
 *
 */

class FieldtypeTextLanguage extends FieldtypeText implements FieldtypeLanguageInterface {

  public static function getModuleInfo() {
    return array(
      'title' => 'Text (Multi-language)',
      'version' => 100,
      'summary' => 'Field that stores a single line of text in multiple languages',
      'permanent' => false,
      'requires' => array('LanguageSupportFields'),
      );
  }

  /**
   * Sanitize value for storage
   *
   * @param Page $page
   * @param Field $field
   * @param LanguagesValueInterface|string $value
   * @return LanguagesPageFieldValue
   *
   */
  public function sanitizeValue(Page $page, Field $field, $value) {

    if(is_object($value) && $value instanceof LanguagesPageFieldValue) {
      // great, already what we wanted
      return $value;
    }

    // convert it to a LanguagesPageFieldValue
    $pageValue = $page->data($field->name); // raw unformatted value, with no load possible

    if(!$pageValue instanceof LanguagesPageFieldValue) {
      $pageValue = new LanguagesPageFieldValue($page, $field, $pageValue); // #98
    }

    if(is_array($value)) {
      $pageValue->importArray($value);
      return $pageValue;
    }

    $user = $this->wire()->user;
    $language = $user ? $user->language : null;
    $template = $page->template;

    if(!$language) return $pageValue;

    if($template && $template->noLang) {
      $languages = $this->wire()->languages;
      $pageValue->setLanguageValue($languages->getDefault()->id, (string) $value);
    } else {
      $pageValue->setLanguageValue($language->id, (string) $value);
    }

    return $pageValue;
  }


  /**
   * Return the database schema in specified format
   * 
   * @param Field $field
   * @return array
   *
   */
  public function getDatabaseSchema(Field $field) {
  
    $schema = parent::getDatabaseSchema($field);
    $languageSupport = $this->wire('modules')->get('LanguageSupport'); 
    $maxIndex = (int) $this->wire('database')->getMaxIndexLength();
  
    // note that we use otherLanguagePageIDs rather than wire('languages') because
    // it's possible that this method may be called before the languages are known 
    foreach($languageSupport->otherLanguagePageIDs as $languageID) {
      // $schema['data' . $languageID] = $schema['data'];
      $schema['data' . $languageID] = 'text';
      $schema['keys']["data_exact{$languageID}"] = "KEY `data_exact{$languageID}` (`data{$languageID}`($maxIndex))";
      $schema['keys']["data{$languageID}"] = "FULLTEXT KEY `data{$languageID}` (`data{$languageID}`)";
    }
  
    return $schema;
  }

  /**
   * Format value for output, basically typecasting to a string and sending to textformatters from FieldtypeText
   * 
   * @param Page $page
   * @param Field $field
   * @param LanguagesValueInterface|string $value
   * @return string
   *
   */
  public function formatValue(Page $page, Field $field, $value) {
    return parent::formatValue($page, $field, (string) $value); 
  }

  /**
   * Given a value, return an portable version of it as array
   *
   * @param Page $page
   * @param Field $field
   * @param string|int|float|array|object|null $value
   * @param array $options Optional settings to shape the exported value, if needed.
   * @return string|float|int|array
   *
   */
  public function ___exportValue(Page $page, Field $field, $value, array $options = array()) {
    if(isset($options['sleepValue'])) {
      // allow a sleepValue option, for use by other language Fieldtypes that delegate
      // their exportValue to this one, like FieldtypeTextareaLanguage
      $sleepValue = $options['sleepValue'];
    } else {
      $sleepValue = $this->sleepValue($page, $field, $value);
    }
    $exportValue = array();
    foreach($sleepValue as $k => $v) {
      if($k === 'data') {
        $exportValue['default'] = $v;
      } else if(strpos($k, 'data') === 0) {
        $languageID = substr($k, 4);
        $language = $this->wire('languages')->get((int) $languageID);
        $exportValue[$language->name] = $v;
      } else {
        $exportValue[$k] = $v;
      }
    }
    return $exportValue;
  }
  
  public function ___importValue(Page $page, Field $field, $value, array $options = array()) {
    if(is_null($value)) $value = '';
    if(is_string($value)) {
      $v = $value;
      $value = $field->type->exportValue($page, $field, $page->getUnformatted($field->name), $options);
      $value['default'] = $v; 
    }
    if(!is_array($value)) {
      throw new WireException("Array value expected for multi-language importValue");
    }
    /** @var Languages $languages */
    $languages = $this->wire('languages');
    /** @var LanguagesPageFieldValue $importValue */
    $importValue = $page->get($field->name); 
    foreach($value as $languageName => $languageValue) {
      $language = $languages->get($languageName); 
      if(!$language->id) continue; 
      $importValue->setLanguageValue($language->id, $languageValue); 
    }
    return $importValue;
  }

}