ktwidgets.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 931 行 · 第 1/3 页

PHP
931
字号
<?php
/**
 * $Id: KTWidgets.php 8387 2008-04-22 16:36:04Z kevin_fourie $
 *
 * KnowledgeTree Community Edition
 * Document Management Made Simple
 * Copyright (C) 2008 KnowledgeTree Inc.
 * Portions copyright The Jam Warehouse Software (Pty) Limited
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 3 as published by the
 * Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, 
 * California 94120-7775, or email info@knowledgetree.com.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * KnowledgeTree" logo and retain the original copyright notice. If the display of the 
 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
 * must display the words "Powered by KnowledgeTree" and retain the original 
 * copyright notice.
 * Contributor( s): ______________________________________
 */

require_once(KT_LIB_DIR . '/widgets/basewidget.inc.php');
require_once(KT_LIB_DIR . '/templating/templating.inc.php');
require_once(KT_LIB_DIR . '/browse/DocumentCollection.inc.php');

class KTCoreStringWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.string';
    var $sTemplate = 'ktcore/forms/widgets/string';
}

class KTCoreHiddenWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.hidden';
    var $sTemplate = 'ktcore/forms/widgets/hidden';
}

class KTCoreFileWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.file';
    var $sTemplate = 'ktcore/forms/widgets/file';

    function wrapName($outer) {
        $this->sName = sprintf('_kt_attempt_unique_%s', $this->sName);
        // we don't have access via "wrap" when processing, so we can't actually
        // wrap.  just don't use a lot of names
    }

    function process($data){
        $tname = sprintf('_kt_attempt_unique_%s', $this->sName);
        return array($this->sBasename => $_FILES[$tname]);
    }

    function getValidators() {
        if (!$this->bAutoValidate) {
            return null;
        }

        $oVF =& KTValidatorFactory::getSingleton();
        return $oVF->get('ktcore.validators.requiredfile', array(
            'test' => sprintf('_kt_attempt_unique_%s', $this->sName),
            'basename' => $this->sBasename,
        ));
    }
}


class KTCoreTextWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.text';
    var $sTemplate = 'ktcore/forms/widgets/text';
}

class KTCoreReasonWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.reason';
    var $sTemplate = 'ktcore/forms/widgets/text';

    function configure($aOptions) {
        $res = parent::configure($aOptions);
        if (PEAR::isError($res)) {
            return $res;
        }

        // FIXME make required *either* per-action property
        // FIXME or a global pref.
        $global_required_default = true;
        $this->bRequired = KTUtil::arrayGet($aOptions, 'required', $global_required_default, false);

        $this->aOptions['cols'] = KTUtil::arrayGet($aOptions, 'cols', 60);
        $this->aOptions['rows'] = KTUtil::arrayGet($aOptions, 'rows', 3);
    }
}

class KTCoreBooleanWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.boolean';
    var $sTemplate = 'ktcore/forms/widgets/boolean';

    function setDefault($mValue) {
        $this->value = ($mValue == true);
    }
}

class KTCorePasswordWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.password';
    var $sTemplate = 'ktcore/forms/widgets/password';

    var $bConfirm = false;
    var $sConfirmDescription;

    function configure($aOptions) {
        $res = parent::configure($aOptions);
        if (PEAR::isError($res)) {
            return $res;
        }

        $this->bConfirm = KTUtil::arrayGet($aOptions, 'confirm', false);
        $this->sConfirmDescription = KTUtil::arrayGet($aOptions, 'confirm_description');
    }

    function process($raw_data) {
        // since we're essentially a string, pass *that* out as the primary
        // but we also might want to confirm, and if so we use a private name
        $res = array();
        if ($this->bConfirm) {
            $res['_password_confirm_' . $this->sBasename] = array(
                'base' => $raw_data[$this->sBasename]['base'],
                'confirm' => $raw_data[$this->sBasename]['confirm'],
            );
            $res[$this->sBasename] = $raw_data[$this->sBasename]['base'];
        } else {
            $res[$this->sBasename] = $raw_data[$this->sName];
        }
        return $res;
    }

    function getValidators() {
        if (!$this->bAutoValidate) {
            return null;
        }
        $oVF =& KTValidatorFactory::getSingleton();

        $val = array();
        $val[] = parent::getValidators(); // required, etc.
        $val[] = $oVF->get('ktcore.validators.password', array(
            'test' => $this->sOrigname,
            'basename' => $this->sBasename
        ));

        return $val;
    }
}


class KTCoreSelectionWidget extends KTWidget {
    var $sNamespace = 'ktcore.widgets.selection';

    var $bMulti = false;    // multiselection
    var $USE_SIMPLE = 10;   // point at which to switch to a dropdown/multiselect
    var $bUseSimple;    // only use checkboxes, regardless of size

    var $aVocab;

    var $sEmptyMessage;

    var $_valuesearch;

    function configure($aOptions) {
        $res = parent::configure($aOptions);
        if (PEAR::isError($res)) {
            return $res;
        }

        $this->bUseSimple = KTUtil::arrayGet($aOptions, 'simple_select', null, false);
        $this->bMulti = KTUtil::arrayGet($aOptions, 'multi', false);

        $this->aVocab = (array) KTUtil::arrayGet($aOptions, 'vocab');
        $this->sEmptyMessage = KTUtil::arrayGet($aOptions, 'empty_message',
            _kt('No options available for this field.'));
    }

    function getWidget() {
        // very simple, general purpose passthrough.  Chances are this is sufficient,
        // just override the template being used.
        $bHasErrors = false;
        if (count($this->aErrors) != 0) { $bHasErrors = true; }

        // at this last moment we pick the template to use
        $total = count($this->aVocab);
        if ($this->bUseSimple === true) {
            $this->sTemplate = 'ktcore/forms/widgets/simple_selection';
        } else if ($this->bUseSimple === false) {
            $this->sTemplate = 'ktcore/forms/widgets/selection';
        } else if (is_null($this->bUseSimple) && ($total <= $this->USE_SIMPLE)) {
            $this->sTemplate = 'ktcore/forms/widgets/simple_selection';
        } else {
            $this->sTemplate = 'ktcore/forms/widgets/selection';
        }

        $oTemplating =& KTTemplating::getSingleton();
        $oTemplate = $oTemplating->loadTemplate($this->sTemplate);

        // have to do this here, and not in "configure" since it breaks
        // entity-select.
        $unselected = KTUtil::arrayGet($this->aOptions, 'unselected_label');
        if (!empty($unselected)) {
            // NBM:  we get really, really nasty interactions if we try merge
            // NBM:  items with numeric (but important) key values and other
            // NBM:  numerically / null keyed items
            $vocab = array();
            $vocab[] = $unselected;
            foreach ($this->aVocab as $k => $v) {
                $vocab[$k] = $v;
            }

            $this->aVocab = $vocab;

            // make sure its the selected one if there's no value specified.
            if (empty($this->value)) {
                $this->value = '0';
            }
        }

        // performance optimisation for large selected sets.
        if ($this->bMulti) {
            $this->_valuesearch = array();
            $value = (array) $this->value;
            foreach ($value as $v) {
                $this->_valuesearch[$v] = true;
            }
        }

        $aTemplateData = array(
            'context' => $this,
            'name' => $this->sName,
            'has_id' => ($this->sId !== null),
            'id' => $this->sId,
            'has_value' => ($this->value !== null),
            'value' => $this->value,
            'options' => $this->aOptions,
            'vocab' => $this->aVocab,
        );
        return $oTemplate->render($aTemplateData);
    }

    function selected($lookup) {
        if ($this->bMulti) {
            return $this->_valuesearch[$lookup];
        } else {
            return ($this->value == $lookup);
        }
    }

    function process($raw_data) {
        return array($this->sBasename => $raw_data[$this->sBasename]);
    }
}

// this happens so often, its worth creating a util function for it
class KTCoreEntitySelectionWidget extends KTCoreSelectionWidget {
    var $sNamespace = 'ktcore.widgets.entityselection';

    var $sIdMethod;
    var $sLabelMethod;

    function configure($aOptions) {
        $res = parent::configure($aOptions);
        if (PEAR::isError($res)) {
            return $res;
        }

        // the selection widget's configure method has already setup almost
        // all the vars we need.  we have one utility here, where you pass
        // in a list of existing entities that match the query, and we work
        // from there.

        $this->sIdMethod = KTUtil::arrayGet($aOptions, 'id_method', 'getId');
        $this->sLabelMethod = KTUtil::arrayGet($aOptions, 'label_method');
        if (empty($this->sLabelMethod)) {
            return PEAR::raiseError(_kt('No label method specified.'));
        }
        $existing_entities = (array) KTUtil::arrayGet($aOptions, 'existing_entities');

        // now we construct the "value" array from this set
        // BUT ONLY IF WE DON'T HAVE A "VALUE" array.
        if (empty($this->value)) {
            $this->value = array();
            foreach ($existing_entities as $oEntity) {
                $this->value[] = call_user_func(array(&$oEntity, $this->sIdMethod));
            }
        }

        // we next walk the "vocab" array, constructing a new one based on the
        // functions passed in so far.
        $new_vocab = array();
        foreach ($this->aVocab as $oEntity) {
            $id = call_user_func(array(&$oEntity, $this->sIdMethod));
            $label = call_user_func(array(&$oEntity, $this->sLabelMethod));
            $new_vocab[$id] = $label;
        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?