/** * Get the columsn which can save for the specidied form * @param I2CE_Form $form * @returns array keys are the field names and values are the column names */ protected function getSaveColumns($form) { $formName = $form->getName(); if (array_key_exists($formName, $this->saveCols)) { return $this->saveCols[$formName]; } $table = $this->getTable($formName); if (!$table) { I2CE::raiseError("No table specified for {$form}"); $this->saveCols[$formName] = array(); return array(); } $writable = false; $options = $this->getStorageOptions($formName); $options->setIfIsSet($writable, 'writable'); if (!$writable) { I2CE::raiseError("Trying to save non-writable form"); $this->saveCols[$formName] = array(); return array(); } if (!$options instanceof I2CE_MagicDataNode) { I2CE::raiseError("Invalid storage options for {$formName}"); $this->saveCols[$formName] = array(); return array(); } $form_prepended = true; $options->setIfIsSet($form_prepended, 'id/form_prepended'); if ($form_prepended) { $this->saveCols[$formName] = array(); return array(); } $id_col = 'id'; if (!$options->setIfIsSet($id_col, 'id/col') || !$id_col) { if ($options->is_scalar('id/function') && $options->id->function) { //the id is being read in as a function. and the col is not overwritten //so cannot save to a function value $this->saveCols[$formName] = array(); return array(); } } $rows = $this->db->queryAll("SHOW FULL COLUMNS FROM {$table} WHERE Field='{$id_col}'"); if (!is_array($rows) || count($rows) != 1) { //the id column was not there $this->saveCols[$formName] = array(); return array(); } $cols['id'] = $id_col; $parent_col = false; $parent_enabled = true; $options->setIfIsSet($parent_enabled, "parent/enabled"); if ($parent_enabled) { if (!$options->setIfIsSet($parent_col, 'parent/col') || !$parent_col) { if ($options->is_scalar('parent/function') && $options->parent->function) { //the parent is being read in as a function. and the col is not overwritten //so cannot save to a function value //do nothing. can't save the parent id. } else { $cols['parent'] = $parent_col; } } else { $cols['parent'] = $parent_col; } } $fields = $form->getFieldNames(); foreach ($fields as $field) { $field_col = $field; $field_enabled = true; $options->setIfIsSet($field_enabled, "fields/{$field}/enabled"); if ($field_enabled) { if (!$options->setIfIsSet($field_col, "fields/{$field}/col") || !$field_col) { if ($options->is_scalar("fields/{$field}/function") && $options->fields->{$field}->function) { //the parent is being read in as a function. and the col is not overwritten //so cannot save to a function value //do nothing. can't save the parent id. } else { $cols[$field] = $field_col; } } else { $cols[$field] = $field_col; } } //now we need to make sure that the col is "atomic" $rows = $this->db->queryAll("SHOW FULL COLUMNS FROM {$table} WHERE Field='{$cols[$field]}'"); if (!is_array($rows) || count($rows) != 1) { //the column was not there unset($cols[$field]); } $row = current($rows); if ($row->null == 'NO' && !$row->default) { //it is not allowed to be null and there is no default value set. non-atomic unset($cols[$field]); } } $this->saveCols[$formName] = $cols; return $cols; }
/** * Checks a limit boolean expression for a field based on limit data * @param I2CE_Form $formObj * @param mixed $limit_data * array. * @param callback $field_refernece_callback. A callback function whose first arguement is the form, the second arguements * is the field and which returns the way the field value should be references as a field. If the callback is null (the default) then * the reference used is $data["$field'] * @returns string or false on failure */ public function createCheckLimitString($formObj, $limit_data = array(), $field_reference_callback = null) { if (!is_array($limit_data)) { I2CE::raiseError("Expected array for generating where sub-expression, but not received"); return false; } if (!array_key_exists('field', $limit_data) || !is_string($limit_data['field'])) { I2CE::raiseError("Field name is not given at 'field' "); return false; } if (!($fieldObj = $formObj->getField($limit_data['field'])) instanceof I2CE_FormField) { I2CE::raiseError("Field named {$limit_data['field']} is not a field of " . $formObj->getName() . "\nValid fields are:\n\t" . implode(",", $formObj->getFieldNames())); return false; } if (!array_key_exists('style', $limit_data) || !is_string($limit_data['style'])) { I2CE::raiseError("Style is not given at 'style' "); return false; } if (!array_key_exists('data', $limit_data) || !is_array($limit_data['data'])) { $limit_data['data'] = array(); } $method = 'checkLimitString_' . $limit_data['style']; if (!$fieldObj->_hasMethod($method)) { I2CE::raiseError("Not able to check limit (via {$method}) for style " . $limit_data['style'] . " for class " . get_class($fieldObj)); return false; } if ($field_reference_callback !== null) { if (!is_string($ref = call_user_func($field_reference_callback, $formObj->getName(), $field)) === false) { I2CE::raiseError("Invalid field reference callback function"); return false; } } else { $ref = '$data[\'' . $limit_data['field'] . '\']'; } $ret = $fieldObj->{$method}($limit_data['data'], $ref); if (is_string($ret)) { return $ret; } else { I2CE::raiseError("Unexpected return from limit {$style}"); return false; } }