Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php

/**
* SettingsFactory
* Create unlimited settings pages from JSON and PHP
*
* @author Macrura
*
* ProcessWire 3.x
* Copyright (C) 2011 by Ryan Cramer
* Licensed under GNU/GPL v2, see LICENSE.TXT
*
* http://www.processwire.com
* http://www.ryancramer.com
*
*/
class SettingsFactory extends WireData implements Module, ConfigurableModule  {

  public static function getModuleInfo() {
    return array(
      'title' => __('Settings Factory', __FILE__),
      'summary' => __('Create Unlimited Settings Pages!', __FILE__),
      'version' => '1.0.6',
      'author'    => 'Macrura',
      'permanent' => false,
      'autoload' => true,
      'icon' => 'check-square-o',
      'installs' => 'ProcessSettingsFactory'
    );
  }

  protected static $configDefaults = array(
    'instructions' => '',
  );

  /**
  * Set our configuration defaults
  *
  */
  public function __construct() {
    $configDefaults = self::$configDefaults;
    foreach($configDefaults as $key => $value) {
      $this->set($key, $value);
    }
  }


  public function init() {
    $this->buildFactory();
  }

  public function ready() {
    //$this->buildFactory();
  }


  public function buildFactory() {

    /**
    * Look for all settings pages, read the name of the page, and and inputfield names into a this module's properties.
    * thanks @Zeka for fixing this pages find
    */
    $module_id = wire('modules')->getModuleInfo('ProcessSettingsFactory')['id'];
    $settingsPages = $this->wire('pages')->find("template=admin, process=$module_id");

    foreach($settingsPages as $sp) {
      if($sp->sp_filepath) {
        $key = $sp->name;
        $settingsArray = array();
        $path = wire('config')->paths->templates .  $sp->sp_filepath;
        if(file_exists($path)) {
          $pathParts = pathinfo($path);

          if($pathParts['extension'] == 'json') {
            $json = file_get_contents($path);
            $fArray = json_decode($json, true);
            if($fArray === null) {
              $this->error('Your json file must return valid JSON array of inputfields.');
              continue;
            }
          }

          if($pathParts['extension'] == 'php') {
            $fArray = wireRenderFile($path);
            if($fArray === null) {
              $this->error('Your php file must return valid array of inputfields.');
              continue;
            }
          }

          // support for WireTabs (or nested wrappers are returned by file)
          $fArray = $this->extractInputfields($fArray);
          foreach($fArray as $field) {
            if(!$field['name']) continue;
            $value = isset($field['value']) ? $field['value'] : '';
            $settingsArray[$field['name']] = $value;
          }
          $this->set($key, $settingsArray);
        } // end if file exists
      } // end if there is a filepath specified
    } // end foreach pages


  }


  /**
  * Extract the inputfields from nested tabs/fieldsets
  */
  public function extractInputfields($inputfields) {
    $inputfieldsArray = new InputfieldWrapper();
    foreach($inputfields as $field) {
      if(is_array($field)) $inputfieldsArray->importArray($field);
      elseif($field instanceof InputfieldWrapper) $inputfieldsArray->import($field->getAll());
    }
    return $inputfieldsArray->getAll();
  }



  /**
  * Get the settings for frontend api.
  * default to WireArray for returned object
  */
  public function getSettings($key, $wireData = true) {

    $languages = ($this->wire('languages')) ? $this->wire('languages') : '';
    $nonDefaultLanguages = ($languages) ? $languages->findNonDefault() : '';

    $user = $this->wire('user');
    $settings = $this->modules->getConfig('SettingsFactory'); // or $this?
    if(empty($settings[$key])) return;
    $dataArray = $settings[$key];
    $settingsFields = $this[$key];

    $newDataArray = array();

    foreach ($settingsFields as $key => $value) {
      if ($nonDefaultLanguages && $user->language !== $languages->getDefault()) {
        $key_lang = $key . "__" . $user->language->id;
        if (array_key_exists($key_lang, $dataArray)) {
          $newDataArray[$key] = $dataArray[$key_lang] ? $dataArray[$key_lang] : $dataArray[$key];
        } else {
          $newDataArray[$key] = $dataArray[$key];
        }
      //} else {
      } else if(isset($dataArray[$key])) { // 6/5/20 @martijn
        $newDataArray[$key] = $dataArray[$key];
      }
    }

    if(!$wireData) return $newDataArray;
    // convert to object
    $key = new WireData();
    $key->setArray($newDataArray);
    return $key;
  }

  /**
  * Get the settings in plain array for frontend api.
  */
  public function getSettingsArray($key) {
    return $this->getSettings($key, false);
  }


  /**
  * Called only when your module is installed
  *
  * This version creates a new page with this Process module assigned.
  *
  */
  public function ___install() {
    // Check for existence of the field below, throw a message if it already exists
    if($this->fields->get('sp_filepath') == NULL) {
      // If it doesn't exist then and create it
      $field = new Field();
      $field->type = $this->modules->get("FieldtypeText");
      $field->name = 'sp_filepath';
      $field->label = __('Inputfields Definition File Path.');
      $field->description = __('Path to the file that defines the inputfields - json or php. Relative to templates folder.');
      $field->notes = __('See the examples included in the modules to get started.');
      //$field->placeholder = __('settings/site-settings.php');
      $field->showIf = 'process=ProcessSettingsFactory';
      $field->save();
    }

    // add to admin template, set visibility to only for the process
    $adminTemplate = $this->templates->get('admin');
    $adminTemplate->fields->add($field);
    $adminTemplate->fields->save();
    $this->message(__("Added field 'sp_filepath' to admin template."));
  }

  /**
  * Called only when your module is uninstalled
  * This should return the site to the same state it was in before the module was installed.
  *
  */
  public function ___uninstall() {

    // 1) Remove the path field from the template
    $adminTemplate = $this->templates->get('admin');
    if($adminTemplate->fields->get('sp_filepath')) {
      $adminTemplate->fields->remove($adminTemplate->fields->get('sp_filepath'));
      $adminTemplate->fields->save();
    }

    // 2) Remove the field sp_filepath
    if($this->fields->get('sp_filepath')) {
      $field = $this->fields->get('sp_filepath');
      $this->fields->delete($field);
    }

  }


  public static function getModuleConfigInputfields(array $data) {

    foreach(self::$configDefaults as $key => $value) {
      if(!isset($data[$key])||$data[$key]=="") $data[$key] = $value;
    }

    $inputfields = new InputfieldWrapper();

    /* INSTRUCTIONS
    ------------------------------------------------------------------------ */
    $f = wire('modules')->get('InputfieldMarkup');
    $f->name  = 'instructions';
    $f->label = __('Instructions', __FILE__);
    $f->markupText = __('Create your processes then enter a path to the json or php definition file of the fields in the path field.', __FILE__);
    $inputfields->add($f);

    return $inputfields;

  }

  /**
   * @var $key - the settings key
   * @var $_key - the setting within the key
   * @var $value - the new value
   */
  public function changeSetting($key,$_key,$value) {

    $modData = $this->modules->getConfig('SettingsFactory');
    if(!array_key_exists($key, $modData)) return;
    if(!array_key_exists($_key, $modData[$key])) return;
    $modData[$key][$_key] = $value;
    $this->modules->saveModuleConfigData('SettingsFactory', $modData);

  }


}