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);

    }


}