_ci =& get_instance(); } // ------------------------------------------------------------------------------------------------- // Public methods /** * UDFWidget */ public function UDFWidget($args, $htmlArgs = array()) { if ((isset($args[self::SCHEMA_ARG_NAME]) && !isEmptyString($args[self::SCHEMA_ARG_NAME])) && (isset($args[self::TABLE_ARG_NAME]) && !isEmptyString($args[self::TABLE_ARG_NAME]))) { // Loads the widget library $this->_ci->load->library('WidgetLib'); // Loads widgets to render HTML for UDF loadResource(APPPATH.'widgets/udf'); // Default external block is true if (!isset($args[self::FIELD_ARG_NAME]) && !isset($htmlArgs[HTMLWidget::EXTERNAL_BLOCK])) { $htmlArgs[HTMLWidget::EXTERNAL_BLOCK] = true; } return $this->_ci->widgetlib->widget( self::WIDGET_NAME, $args, $htmlArgs ); } else { if (!isset($args[self::SCHEMA_ARG_NAME]) || isEmptyString($args[self::SCHEMA_ARG_NAME])) { show_error(self::SCHEMA_ARG_NAME.' parameter is missing!'); } if (!isset($args[self::TABLE_ARG_NAME]) || isEmptyString($args[self::TABLE_ARG_NAME])) { show_error(self::TABLE_ARG_NAME.' parameter is missing!'); } } } /** * It renders the HTML of the UDF * * NOTE: When this method is called $widgetData contains different data from * parameter $args in the constructor */ public function displayUDFWidget(&$widgetData) { $schema = $widgetData[self::SCHEMA_ARG_NAME]; // schema attribute $table = $widgetData[self::TABLE_ARG_NAME]; // table attribute if (isset($widgetData[self::FIELD_ARG_NAME])) { $field = $widgetData[self::FIELD_ARG_NAME]; // UDF name } $udfResults = $this->_loadUDF($schema, $table); // loads UDF definition if (hasData($udfResults)) { $udf = $udfResults->retval[0]; // only one record is loaded if (isset($udf->jsons)) { $jsonSchemas = json_decode($udf->jsons); // decode the json schema if (is_object($jsonSchemas) || is_array($jsonSchemas)) { // $this->_printStartUDFBlock($widgetData); // If the schema is an object then convert it into an array if (is_object($jsonSchemas)) { $jsonSchemasArray = array($jsonSchemas); } else // keep it as it is { $jsonSchemasArray = $jsonSchemas; } $found = false; // used to check if the field is found or not in the json schema $this->_sortJsonSchemas($jsonSchemasArray); // Sort the list of UDF by sort property // Loops through json schemas foreach ($jsonSchemasArray as $jsonSchema) { // If the type property is not present then show an error if (!isset($jsonSchema->{self::TYPE})) { show_error(sprintf('%s.%s: Attribute "type" not present in the json schema', $schema, $table)); } // If the name property is not present then show an error if (!isset($jsonSchema->{self::NAME})) { show_error(sprintf('%s.%s: Attribute "name" not present in the json schema', $schema, $table)); } // If a UDF is specified and is present in the json schemas list or no UDF is specified if ((isset($field) && $field == $jsonSchema->{self::NAME}) || !isset($field)) { // Set attributes using phrases $this->_setAttributesWithPhrases($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); // Set validation attributes $this->_setValidationAttributes($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); // Set name and id attributes $this->_setNameAndId($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); // Render the HTML for this UDF $this->_render($jsonSchema, $widgetData); // If a UDf is specified and it was found then stop looking through this list if (isset($field) && $field == $jsonSchema->{self::NAME}) { $found = true; break; } } } // If a UDf is specified and it was not found then show an error if (isset($field) && !$found) { show_error(sprintf('%s.%s: No schema present for field: %s', $schema, $table, $field)); } // $this->_printEndUDFBlock(); } else // not a valid schema { show_error(sprintf('%s.%s: Not a valid json schema', $schema, $table)); } } else // no json column present in table tbl_udf { show_error(sprintf('%s.%s: Does not contain "jsons" field', $schema, $table)); } } } /** * Manage UDFs */ public function manageUDFs(&$data, $schemaAndTable, $udfValues = null) { $validate = success(true); // returned value // Contains a list of validation errors for the UDFs that have not passed the validation $notValidUDFsArray = array(); $this->_ci->load->model('system/UDF_model', 'UDFModel'); // Retrieves UDFs definitions for this table $resultUDFsDefinitions = $this->_ci->UDFModel->getUDFsDefinitions($schemaAndTable); if (hasData($resultUDFsDefinitions)) // standard check if everything is ok and data are present { // Get udf values from $data & clean udf values from $data // NOTE: Must be performed here because the load method populates the property UDFs too $udfsParameters = $this->_popUDFParameters($data); $requiredUDFsArray = array(); // contains a list of required UDFs // Contains the UDFs values to be stored // NOTE: the UDFs supplied that are not present in the UDF definition of this table, will be discarded $toBeStoredUDFsArray = array(); // Decodes json that define the UDFs for this table $decodedUDFDefinitions = json_decode( $resultUDFsDefinitions->retval[0]->{self::COLUMN_JSON_DESCRIPTION} ); // Loops through the UDFs definitions for ($i = 0; $i < count($decodedUDFDefinitions); $i++) { $decodedUDFDefinition = $decodedUDFDefinitions[$i]; // Definition of a single UDF // Loops through the UDFs values that should be stored foreach ($udfsParameters as $key => $val) { $tmpValidate = success(true); // temporary variable used to store the returned value from _validateUDFs // If this is the definition of this UDF if ($decodedUDFDefinition->{self::NAME} == $key) { if (isset($decodedUDFDefinition->{self::VALIDATION})) // If validation rules are present for this UDF { // Checks if the given UDF is required and the result will be stored in $chkRequiredPassed // If $chkRequiredPassed == true => required check passed // If $chkRequiredPassed == false => required check NOT passed $chkRequiredPassed = true; // If required property is present in the UDF description and it is true if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === true) { // If this UDF is a checkbox and the given value is false // OR // if this UD7F is NOT a checkbox and the given value is null if (($decodedUDFDefinition->{self::TYPE} == self::CHKBOX_TYPE && $val === false) || ($decodedUDFDefinition->{self::TYPE} != self::CHKBOX_TYPE && $val == null)) { $chkRequiredPassed = false; // not passed // A new error is generated and added to array $requiredUDFsArray $requiredUDFsArray[$decodedUDFDefinition->{self::NAME}] = error( $decodedUDFDefinition->{self::NAME}, EXIT_VALIDATION_UDF_REQUIRED ); } } // If the previous required check has failed then the validation is not performed if ($chkRequiredPassed === true) { // Checks if the validation should be performed // If $toBeValidated == true => validation is performed // If $toBeValidated == false => validation is NOT performed $toBeValidated = false; // If this UDF is NOT a checkbox if ($decodedUDFDefinition->{self::TYPE} != self::CHKBOX_TYPE) { // If required property is NOT present in the UDF description if (!isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED})) { $toBeValidated = true; } // If required property is present in the UDF description and it is true if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === true) { $toBeValidated = true; } // If required property is present in the UDF description and it is true and the given value is null if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === false && $val != null) { $toBeValidated = true; } } if ($toBeValidated === true) // Checks if validation should be performed { $tmpValidate = $this->_validateUDFs( $decodedUDFDefinition->{self::VALIDATION}, $decodedUDFDefinition->{self::NAME}, $val ); } } } // If validation is ok copy the value that is to be stored into $toBeStoredUDFsArray if (isSuccess($tmpValidate)) { $toBeStoredUDFsArray[$key] = $val; } else // otherwise store the validation error in $notValidUDFsArray { $notValidUDFsArray[] = $tmpValidate; } } } } // Copies the remaining required UDFs into $notValidUDFsArray // because they were not supplied, therefore must be notified as error foreach ($requiredUDFsArray as $key => $val) { $notValidUDFsArray[] = array($val); } // If the validation of all the supplied UDFs is ok if (count($notValidUDFsArray) == 0) { // An update is performed, then in this case it preserves the values // of the UDF that are not updated if (is_array($udfValues) && count($udfValues) > 0) { foreach ($udfValues as $fieldName => $fieldValue) { // If this field is not present in the given parameters // then copy it from the DB without changes if (!array_key_exists($fieldName, $toBeStoredUDFsArray)) { $toBeStoredUDFsArray[$fieldName] = $fieldValue; } } } $encodedToBeStoredUDFs = json_encode($toBeStoredUDFsArray); // encode to json if ($encodedToBeStoredUDFs !== false) // if encode was ok { // Save the supplied UDFs values $data[self::COLUMN_NAME] = $encodedToBeStoredUDFs; } } else // otherwise the returning value will be the list of UDFs validation errors { $validate = error($notValidUDFsArray, EXIT_VALIDATION_UDF); } } return $validate; } /** * isUDFColumn */ public function isUDFColumn($columnName, $columnType) { $isUDFColumn = false; if (substr($columnName, 0, strlen(self::COLUMN_PREFIX)) == self::COLUMN_PREFIX && $columnType == self::COLUMN_TYPE) { $isUDFColumn = true; } return $isUDFColumn; } /** * Set the _udfUniqueId property */ public function setUDFUniqueId($udfUniqueId) { $this->_udfUniqueId = $udfUniqueId; } /** * Return an unique string that identify this UDF widget * NOTE: The default value is the URI where the FilterWidget is called * If the fhc_controller_id is present then is also used */ public function setUDFUniqueIdByParams($params) { if ($params != null && is_array($params) && isset($params[self::UDF_UNIQUE_ID]) && !isEmptyString($params[self::UDF_UNIQUE_ID])) { $udfUniqueId = $this->_ci->router->directory.$this->_ci->router->class.'/'. $this->_ci->router->method.'/'. $params[self::UDF_UNIQUE_ID]; $this->setUDFUniqueId($udfUniqueId); } } /** * Wrapper method to the session helper funtions to retrieve the whole session for this UDF widget */ public function getSession() { return getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); } /** * Wrapper method to the session helper funtions to retrieve one element from the session of this UDF widget */ public function getSessionElement($name) { $session = getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); if (isset($session[$name])) { return $session[$name]; } return null; } /** * Wrapper method to the session helper funtions to set the whole session for this UDF widget */ public function setSession($data) { setSessionElement(self::SESSION_NAME, $this->_udfUniqueId, $data); } /** * Wrapper method to the session helper funtions to set one element in the session for this UDF widget */ public function setSessionElement($name, $value) { $session = getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); $session[$name] = $value; setSessionElement(self::SESSION_NAME, $this->_udfUniqueId, $session); // stores the single value } /** * Save UDFs */ public function saveUDFs($udfUniqueId, $udfs) { // Read the all session for this udf widget $session = $this->getSession(); // If session is empty then return an error if ($session == null) return error('No UDFWidget loaded'); // Workaround to load CI $this->_ci->load->model('system/UDF_model', 'UDFModel'); // Initialize a new DB_Model $dbModel = new DB_Model(); // Setup the new dbModel object with... $dbModel->setup( $session[self::SCHEMA_ARG_NAME], // ... schema... $session[self::TABLE_ARG_NAME], // ...table... $session[self::PRIMARY_KEY_NAME] // ...and primary key name ); // Returns the result of the database update operation to save UDFs return $dbModel->update( array($session[self::PRIMARY_KEY_NAME] => $session[self::PRIMARY_KEY_VALUE]), (array)$udfs ); } /** * Checks if at least one of the permissions given as parameter (requiredPermissions) belongs * to the authenticated user, if confirmed then is allowed to use this UDFWidget. * If the parameter requiredPermissions is NOT given or is not present in the session, * then NO one is allow to use this UDFWidget * Wrapper method to permissionlib->hasAtLeastOne */ public function isAllowed($requiredPermissions = null) { $this->_ci->load->library('PermissionLib'); // Load permission library // Gets the required permissions from the session if they are not provided as parameter $rq = $requiredPermissions; if ($rq == null) $rq = $this->getSessionElement(self::REQUIRED_PERMISSIONS_PARAMETER); return $this->_ci->permissionlib->hasAtLeastOne($rq, self::PERMISSION_TABLE_METHOD, self::PERMISSION_TYPE); } // ------------------------------------------------------------------------------------------------- // Private methods /** * Print the block for UDFs */ private function _printStartUDFBlock($widgetData) { $startBlock = '