/library/Adapto/Attribute.php
PHP | 1980 lines | 659 code | 214 blank | 1107 comment | 158 complexity | 3417581a86029525812ff761dc1bb95e MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * This file is part of the Adapto Toolkit.
- * Detailed copyright and licensing information can be found
- * in the doc/COPYRIGHT and doc/LICENSE files which should be
- * included in the distribution.
- *
- * @package adapto
- * @subpackage attributes
- *
- * @copyright (c)2000-2006 Ivo Jansch
- * @copyright (c)2000-2006 Ibuildings.nl BV
- * @license http://www.achievo.org/atk/licensing ATK Open Source License
- *
- */
- /**
- * Attributeflags. The following flags can be used for attributes
- * @internal WARNING: flags may *not* exceed 2^31 (2147483648), because
- * that's the integer limit beyond which the bitwise operators won't
- * work anymore!
- */
- /**
- * Value must be entered
- *
- * "database-level" processing flag
- */
- define("AF_OBLIGATORY", 1);
- /**
- * Value must be unique
- *
- * "database-level" processing flag
- */
- define("AF_UNIQUE", 2);
- /**
- * Part of the primary-key entity, also makes it obligatory
- *
- * "database-level" processing flag
- */
- define("AF_PRIMARY", 4 | AF_OBLIGATORY);
- /**
- * Auto-increment field
- *
- * "database-level" processing flag
- */
- define("AF_AUTO_INCREMENT", 8);
- /**
- * Alias for AF_AUTO_INCREMENT (auto-increment flag is often mistyped)
- *
- * "database-level" processing flag
- */
- define("AF_AUTOINCREMENT", AF_AUTO_INCREMENT);
- /**
- * Don't show in record lists
- *
- * hide flag
- */
- define("AF_HIDE_LIST", 16);
- /**
- * Don't show on add pages
- *
- * hide flag
- */
- define("AF_HIDE_ADD", 32);
- /**
- * Don't show on edit pages
- *
- * hide flag
- */
- define("AF_HIDE_EDIT", 64);
- /**
- * Don't show on select pages
- *
- * hide flag
- */
- define("AF_HIDE_SELECT", 128);
- /**
- * Don't show on view pages
- *
- * hide flag
- */
- define("AF_HIDE_VIEW", 256);
- /**
- * Not searchable in extended search
- *
- * hide flag
- */
- define("AF_HIDE_SEARCH", 512); // not searchable in extended search
- /**
- * Load always, even if not displayed anywhere
- *
- * hide flag
- */
- define("AF_FORCE_LOAD", 1024); // load always, even if not displayed anywhere
- /**
- * Attribute is totally hidden
- *
- * hide flag
- */
- define("AF_HIDE",
- AF_HIDE_EDIT | AF_HIDE_ADD | // attribute is totally hidden
- AF_HIDE_LIST | AF_HIDE_SEARCH | AF_HIDE_VIEW | AF_HIDE_SELECT);
- /**
- * Readonly in add
- *
- * readonly flag
- */
- define("AF_READONLY_ADD", 2048); // readonly in add
- /**
- * Readonly when edited
- *
- * readonly flag
- */
- define("AF_READONLY_EDIT", 4096); // readonly when edited
- /**
- * Always readonly
- *
- * readonly flag
- */
- define("AF_READONLY", AF_READONLY_EDIT | AF_READONLY_ADD); // always readonly
- /**
- * No label in forms
- *
- * display-related processing flag
- */
- define("AF_NO_LABEL", 8192); // no label in forms
- /**
- * Alias for AF_NO_LABEL (mistyped)
- *
- * display-related processing flag
- */
- define("AF_NOLABEL", AF_NO_LABEL); // no label (mistyped)
- /**
- * Blank label in forms
- *
- * display-related processing flag
- */
- define("AF_BLANK_LABEL", 16384); // blank label in forms
- /**
- * Alias for AF_BLANK_LABEL (mistyped)
- *
- * display-related processing flag
- */
- define("AF_BLANKLABEL", AF_BLANK_LABEL); // blank label (mistyped)
- /**
- * Cannot be sorted in recordlists
- *
- * display-related processing flag
- */
- define("AF_NO_SORT", 32768); // cannot be sorted in recordlists.
- /**
- * Alias for AF_NO_SORT (mistyped)
- *
- * display-related processing flag
- */
- define("AF_NOSORT", AF_NO_SORT); // no-sort flag is often mistyped
- /**
- * Attribute is searchable in list views
- *
- * display-related processing flag
- */
- define("AF_SEARCHABLE", 65536); // Attribute is searchable in list views
- /**
- * The attribute will have a 'total' column in lists
- *
- * display-related processing flag
- */
- define("AF_TOTAL", 131072); // The attribute will have a 'total' column in lists.
- /**
- * If supported, use pop-up window
- *
- * display-related processing flag
- */
- define("AF_POPUP", 262144); // if supported, use pop-up window
- /**
- * Delete function is called when owning entity is deleted
- *
- * miscellaneous processing flag
- */
- define("AF_CASCADE_DELETE", 524288); // delete function is called when owning entity is deleted
- /**
- * Will have a large amount of recors (relation)
- *
- * Instead of showing a listbox with all the records it will show an add link to a select page
- *
- * miscellaneous processing flag
- */
- define("AF_LARGE", 1048576); // will have a large ammount of records (relation)
- /**
- * Ignore filters when selecting records (relation)
- *
- * miscellaneous processing flag
- */
- define("AF_NO_FILTER", 2097152); // ignore filters when selecting records (relation)
- /**
- * Parent field for parent child relations (treeview)
- *
- * miscellaneous processing flag
- */
- define("AF_PARENT", 4194304); // parent field for parent child relations (treeview)
- /**
- * No quotes are used when adding to the database
- *
- * miscellaneous processing flag
- */
- define("AF_NO_QUOTES", 8388608); // no quotes are used when adding to database
- /**
- * Multi-language field
- *
- * miscellaneous processing flag
- */
- define("AF_ML", 16777216); // multi-language field
- /**
- * Alias for AF_ML (spelled out)
- *
- * miscellaneous processing flag
- */
- define("AF_MULTILANGUAGE", AF_ML);
- /**
- * Shortcut for hidden auto-incremented primary key
- *
- * miscellaneous processing flag
- */
- define("AF_AUTOKEY", AF_PRIMARY | AF_HIDE | // shortcut for hidden auto-incremented primary-key
- AF_AUTOINCREMENT);
- /*
- * flag (values) that can be used for attribute specific flags
- * NOTE: Attribute specific flags aren't good behaviour, but for
- * compatibility reasons we support them anyway. Newly derived attributes
- * should not use these specific flags, but work with extra parameters.
- */
- /**
- * Specific attribute flag 1
- */
- define("AF_SPECIFIC_1", 33554432); // specific attribute flag 1
- /**
- * Specific attribute flag 2
- */
- define("AF_SPECIFIC_2", 67108864); // specific attribute flag 2
- /**
- * Specific attribute flag 3
- */
- define("AF_SPECIFIC_3", 134217728); // specific attribute flag 3
- /**
- * Specific attribute flag 4
- */
- define("AF_SPECIFIC_4", 268435456); // specific attribute flag 4
- /**
- * Specific attribute flag 5
- */
- define("AF_SPECIFIC_5", 536870912); // specific attribute flag 5
- /**
- * Do not store this attribute
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("NOSTORE", 0);
- /**
- * Do not load this attribute
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("NOLOAD", 0);
- /**
- * Store before all other ('normal') attributes (?)
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("PRESTORE", 1);
- /**
- * Call load before selectDb()
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("PRELOAD", 1);
- /**
- * Store after all other ('normal') attributes (?)
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("POSTSTORE", 2);
- /**
- * Call load after selectDb()
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("POSTLOAD", 2);
- /**
- * Do addToQuery() of this attribute
- *
- * Storage type flag, used by the storageType() and related methods
- */
- define("ADDTOQUERY", 4);
- /**
- * Attribute is disable in view mode
- */
- define("DISABLED_VIEW", 1);
- /**
- * Attribute is disable in edit mode
- */
- define("DISABLED_EDIT", 2);
- /**
- * Attribute is disabled in view and edit mode
- */
- define("DISABLED_ALL", DISABLED_VIEW | DISABLED_EDIT);
- /**
- * The Adapto_Attribute class represents an attribute of an atkEntity.
- * An Adapto_Attribute has a name and a set of parameters that
- * control its behaviour, like whether an Adapto_Attribute
- * is obligatory, etc.
- *
- * @author ijansch
- * @package adapto
- * @subpackage attributes
- */
- class Adapto_Attribute
- {
- /**
- * The name of the attribute
- * @access private
- * @var String
- */
- public $m_name; // defaulted to public
- /**
- * The attribute flags (see above)
- * @access private
- * @var int
- */
- public $m_flags = 0; // defaulted to public
- /**
- * The name of the atkEntity that owns this attribute (set by atkentity)
- * @access private
- * @var String
- */
- public $m_owner = ""; // defaulted to public
- /**
- * The module of the attribute (if empty, the module from the owner entity
- * should be assumed).
- * @access private
- * @var String
- *
- */
- public $m_module = ""; // defaulted to public
- /**
- * Instance of the atkEntity that owns this attribute
- * @access private
- * @var atkEntity
- */
- public $m_ownerInstance = ""; // defaulted to public
- /**
- * The size the attribute's field.
- * @access private
- * @var int
- */
- public $m_size = 0; // defaulted to public
- /**
- * The size the attribute's search input field.
- * @access private
- * @var int
- */
- public $m_searchsize = 0; // defaulted to public
- /**
- * The maximum size the attribute's value may have in the database.
- * @access private
- * @var int
- */
- public $m_maxsize = 0; // defaulted to public
- /**
- * The database fieldtype.
- * @access private
- * @var String
- */
- public $m_dbfieldtype = ""; // defaulted to public
- /**
- * The order of the attribute within its entity.
- * @access private
- * @var int
- */
- public $m_order = 0; // defaulted to public
- /**
- * Index of the attribute within its entity.
- * @access private
- * @var int
- */
- public $m_index = 0; // defaulted to public
- /**
- * The tab(s) on which the attribute lives.
- * @access private
- * @var mixed
- */
- public $m_tabs = "*"; // defaulted to public
- /**
- * The section(s) on which the attribute lives.
- * @access private
- * @var mixed
- */
- public $m_sections = "*"; // defaulted to public
- /**
- * The id of the attribute in the HTML
- * @access private
- * @var String
- */
- public $m_htmlid; // defaulted to public
- /**
- * The css classes of the attribute
- * @access private
- * @var sttsy
- */
- public $m_cssclasses = array(); // defaulted to public
- /**
- * The label of the attribute.
- * @access private
- * @var String
- */
- public $m_label = ""; // defaulted to public
- /**
- * The postfix label of the attribute.
- * @access private
- * @var String
- */
- public $m_postfixlabel = ""; // defaulted to public
- /**
- * The searchmode for this attribute
- *
- * This var exists so that you can assign searchmodes to specific
- * attributes instead of having a general searchmode for the entire
- * search. This can be any one of the supported modes, as returned by
- * the attribute's getSearchModes() method.
- * @access private
- * @var String
- */
- public $m_searchmode = ""; // defaulted to public
- /**
- * Wether to force an insert of the attribute
- * @access private
- * @var bool
- */
- public $m_forceinsert = false; // defaulted to public
- /**
- * Wether to force a reload of the attribute ignoring the saved session data
- *
- * @access private
- * @var bool
- */
- public $m_forcereload = false; // defaulted to public
- /**
- * Wether to force an update of the attribute
- * @access private
- * @var bool
- */
- public $m_forceupdate = false; // defaulted to public
- /**
- * Array for containing onchange javascript code
- * @access private
- * @var Array
- */
- public $m_onchangecode = array(); // defaulted to public
- /**
- * Variable to store initialisation javascript code
- * in for the changehandler.
- * @access private
- * @var String
- */
- public $m_onchangehandler_init = ""; // defaulted to public
- /**
- * Variable to store dependency callbacks.
- *
- * @var array
- */
- private $m_dependencies = array();
- /**
- * Attribute to store disabled modes.
- * @access private
- * @var int
- */
- public $m_disabledModes = 0; // defaulted to public
- /**
- * Whether to hide initially or not
- * @access private
- * @var bool
- */
- public $m_initial_hidden = false; // defaulted to public
- /**
- * Storage type.
- * @access private
- * @var int
- * @see setStorageType
- */
- public $m_storageType = array(); // defaulted to public
- /**
- * Load type.
- * @access private
- * @var int
- * @see setLoadType
- */
- public $m_loadType = array(); // defaulted to public
- /**
- * Initial value.
- * @access private
- * @var mixed
- * @see setInitialValue
- */
- public $m_initialValue = NULL; // defaulted to public
- /**
- * Column.
- *
- * @var string
- */
- private $m_column;
- /**
- * JavaScript observers. Key is the event name
- * value is an array with event handlers.
- *
- * @var array
- */
- private $m_jsObservers = array();
- /**
- * View callback.
- *
- * @var mixed
- */
- private $m_viewCallback = null;
- /**
- * Edit callback.
- *
- * @var mixed
- */
- private $m_editCallback = null;
- /**
- * Constructor
- *
- * <b>Example:</b>
- * $this->add(new Adapto_Attribute("name",AF_OBLIGATORY, 30));
- *
- * Note: If you want to use the db/ddl utility class to
- * automatically generate the table, the $size parameter must be
- * set, for it will use the size specified here to determine the
- * field length. (Derived classes might have reasonable default
- * values, but the standard Adapto_Attribute doesn't.)
- *
- * @param String $name Name of the attribute (unique within an entity, and
- * for most attributes, corresponds to a field in
- * the database.
- * @param int $flags Flags for the attribute.
- * @param mixed $size The size(s) of the attribute. See the $size
- * parameter of the setAttribSize() method for more
- * information on the possible values of this
- * parameter.
- *
- */
- public function __construct($name, $flags = 0, $size = 0)
- {
- $this->m_name = $name;
- $this->setFlags((int) $flags);
- $this->setAttribSize($size);
- // default class
- $this->addCSSClass(get_class($this));
- }
- /**
- * Returns the owner instance.
- *
- * @return atkEntity owner instance
- */
- function &getOwnerInstance()
- {
- return $this->m_ownerInstance;
- }
- /**
- * Sets the owner instance.
- *
- * @param atkEntity $instance
- */
- function setOwnerInstance(&$instance)
- {
- $this->m_ownerInstance = &$instance;
- }
- /**
- * Check if the attribute has a certain flag.
- * @param int $flag The flag you want to check
- * @return boolean
- */
- function hasFlag($flag)
- {
- return (($this->m_flags & $flag) == $flag);
- }
- /**
- * Returns the full set of flags of the attribute.
- * @return int $m_flags The full set of flags
- */
- function getFlags()
- {
- return $this->m_flags;
- }
- /**
- * Adds a flag to the attribute.
- * Note that adding flags at any time after the constructor might not
- * always work. There are flags that are processed only at
- * constructor time.
- * @param int $flag The flag to add to the attribute
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function addFlag($flag)
- {
- $this->m_flags |= $flag;
- if (!$this->hasFlag(AF_PRIMARY) && is_object($this->m_ownerInstance)) {
- if (hasFlag($flag, AF_HIDE_LIST) && !in_array($this->fieldName(), $this->m_ownerInstance->m_listExcludes)) {
- $this->m_ownerInstance->m_listExcludes[] = $this->fieldName();
- }
- if (hasFlag($flag, AF_HIDE_VIEW) && !in_array($this->fieldName(), $this->m_ownerInstance->m_viewExcludes)) {
- $this->m_ownerInstance->m_viewExcludes[] = $this->fieldName();
- }
- }
- return $this;
- }
- /**
- * Sets the flags of the attribute
- *
- * Note that if you assign nothing or 0, this will remove all the flags
- * from the attribute. You can assign multiple flags by using the pipe
- * symbol. Setting the flags will overwrite all previous flag-settings.
- * @param int $flags The flags to be set to the attribute.
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function setFlags($flags = 0)
- {
- $this->m_flags = 0;
- $this->addFlag($flags); // always call addFlag
- return $this;
- }
- /**
- * Removes a flag from the attribute.
- *
- * Note that removing flags at any time after the constructor might not
- * always work. There are flags that have already been processed at
- * constructor time, so removing them will be futile.
- * @param int $flag The flag to remove from the attribute
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function removeFlag($flag)
- {
- if ($this->hasFlag($flag)) {
- $this->m_flags ^= $flag;
- }
- if (!$this->hasFlag(AF_PRIMARY) && is_object($this->m_ownerInstance)) {
- if (hasFlag($flag, AF_HIDE_LIST) && in_array($this->fieldName(), $this->m_ownerInstance->m_listExcludes)) {
- $key = array_search($this->fieldName(), $this->m_ownerInstance->m_listExcludes);
- unset($this->m_ownerInstance->m_listExcludes[$key]);
- }
- if (hasFlag($flag, AF_HIDE_VIEW) && in_array($this->fieldName(), $this->m_ownerInstance->m_viewExcludes)) {
- $key = array_search($this->fieldName(), $this->m_ownerInstance->m_viewExcludes);
- unset($this->m_ownerInstance->m_viewExcludes[$key]);
- }
- }
- return $this;
- }
- /**
- * Adds a disabled mode flag to the attribute (use DISABLED_VIEW and DISABLED_EDIT flags).
- * @param int $flag The flag to add to the attribute
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function addDisabledMode($flag)
- {
- $this->m_disabledModes |= $flag;
- return $this;
- }
- /**
- * Check if the attribute is disabled in some mode (use DISABLED_VIEW and DISABLED_EDIT flags).
- * @param int $flag The flag you want to check
- * @return boolean
- */
- function hasDisabledMode($flag)
- {
- return (($this->m_disabledModes & $flag) == $flag);
- }
- /**
- * Sets the disabled mode flag of the attribute
- *
- * Note that if you assign nothing or 0, this will remove all the flags
- * from the attribute. You can assign multiple flags by using the pipe
- * symbol. Setting the flags will overwrite all previous flag-settings.
- * @param int $flags The flags to be set to the attribute.
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function setDisabledModes($flags = 0)
- {
- $this->m_disabledModes = $flags;
- return $this;
- }
- /**
- * Removes a disabled mode from the attribute.
- *
- * @param int $flag The flag to remove from the attribute
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function removeDisabledMode($flag)
- {
- if ($this->hasDisabledMode($flag)) {
- $this->m_disabledModes ^= $flag;
- }
- return $this;
- }
- /**
- * Returns the name of the attribute.
- *
- * For most attributes, this corresponds to the name of the field in the
- * database. For some attributes though (like one2many relations), the
- * name is a mere identifier within an entity. This method always returns
- * the attribute name, despite the 'field' prefix of the method.
- *
- * @return String fieldname
- */
- function fieldName()
- {
- return $this->m_name;
- }
- /**
- * Check if a record has an empty value for this attribute.
- * @param array $record The record that holds this attribute's value.
- * @return boolean
- */
- function isEmpty($record)
- {
- return (!isset($record[$this->fieldName()]) || $record[$this->fieldName()] === "");
- }
- /**
- * Converts the internal attribute value to one that is understood by the
- * database.
- *
- * For the regular Adapto_Attribute, this means escaping things like
- * quotes and slashes. Derived attributes may reimplement this for their
- * own conversion.
- * This is the exact opposite of the db2value method.
- *
- * @param array $rec The record that holds this attribute's value.
- * @return String The database compatible value
- */
- function value2db($rec)
- {
- if (is_array($rec) && isset($rec[$this->fieldName()])) {
- return $this->escapeSQL($rec[$this->fieldName()]);
- }
- return NULL;
- }
- /**
- * Converts a database value to an internal value.
- *
- * For the regular Adapto_Attribute
- * Derived attributes may reimplement this for their own conversion.
- * (In which case, the return type might be 'mixed')
- *
- * This is the exact opposite of the value2db method.
- *
- * @param array $rec The database record that holds this attribute's value
- * @return mixed The internal value
- */
- function db2value($rec)
- {
- if (isset($rec[$this->fieldName()])) {
- return $rec[$this->fieldName()] === NULL ? NULL : $rec[$this->fieldName()];
- }
- return NULL;
- }
- /**
- * Is there a value posted for this attribute?
- *
- * @param array $postvars
- * @return boolean posted?
- */
- function isPosted($postvars)
- {
- return is_array($postvars) && isset($postvars[$this->fieldName()]);
- }
- /**
- * Set initial value for this attribute.
- *
- * NOTE: the initial value only works if there is no initial_values override
- * in the entity or if the override properly calls parent::initial_values!
- *
- * @param mixed $value initial value
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function setInitialValue($value)
- {
- $this->m_initialValue = $value;
- return $this;
- }
- /**
- * Initial value. Returns the initial value for this attribute
- * which will be used in the add form etc.
- *
- * @return mixed initial value for this attribute
- */
- function initialValue()
- {
- return $this->m_initialValue;
- }
- /**
- * Convert values from an HTML form posting to an internal value for
- * this attribute.
- *
- * For the regular Adapto_Attribute, this means getting the field with the
- * same name as the attribute from the html posting.
- *
- * @param array $postvars The array with html posted values ($_POST, for
- * example) that holds this attribute's value.
- * @return String The internal value
- */
- function fetchValue($postvars)
- {
- if ($this->isPosted($postvars)) {
- return $postvars[$this->fieldName()];
- }
- }
- /**
- * Register JavaScript event handlers.
- *
- * @param string $fieldId field identifier
- */
- protected function registerJavaScriptObservers($fieldId)
- {
- foreach ($this->m_jsObservers as $event => $handlers) {
- foreach ($handlers as $handler) {
- $code = '$(\'' . $fieldId . '\').observe(\'' . $event . '\', function(event) { var fieldId = \'' . $fieldId . '\'; ' . $handler . ' });';
- $this->getOwnerInstance()->getPage()->register_loadscript($code);
- }
- }
- }
- /**
- * Returns a piece of html code that can be used in a form to edit this
- * attribute's value.
- *
- * @param array $record The record that holds the value for this attribute.
- * @param String $fieldprefix The fieldprefix to put in front of the name
- * of any html form element for this attribute.
- * @param String $mode The mode we're in ('add' or 'edit')
- * @return String A piece of htmlcode for editing this attribute
- */
- function edit($record = "", $fieldprefix = "", $mode = "")
- {
- $id = $this->getHtmlId($fieldprefix);
- $this->registerKeyListener($id, KB_CTRLCURSOR | KB_UPDOWN);
- if (count($this->m_onchangecode)) {
- $onchange = 'onChange="' . $id . '_onChange(this);"';
- $this->_renderChangeHandler($fieldprefix);
- } else {
- $onchange = '';
- }
- $this->registerJavaScriptObservers($id);
- $size = $this->m_size;
- if ($mode == 'list' && $size > 20)
- $size = 20;
- $value = (isset($record[$this->fieldName()]) && !is_array($record[$this->fieldName()]) ? htmlspecialchars($record[$this->fieldName()]) : "");
- $result = '<input type="text" id="' . $id . '" name="' . $id . '" ' . $this->getCSSClassAttribute() . ' value="' . $value . '"'
- . ($size > 0 ? ' size="' . $size . '"' : '') . ($this->m_maxsize > 0 ? ' maxlength="' . $this->m_maxsize . '"' : '') . ' ' . $onchange . ' />';
- return $result;
- }
- /**
- * Add a javascript onchange event handler.
- * @param string $jscode A block of valid javascript code.
- * @return Adapto_Attribute Returns the instance of this attribute.
- */
- function addOnChangeHandler($jscode)
- {
- if (!in_array($jscode, $this->m_onchangecode))
- $this->m_onchangecode[] = $jscode;
- return $this;
- }
- /**
- * Renders the onchange code on the page.
- *
- * @access private
- * @param String $fieldprefix The prefix to the field
- * @param String $elementNr The number of the element when attribute contains multiple options
- */
- function _renderChangeHandler($fieldprefix, $elementNr = "")
- {
- if (count($this->m_onchangecode)) {
- $page = &$this->m_ownerInstance->getPage();
- $page
- ->register_scriptcode(
- "
- function " . $this->getHtmlId($fieldprefix) . $elementNr . "_onChange(el)
- {
- {$this->m_onchangehandler_init}
- " . implode("\n ", $this->m_onchangecode) . "
- }\n");
- }
- }
- /**
- * Returns a piece of html code for hiding this attribute in an HTML form,
- * while still posting its value. (<input type="hidden">)
- *
- * @param array $record The record that holds the value for this attribute
- * @param String $fieldprefix The fieldprefix to put in front of the name
- * of any html form element for this attribute.
- * @return String A piece of htmlcode with hidden form elements that post
- * this attribute's value without showing it.
- */
- function hide($record = "", $fieldprefix = "")
- {
- // the next if-statement is a workaround for derived attributes which do
- // not override the hide() method properly. This will not give them a
- // working hide() functionality but at least it will not give error messages.
- if (!is_array($record[$this->fieldName()])) {
- $id = $id = $this->getHtmlId($fieldprefix);
- $result = '<input type="hidden" id="' . $id . '" name="' . $fieldprefix . $this->formName() . '" value="'
- . htmlspecialchars($record[$this->fieldName()]) . '">';
- return $result;
- } else
- Adapto_Util_Debugger::debug("Warning attribute " . $this->m_name . " has no proper hide method!");
- }
- /**
- * Return the html identifier (id="") of the attribute. (unique within a
- * page)
- * @param String $fieldprefix The fieldprefix to put in front of the name
- * of any html form element for this attribute.
- * @return String the HTML identifier.
- */
- function getHtmlId($fieldprefix)
- {
- $this->m_htmlid = $fieldprefix . $this->fieldName();
- return $this->m_htmlid;
- }
- /**
- * Returns the html identifier of the attribute without setting it
- * Created because getHtmlId would always SET the htmlid while getting it.
- * @return String The HTML id of this attribute
- */
- function getAttributeHtmlId()
- {
- if ($this->m_htmlid)
- return $this->m_htmlid;
- else
- return $this->fieldName();
- }
- /**
- * Adds the attribute's view / hide HTML code to the view array.
- *
- * This method is called by the entity if it wants the data needed to create
- * a view form.
- *
- * This is a framework method, it should never be called directly.
- *
- * @param String $mode the mode ("view")
- * @param array $arr pointer to the view array
- * @param array $defaults pointer to the default values array
- */
- function addToViewArray($mode, &$arr, &$defaults)
- {
- if (!$this->hasFlag(AF_HIDE_VIEW)) {
- $entry = array("name" => $this->m_name, "attribute" => &$this);
- /* label? */
- $entry["label"] = $this->getLabel($defaults, $mode);
- // on which tab?
- $entry["tabs"] = $this->getTabs($mode);
- //on which sections?
- $entry["sections"] = $this->getSections();
- /* the actual edit contents */
- $entry["html"] = $this->getView($mode, $defaults);
- $arr["fields"][] = $entry;
- }
- }
- /**
- * Prepare for edit. Is called before all attributes are added to the
- * edit array and allows for last minute manipulations based on the
- * record but also manipulations on the record itself.
- *
- * @param array $record reference to the record
- * @param string $fieldPrefix field prefix
- * @param string $mode edit mode
- */
- public function preAddToEditArray(&$record, $fieldPrefix, $mode)
- {
- }
- /**
- * Prepare for view. Is called before all attributes are added to the
- * view array and allows for last minute manipulations based on the
- * record but also manipulations on the record itself.
- *
- * @param array $record reference to the record
- * @param string $mode view mode
- */
- public function preAddToViewArray(&$record, $mode)
- {
- }
- /**
- * Adds the attribute's edit / hide HTML code to the edit array.
- *
- * This method is called by the entity if it wants the data needed to create
- * an edit form.
- *
- * This is a framework method, it should never be called directly.
- *
- * @param String $mode the edit mode ("add" or "edit")
- * @param array $arr pointer to the edit array
- * @param array $defaults pointer to the default values array
- * @param array $error pointer to the error array
- * @param String $fieldprefix the fieldprefix
- */
- function addToEditArray($mode, &$arr, &$defaults, &$error, $fieldprefix)
- {
- /* hide */
- if (($mode == "edit" && $this->hasFlag(AF_HIDE_EDIT)) || ($mode == "add" && $this->hasFlag(AF_HIDE_ADD))) {
- /* when adding, there's nothing to hide, unless we're dealing with atkHiddenAttribute... */
- if ($mode == "edit" || ($mode == "add" && (!$this->isEmpty($defaults) || $this instanceof atkHiddenAttribute))) {
- $arr["hide"][] = $this->hide($defaults, $fieldprefix, $mode);
- }
- }
- /* edit */
- else {
- global $Adapto_VARS;
- $entry = array("name" => $this->m_name, "obligatory" => $this->hasFlag(AF_OBLIGATORY), "attribute" => &$this);
- $entry["id"] = $this->getHtmlId($fieldprefix);
- /* label? */
- $entry["label"] = $this->getLabel($defaults, $mode);
- /* error? */
- $entry["error"] = $this->getError($error)
- || (isset($Adapto_VARS["atkerrorfields"]) && Adapto_in_array($entry['id'], $Adapto_VARS['atkerrorfields']));
- // on which tab?
- $entry["tabs"] = $this->getTabs($mode);
- //on which sections?
- $entry["sections"] = $this->getSections();
- // the actual edit contents
- $entry["html"] = $this->getEdit($mode, $defaults, $fieldprefix);
- // initially hidden
- $entry["initial_hidden"] = $this->isInitialHidden($defaults);
- $arr["fields"][] = $entry;
- }
- }
- /**
- * Put the attribute on one or more tabs.
- * @param array $tabs An array of tabs on which the attribute should
- * be displayed.
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function setTabs($tabs)
- {
- if (empty($tabs) && isset($this->m_ownerInstance) && is_object($this->m_ownerInstance)) {
- $tabs = array($this->m_ownerInstance->m_default_tab);
- } else if (empty($tabs)) {
- $tabs = array('default');
- }
- $this->m_tabs = $tabs;
- return $this;
- }
- /**
- * retrieve the tabs for this attribute.
- * @param string $mode
- * @return array
- */
- function getTabs($mode = "")
- {
- return $this->m_tabs;
- }
- /**
- * Put the attribute on one or more tabs and/or sections.
- *
- * Example:
- * <code>$attribute->setSections(array('tab.section','tab.othersection));</code>
- *
- * @param array $sections An array of tabs and/or sections on which the attribute should
- * be displayed.
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- function setSections($sections)
- {
- if ($sections == NULL) {
- $this->m_sections = array();
- } else {
- $this->m_sections = $sections;
- }
- return $this;
- }
- /**
- * retrieve the tabs and/or sections for this attribute.
- *
- * @return array
- */
- function getSections()
- {
- return $this->m_sections;
- }
- /**
- * Get column.
- *
- * @return string column name
- */
- public function getColumn()
- {
- return $this->m_column;
- }
- /**
- * Set column.
- *
- * @param string $name column name
- * @return Adapto_Attribute The instance of this Adapto_Attribute
- */
- public function setColumn($name)
- {
- $this->m_column = $name;
- return $this;
- }
- /**
- * Returns the view callback (if set).
- *
- * @return mixed callback method
- */
- protected function getViewCallback()
- {
- return $this->m_viewCallback;
- }
- /**
- * Sets the view callback.
- *
- * The callback is called instead of the regular display method of the
- * attribute.
- *
- * @param mixed $callback callback method
- */
- public function setViewCallback($callback)
- {
- $this->m_viewCallback = $callback;
- }
- /**
- * Retrieve the html code for placing this attribute in a view page.
- *
- * Method is 'smart' and can be overridden in the entity using the
- * <attributename>_display() methods.
- *
- * Framework method, it should not be necessary to call this method
- * directly.
- *
- * @param String $mode The mode ("view")
- * @param array $defaults The record holding the values for this attribute
- *
- * @return String the HTML code for this attribute that can be used in a
- * viewpage.
- */
- function getView($mode, &$defaults)
- {
- $method = $this->m_name . "_display";
- if ($this->getViewCallback() != null) {
- return call_user_func($this->getViewCallback(), $defaults, $mode, $this);
- } else if (method_exists($this->m_ownerInstance, $method)) {
- return $this->m_ownerInstance->$method($defaults, $mode);
- } else {
- return $this->display($defaults, $mode) . (strlen($this->m_postfixlabel) > 0 ? " " . $this->m_postfixlabel : "");
- }
- }
- /**
- * Retrieve the html/javascript code for showing the tooltip for this attribute.
- *
- * @return String HTML
- */
- function getToolTip()
- {
- $tooltip = $this->text($this->fieldName() . '_tooltip', false);
- if (!$tooltip) {
- return '';
- }
- $template = atkTheme::getInstance()->tplPath('tooltip.tpl', $this->getModule());
- $vars = array('tooltip' => $tooltip, 'attribute' => $this);
- $result = $this->getOwnerInstance()->getUi()->render($template, $vars, $this->getModule());
- return $result;
- }
- /**
- * Returns the edit callback (if set).
- *
- * @return mixed callback method
- */
- protected function getEditCallback()
- {
- return $this->m_editCallback;
- }
- /**
- * Sets the edit callback.
- *
- * The callback is called instead of the regular display method of the
- * attribute.
- *
- * @param mixed $callback callback method
- */
- public function setEditCallback($callback)
- {
- $this->m_editCallback = $callback;
- }
- /**
- * Retrieve the HTML code for placing this attribute in an edit page.
- *
- * The difference with the edit() method is that the edit() method just
- * generates the HTML code for editing the attribute, while the getEdit()
- * method is 'smart', and implements a hide/readonly policy based on
- * flags and/or custom override methodes in the entity.
- * (<attributename>_edit() and <attributename>_display() methods)
- *
- * Framework method, it should not be necessary to call this method
- * directly.
- *
- * @param String $mode The edit mode ("add" or "edit")
- * @param array $defaults The record holding the values for this attribute
- * @param String $fieldprefix The fieldprefix to put in front of the name
- * of any html form element for this attribute.
- * @return String the HTML code for this attribute that can be used in an
- * editpage.
- */
- function getEdit($mode, &$defaults, $fieldprefix)
- {
- // readonly
- if (($mode == "edit" && $this->hasFlag(AF_READONLY_EDIT)) || ($mode == "add" && $this->hasFlag(AF_READONLY_ADD))) {
- return $this->hide($defaults, $fieldprefix) . $this->getView($mode, $defaults);
- }
- $method = $this->m_name . "_edit";
- if ($this->getEditCallback() != null) {
- return call_user_func($this->getEditCallback(), $defaults, $fieldprefix, $mode, $this);
- } else if ($this->m_name != "action" && method_exists($this->m_ownerInstance, $method)) {
- // we can't support the override for attributes named action, because of a conflict with
- // a possible edit action override (in both cases the method is called action_edit)
- return $this->m_ownerInstance->$method($defaults, $fieldprefix, $mode);
- } else {
- return $this->edit($defaults, $fieldprefix, $mode) . (strlen($this->m_postfixlabel) > 0 ? " " . $this->m_postfixlabel : "");
- }
- }
- /**
- * Check if this attribute has errors in the specified error list.
- *
- * @param array $errors The error list is one that is stored in the
- * "atkerror" section of a record, for example
- * generated by validate() methods.
- * @return boolean
- */
- function getError($errors)
- {
- for ($i = 0; $i < count($errors); $i++) {
- if ($errors[$i]['attrib_name'] == $this->fieldName() || Adapto_in_array($this->fieldName(), $errors[$i]['attrib_name'])) {
- return true;
- }
- }
- return false;
- }
- /**
- * Adds the attribute / field to the list header. This includes the column name and search field.
- *
- * Framework method. It should not be necessary to call this method directly.
- *
- * @param String $action the action that is being performed on the entity
- * @param array $arr reference to the the recordlist array
- * @param String $fieldprefix the fieldprefix
- * @param int $flags the recordlist flags
- * @param array $atksearch the current ATK search list (if not empty)
- * @param atkColumnConfig $columnConfig Column configuration object
- * @param atkDataGrid $grid The atkDataGrid this attribute lives on.
- * @param string $column child column (null for this attribute, * for this attribute and all childs)
- */
- public function addToListArrayHeader($action, &$arr, $fieldprefix, $flags, $atksearch, $columnConfig, atkDataGrid $grid = null, $column = '*')
- {
- if ($column != null && $column != '*') {
- throw new Exception("Invalid list column {$column} for " . get_class($this) . " " . $this->getOwnerInstance()->atkEntityType() . '::'
- . $this->fieldName());
- }
- if (!$this->hasFlag(AF_HIDE_LIST) && !($this->hasFlag(AF_HIDE_SELECT) && $action == "select")) {
- $key = $fieldprefix . $this->fieldName();
- $arr["heading"][$key]["title"] = $this->label();
- if ($grid->hasFlag(atkDataGrid::SORT) && !$this->hasFlag(AF_NO_SORT)) {
- $arr["heading"][$key]["order"] = $this->listHeaderSortOrder($columnConfig, $fieldprefix);
- }
- if ($grid->hasFlag(atkDataGrid::EXTENDED_SORT)) {
- $arr["sort"][$key] = $this->extendedSort($columnConfig, $fieldprefix, $grid);
- }
- if ($grid->hasFlag(atkDataGrid::SEARCH) && $this->hasFlag(AF_SEARCHABLE)) {
- $fn = $this->fieldName() . "_search";
- if (method_exists($this->m_ownerInstance, $fn)) {
- $arr["search"][$key] = $this->m_ownerInstance->$fn($atksearch, false, $fieldprefix, $grid);
- } else {
- $arr["search"][$key] = $this->search($atksearch, false, $fieldprefix, $grid);
- }
- $arr["search"][$key] .= $this->searchMode(false, $fieldprefix);
- }
- }
- }
- /**
- * Adds the attribute / field to the list row. And if the row is totalisable also to the total.
- *
- * Framework method. It should not be necessary to call this method directly.
- *
- * @param String $action the action that is being performed on the entity
- * @param array $arr reference to the the recordlist array
- * @param int $nr the current row number
- * @param String $fieldprefix the fieldprefix
- * @param int $flags the recordlist flags
- * @param boolean $edit editing?
- * @param atkDataGrid $grid data grid
- * @param string $column child column (null for this attribute, * for this attribute and all childs)
- */
- public function addToListArrayRow($action, &$arr, $nr, $fieldprefix, $flags, $edit = false, atkDataGrid $grid = null, $column = '*')
- {
- if ($column != null && $column != '*') {
- throw new Exception("Invalid list column {$column} for " . get_class($this) . " " . $this->getOwnerInstance()->atkEntityType() . '::'
- . $this->fieldName());
- }
- if (!$this->hasFlag(AF_HIDE_LIST) && !($this->hasFlag(AF_HIDE_SELECT) && $action == "select")) {
- if ($edit) {
- $arr["rows"][$nr]["data"][$fieldprefix . $this->fieldName()] = $this
- ->getEdit('list', $arr["rows"][$nr]["record"], 'atkdatagriddata_AE_' . $nr . '_AE_');
- } else {
- $arr["rows"][$nr]["data"][$fieldprefix . $this->fieldName()] = $this->getView('list', $arr["rows"][$nr]["record"]);
- }
- /* totalisable? */
- if ($this->hasFlag(AF_TOTAL)) {
- $sum = $this->sum($arr["totalraw"], $arr["rows"][$nr]["record"], $fieldprefix);
- $arr["totalraw"][$this->fieldName()] = $sum[$this->fieldName()];
- $arr["total"][$fieldprefix . $this->fieldName()] = $this->getView('list', $sum);
- }
- }
- }
- /**
- * Returns a piece of html code that can be used to get search terms input
- * from the user.
- *
- * The framework calls this method to display the searchbox
- * in the search bar of the recordlist, and to display a more extensive
- * search in the 'extended' search screen.
- * The regular atkAttributes returns a simple text input box for entering
- * a keyword to search for.
- * @todo find a better way to search on onetomanys that does not require
- * something evil in Adapto_Attribute
- * @param array $record Array with values
- * @param boolean $extended if set to false, a simple search input is
- * returned for use in the searchbar of the
- * recordlist. If set to true, a more extended
- * search may be returned for the 'extended'
- * search page. The Adapto_Attribute does not
- * make a difference for $extended is true, but
- * derived attributes may reimplement this.
- * @param string $fieldprefix The fieldprefix of this attribute's HTML element.
- *
- * @return String A piece of html-code
- */
- public function search($record = array(), $extended = false, $fieldprefix = "", atkDataGrid $grid = null)
- {
- $id = $this->getSearchFieldName($fieldprefix);
- $value = "";
- if (is_array($record) && isset($record[$this->fieldName()])) {
- $value = $record[$this->fieldName()];
- }
- $this->registerKeyListener($id, KB_CTRLCURSOR | KB_UPDOWN);
- $result = '<input type="text" id="' . $id . '" class="' . get_class($this) . '" name="' . $id . '" value="' . atk_htmlentities($value) . '"'
- . ($this->m_searchsize > 0 ? ' size="' . $this->m_searchsize . '"' : '') . ($this->m_maxsize > 0 ? ' maxlength="' . $this->m_maxsize . '"' : '')
- . '>';
- return $result;
- }
- /**
- * Returns piece of html which is used for setting/selecting the search
- * mode for this attribute.
- *
- * It will show a pulldown if using extended search and multiple
- * searchmodes are supported otherwise the default searchmode is selected.
- *
- * @param boolean $extended using extended search?
- * @param string $fieldprefix optional fieldprefix
- * @return string html which is used for selecting searchmode
- */
- public function searchMode($extended = false, $fieldprefix = '')
- {
- $searchModes = $this->getSearchModes();
- $dbSearchModes = $this->getDb()->getSearchModes();
- $searchModes = array_values(array_intersect($searchModes, $dbSearchModes));
- $searchMode = $this->getSearchMode($extended);
- // Set current searchmode to first searchmode if not searching in extended form or no searchmode is set
- if (!$extended || empty($searchMode) || !in_array($searchMode, $searchModes))
- $searchMode = $searchModes[0];
- if ($extended && count($searchModes) > 1) {
- $field = '<select name="' . $this->getSearchModeFieldname($fieldprefix) . '">';
- foreach ($searchModes as $value) {
- $selected = $searchMode == $value ? ' selected="selected"' : '';
- $field .= '<option value="' . $value . '"' . $selected . '>' . Adapto_htmlentities($this->text("search_" . $value)) . '</option>';
- }
- $field .= '</select>';
- } else {
- $field = '<input type="hidden" name="' . $this->getSearchModeFieldname($fieldprefix) . '" value="' . $searchMode . '">'
- . ($extended ? atktext("search_" . $searchMode) : '');
- }
- return $field;
- }
- /**
- * Retrieve the current set or default searchmode of this attribute
- *
- * @param boolean $extended Whether extended search is being used
- * @return String the default searchmode for this attribute.
- */
- function getSearchMode($extended = false)
- {
- $searchmode = $this->m_ownerInstance->getSearchMode();
- if (is_array($searchmode)) {
- return $searchmode[$this->fieldName()];
- }
- return $searchmode;
- }
- /**
- * Creates a smart search condition for a given search value, and adds it
- * to the query that will be used for performing the actual search.
- *
- * @param Integer $id The unique smart search criterium identifier.
- * @param Integer $nr The element number in the path.
- * @param Array $path The remaining attribute path.
- * @param atkQuery $query The query to which the condition will be added.
- * @param String $ownerAlias The owner table alias to use.
- * @param Mixed $value The value the user has entered in the searchbox.
- * @param String $mode The searchmode to use.
- */
- function smartSearchCondition($id, $nr, $path, &$query, $ownerAlias, $value, $mode)
- {
- // default implementation doesn't supported nested paths, this method
- // should be overriden by relations etc. if they want to support this
- if (count($path) > 0) {
- Adapto_var_dump($path, 'Invalid search path for ' . $this->m_ownerInstance->atkEntityType() . '#' . $this->fieldName() . ', ignoring criterium!');
- } else {
- $this->searchCondition($query, $ownerAlias, $value, $mode);
- }
- }
- /**
- * Creates a search condition for a given search value, and adds it to the
- * query that will be used for performing the actual search.
- *
- * @param atkQue…
Large files files are truncated, but you can click here to view the full file