function test_values() { $record = new Dataface_Record('Profiles', array()); $io = new Dataface_IO('Profiles'); $io->read(array('id' => 10), $record); $this->assertEquals('10', $record->val('id')); $rr = new Dataface_RelatedRecord($record, 'appointments'); $this->assertEquals(10, $rr->val('profileid')); $this->assertEquals(10, $rr->getValue('profileid')); }
/** * Adds a value to a valuelist. This only works for valuelists * that are pulled from the database. * @param Dataface_Table The table to add the valuelist to. * @param string $valuelistName The name of the valuelist. * @param string $value The value to add. * @param string $key The key to add. * @param boolean $checkPerms If true, this will first check permissions * before adding the value. * @returns mixed May return a permission denied error if there is insufficient * permissions. */ function addValueToValuelist(&$table, $valuelistName, $value, $key = null, $checkPerms = false) { import('Dataface/ConfigTool.php'); $configTool =& Dataface_ConfigTool::getInstance(); $conf = $configTool->loadConfig('valuelists', $table->tablename); $relname = $valuelistName . '__valuelist'; //$conf = array($relname=>$conf); $table->addRelationship($relname, $conf[$valuelistName]); $rel =& $table->getRelationship($relname); $fields =& $rel->fields(); if (count($fields) > 1) { $valfield = $fields[1]; $keyfield = $fields[0]; } else { $valfield = $fields[0]; $keyfield = $fields[0]; } $record = new Dataface_Record($table->tablename); $rrecord = new Dataface_RelatedRecord($record, $relname); if ($checkPerms and !$rrecord->checkPermission('edit', array('field' => $valfield))) { return Dataface_Error::permissionDenied(); } $rrecord->setValue($valfield, $value); if (isset($key) and isset($keyfield)) { if ($checkPerms and !$rrecord->checkPermission('edit', array('field' => $keyfield))) { return Dataface_Error::permissionDenied(); } $rrecord->setValue($keyfield, $key); } import('Dataface/IO.php'); $io = new Dataface_IO($table->tablename); $res = $io->addRelatedRecord($rrecord); if (PEAR::isError($res)) { return $res; } return array('key' => $rrecord->val($keyfield), 'value' => $rrecord->val($valfield)); }
/** * @brief Adds as related record's permissions as a permissions mask for * its destination records. Any call to getPermissions() on the destination * records will now have their permissions augmented by the relationship * permissions defined in the context record. * * @since 2.0 * @param Dataface_RelatedRecord $contextRecord The context record to provide permissions * for its destination records. * @returns void * @see removeContextMask() * @see getContextMasks() * @see getContextMask() * @see getPortalRecordPermissions() * @see getPortalFieldPermissions() */ function addContextMask(Dataface_RelatedRecord $contextRecord) { $app = Dataface_Application::getInstance(); if (!isset($this->contextMasks)) { $this->contextMasks = array(); } $parentPerms = $contextRecord->getParent()->getPermissions(array('relationship' => $contextRecord->_relationshipName)); $perms = array(); if (@$parentPerms['add new related record'] or @$parentPerms['add existing related record']) { $perms['new'] = 1; } if (@$parentPerms['delete related record']) { $perms['delete'] = 1; } else { if (isset($parentPerms['delete related record']) and !@$parentPerms['delete related record']) { $perms['delete'] = 0; } } if (@$parentPerms['edit related records']) { $perms['edit'] = 1; } else { if (isset($parentPerms['edit related records']) and !@$parentPerms['edit related records']) { $perms['edit'] = 0; } } if (@$parentPerms['view related records override']) { $perms['view'] = 1; } else { if (isset($parentPerms['view related records override']) and !@$parentPerms['view related records override']) { $perms['view'] = 0; } } if (@$parentPerms['find related records']) { $perms['find'] = 1; } else { if (isset($parentPerms['find related records']) and !@$parentPerms['find related records']) { $perms['find'] = 0; } } if (@$parentPerms['link related records']) { $perms['link'] = 1; } else { if (isset($parentPerms['link related records']) and !@$parentPerms['link related records']) { $perms['link'] = 0; } } $recordPerms = $perms; unset($perms); $domainTable = $contextRecord->_relationship->getDomainTable(); $destRecords = $contextRecord->toRecords(); $numDest = count($destRecords); $destRecordIndex = array(); $destRecordIds = array(); foreach ($destRecords as $destRecord) { $destRecordIndex[$destRecord->table()->tablename] = $destRecord; $id = $destRecord->getId(); $destRecordIds[$destRecord->table()->tablename] = $id; $this->contextMasks[$id] = $recordPerms; if ($numDest > 1) { // This is a many-to-many relationship if (strcmp($destRecord->table()->tablename, $domainTable) === 0) { // For many-to-many relationships // we don't want the user to be able to edit // the domain table. if (!@$parentPerms['add new related record']) { unset($this->contextMasks[$id]['new']); } unset($this->contextMasks[$id]['edit']); unset($this->contextMasks[$id]['link']); } else { // This is a join table if (@$parentPerms['remove related record']) { $this->contextMasks[$id]['delete'] = 1; } else { if (isset($parentPerms['remove related record']) and !@$parentPerms['remove related record']) { $this->contextMasks[$id]['delete'] = 0; } } } } } $relationship = $contextRecord->_relationship; $fields = $relationship->fields(true, true); $constrainedFields = array_flip($contextRecord->getConstrainedFields()); foreach ($fields as $field) { $fieldTable = $relationship->getTable($field); $fieldTableName = $fieldTable->tablename; $rec = $destRecordIndex[$fieldTableName]; $perms = null; if (strpos($field, '.') !== false) { list($junk, $fieldname) = explode('.', $field); } else { $fieldname = $field; } $perms = $rec->getPermissions(array('field' => $fieldname, 'nobubble' => 1)); if (!$perms) { $perms = array(); } $rfperms = $contextRecord->getParent()->getPermissions(array('relationship' => $contextRecord->_relationshipName, 'field' => $fieldname, 'nobubble' => 1)); //echo "RFPerms: ";print_r($rfperms); if ($rfperms) { foreach ($rfperms as $k => $v) { $perms[$k] = $v; } } if (isset($constrainedFields[$fieldTableName . '.' . $fieldname])) { $perms['edit'] = 0; } $id = $destRecordIds[$fieldTableName]; $this->contextMasks[$id . '#' . $fieldname] = $perms; unset($perms); } $this->_cache = array(); // Clear the cache because // the presence of this mask will // alter the result of permissions queries }
function id2record($idstring) { $pairs = explode('&', $idstring); foreach ($pairs as $pair) { list($attname, $attval) = explode('=', $pair); $attname = urldecode($attname); $attval = urldecode($attval); $colVals[$attname] = $attval; } $rrecord = new Dataface_RelatedRecord($this->record, $this->relationship->_name); $rrecord->setValues($colVals); return $rrecord; }
function ¤t() { $rec = new Dataface_RelatedRecord($this->_record, $this->_relationshipName, $this->_records[current($this->_keys)]); $rec->setValues($this->_record->_relatedMetaValues[$this->_relationshipName][$this->_where][$this->_sort][current($this->_keys)]); return $rec; }
function &buildWidget(&$record, &$field, &$form, $formFieldName, $new = false) { /* * * This field uses a table widget. * */ //$field['display'] = 'block'; $table =& $record->_table; $formTool =& Dataface_FormTool::getInstance(); $factory =& Dataface_FormTool::factory(); $widget =& $field['widget']; $el =& $factory->addElement('grid', $formFieldName, $widget['label']); $el->setProperties($widget); $rperms = $record->getPermissions(array('relationship' => $field['relationship'])); if (!$record->checkPermission('add new related record', array('relationship' => $field['relationship']))) { //echo "No add new ".$record->_table->tablename; $el->addNew = false; } if (!$record->checkPermission('add existing related record', array('relationship' => $field['relationship']))) { //echo "No add new ".$record->_table->tablename; $el->addExisting = false; } if (isset($field['relationship'])) { $relationship =& $table->getRelationship($field['relationship']); if (!$record->checkPermission('remove related record', array('relationship' => $field['relationship']))) { $el->delete = false; } else { if ($relationship->isOneToMany() and isset($rperms['delete related record']) and !@$rperms['delete related record']) { $el->delete = false; } } if (!$relationship->supportsRemove()) { $el->delete = false; } if (!$relationship->supportsAddNew()) { $el->addNew = false; } if (!$relationship->supportsAddExisting()) { $el->addExisting = false; } else { $el->addExistingFilters = $relationship->getAddExistingFilters(); } $el->table = $relationship->getDomainTable(); if (isset($widget['columns'])) { $columns = array_map('trim', explode(',', $widget['columns'])); } else { $columns = $relationship->_schema['short_columns']; } $count = 0; $subfactory = new HTML_QuickForm(); $dummyRelatedRecord = new Dataface_RelatedRecord($record, $relationship->getName()); //print_r($dummyRelatedRecord->getPermissions()); $orderCol = $relationship->getOrderColumn(); if (!$orderCol or PEAR::isError($orderCol)) { $el->reorder = false; } foreach ($columns as $column) { $colTable =& $relationship->getTable($column); if (!$colTable) { echo "Could not find table for column {$column}"; } $colPerms = $dummyRelatedRecord->getPermissions(array('field' => $column)); if (!@$colPerms['view']) { unset($colTable); unset($dummyRecord); continue; } // We need to be a bit more refined on this one. We need to take // into account the context being that we are in a relationship. $dummyRecord = new Dataface_Record($colTable->tablename, $record->vals()); /* if ( !$dummyRecord->checkPermission('view', array('field'=>$column, 'recordmask'=>array('view'=>1))) ) { unset($colTable); unset($dummyRecord); continue; } */ $colFieldDef =& $colTable->getField($column); $columnElement =& $formTool->buildWidget($dummyRecord, $colFieldDef, $subfactory, $column, false); $defaultValue = $colTable->getDefaultValue($column); $columnElement->setValue($defaultValue); $el->defaults[$column] = $defaultValue; $el->addField($colFieldDef, $columnElement, $colPerms); unset($columnElement); unset($colFieldDef); unset($dummyRecord); unset($colTable); unset($elementFilter); } } else { if (isset($widget['fields'])) { $widget_fields =& $widget['fields']; foreach ($widget_fields as $widget_field) { $widget_field =& Dataface_Table::getTableField($widget_field, $this->db); if (PEAR::isError($widget_field)) { return $widget_field; } $widget_widget = $formTool->buildWidget($record, $widget_field, $factory, $widget_field['name']); $defaultValue = $table->getDefaultValue($widget_field['name']); $widget_widget->setValue($defaultValue); $el->addField($widget_widget); $el->defaults[$widget_field['name']] = $defaultValue; } } else { if (isset($field['fields'])) { foreach (array_keys($field['fields']) as $field_key) { $widget_widget = $formTool->buildWidget($record, $field['fields'][$field_key], $factory, $field['fields'][$field_key]['name']); $defaultValue = $table->getDefaultValue($widget_field['name']); $widget_widget->setValue($defaultValue); $el->defaults[$widget_field['name']] = $defaultValue; $el->addField($widget_widget); unset($widget_widget); } } } } return $el; }
/** * * Saves the related record. * * @param values Associative array of values received from the submitted form. * */ function save($values) { import('Dataface/LinkTool.php'); $colVals = array(); /* * In case some values were not submitted, we will use the defaults (as specified in the relationships.ini * file for this relationship to fill in the blanks. */ if (isset($this->_relationship->_schema['new'])) { foreach ($this->_relationship->_schema['new'] as $key => $value) { if (!isset($values[$key])) { $values[$key] = $value; } } } $io = new Dataface_IO($values['-table']); // for writing the related record $record = new Dataface_Record($values['-table'], array()); // The parent record... not the record being inserted. $io->read($values['__keys__'], $record); // We submitted the keys to the parent record in the form // so that we can load the parent record of this related record. // convert groups foreach (array_keys($values) as $key) { if (isset($this->_groups[$key])) { foreach ($values[$key] as $fieldkey => $fieldval) { $values[$fieldkey] = $fieldval; } unset($values[$key]); } } foreach ($values as $key => $value) { // We will go through each submitted value from the form and try // to figure out how it should be stored. if (strpos($key, '-') === 0) { continue; } if ($key == "-Save") { continue; } // We don't parse the "Save" button $fullPath = $this->_relationshipName . '.' . $key; // The full path to the field can be used to obtain information // about the field from the parent table, since most methods // in the table class will take field names of the form // <relationship name>.<fieldname> if (!$this->_parentTable->exists($fullPath)) { /* * If the field in question does not exist then we just skip it. * Perhaps we should throw an error?!! * */ //echo $fullPath.' does not exist in table '.$this->_parentTable->tablename; continue; } // At this point we know that the field exists so lets obtain references // to the useful components for us to work with this field. if (isset($field)) { unset($field); } $field =& $this->_parentTable->getField($fullPath); // Field array with data about the field. if (PEAR::isError($field)) { throw new Exception("Error obtaining field '{$fullPath}' while saving related record.", E_USER_ERROR); } $abs_fieldName = $this->_parentTable->absoluteFieldName($key, $this->_relationship->_schema['selected_tables']); // The absolute fieldname of this field. e.g., of the form <Tablename>.<Fieldname> if (PEAR::isError($abs_fieldName)) { throw new Exception("Error trying to obtain absolute field name for the related field: '{$fullPath}'", E_USER_ERROR); } list($tablename, $fieldname) = explode('.', $abs_fieldName); if (isset($table)) { unset($table); } $table =& Dataface_Table::loadTable($tablename); // Reference to the table object where this field resides if (isset($quickForm)) { unset($quickForm); } $quickForm =& $this->_quickForms[$tablename]; // QuickForm object for this field's table. $el = $this->getElement($key); $metaValues = array(); // The $metaValues array will store the meta values associated with // the current field. A meta value is an associated value that // should be stored in another field. For example the mimetype // is a metavalue for a file upload field. The $metaValues array // be of the form [Column Name] -> [Column Value]. // Get the absolute field name of the field. An absolute field name is // of the form <Tablename>.<Fieldname> $tempVal = $quickForm->pushValue($fieldname, $metaValues, $el); //$serializedValue; // $tempVal will contain the value as submitted by the form.. ready // to be added to a record. // The QuickForm element. // !!! Just changed arg from $abs_fieldName to $fullPath to fix errors... but still don't // !!! fully understand what was going on - or why it was working before!?!?! if ($this->_parentTable->isMetaField($fullPath)) { // If this is a meta field, we don't insert it on its own... // we will wait until its value is supplied by its described // field. unset($tempVal); unset($el); continue; } foreach ($metaValues as $metaKey => $metaValue) { // Set the meta values $colVals[$tablename . '.' . $metaKey] = $metaValue; } $colVals[$abs_fieldName] = $tempVal; // Add the value to the array to be saved in the RelatedRecord // object. // Note that right now, Dataface_RelatedRecord will just ignore // the part of the field name before the period, but in the future, // this extra information may be used to allow multiple fields // with the same name from different tables in a single relationship. unset($tempVal); } //$queryBuilder = new Dataface_QueryBuilder($this->_parentTable->tablename); $relatedRecord = new Dataface_RelatedRecord($record, $this->_relationshipName, array()); $relatedRecord->setValues($colVals); $res = $io->addRelatedRecord($relatedRecord, true); if (PEAR::isError($res)) { return $res; } //$res = $io->performSQL($sql); return $res; }
/** * Returns a record or record value given it's unique URI. * @param string $uri The URI of the data we wish to retrieve. * The URI must be of one of the following forms: * tablename?key1=val1&keyn=valn#fieldname * tablename?key1=val1&keyn=valn * tablename/relationshipname?key1=val1&keyn=valn&relationshipname::relatedkey=relatedval#fieldname * tablename/relationshipname?key1=val1&keyn=valn&relationshipname::relatedkey=relatedval * * Where url encoding is used as in normal HTTP urls. If a field is specified (after the '#') * * @param string $filter The name of a filter to pass the data through. This * is only applicable when a field name is specified. Possible filters * include: * strval - Returns the string value of the field. (aka stringValue, getValueAsString) * display - Returns the display value of the field. (This substitutes valuelist values) * htmlValue - Returns the html value of the field. * preview - Returns the preview value of the field (usually this limits * the length of the output and strips any HTML. * * @returns mixed Either a Dataface_Record object, a Dataface_RelatedRecord object * of a value as stored in the object. The output depends on * the input. If it receives invalid input, it will return a PEAR_Error * object. * * Example usage: * * <code> * // Get record from Users table with UserID=10 * $user =& Dataface_IO::getByID('Users?UserID=10'); * // Dataface_Record object * * // get birthdate of user with UserID=10 * $birthdate =& Dataface_IO::getByID('Users?UserID=10#birthdate'); * // array('year'=>'1978','month'=>'12','day'=>'27', ...) * * // get related record from jobs relationship of user with UserID=10 * // where the jobtitle is "cook" * $job =& Dataface_IO::getByID('Users?UserID=10&jobs::jobtitle=cook"); * // Dataface_RelatedRecord object * * // Get the employers name of the cook job * $employername = Dataface_IO::getByID('Users?UserID=10&jobs::jobtitle=cook#employername'); * // String * * // Add filter, so we get the HTML value of the bio field rather than just * // the raw value. * $bio = Dataface_IO::getByID('Users?UserID=10#bio', 'htmlValue'); * * </code> */ static function &getByID($uri, $filter = null) { if (strpos($uri, '?') === false) { return PEAR::raiseError("Invalid record id: " . $uri); } $uri_parts = df_parse_uri($uri); if (PEAR::isError($uri_parts)) { return $uri_parts; } if (!isset($uri_parts['relationship'])) { // This is just requesting a normal record. // Check to see if this is to be a new record or an existing record if (@$uri_parts['action'] and $uri_parts['action'] == 'new') { $record = new Dataface_Record($uri_parts['table'], array()); $record->setValues($uri_parts['query']); return $record; } foreach ($uri_parts['query'] as $ukey => $uval) { if ($uval and $uval[0] != '=') { $uval = '=' . $uval; } $uri_parts['query'][$ukey] = $uval; } // At this point we are sure that this is requesting an existing record $record =& df_get_record($uri_parts['table'], $uri_parts['query']); if (isset($uri_parts['field'])) { if (isset($filter) and method_exists($record, $filter)) { $val =& $record->{$filter}($uri_parts['field']); return $val; } else { $val =& $record->val($uri_parts['field']); return $val; } } else { return $record; } } else { // This is requesting a related record. $record =& df_get_record($uri_parts['table'], $uri_parts['query']); if (!$record) { return PEAR::raiseError("Could not find any records matching the query"); } // Check to see if we are creating a new record if (@$uri_parts['action'] and $uri_parts['action'] == 'new') { $related_record = new Dataface_RelatedRecord($record, $uri_parts['relationship']); $related_record->setValues($uri_parts['query']); return $related_record; } // At this point we can be sure that we are requesting an existing record. $related_records =& $record->getRelatedRecordObjects($uri_parts['relationship'], 0, 1, $uri_parts['related_where']); if (count($related_records) == 0) { return PEAR::raiseError("Could not find any related records matching the query: " . $uri_parts['related_where']); } if (isset($uri_parts['field'])) { if (isset($filter) and method_exists($related_records[0], $filter)) { $val =& $related_records[0]->{$filter}($uri_parts['field']); return $val; } else { $val =& $related_records[0]->val($uri_parts['field']); return $val; } } else { return $related_records[0]; } } }
function commit(&$grid) { $columnnames = array_keys($grid->columns); if ($this->recordid == '__new__') { // this is a new record - so we must create a new one. $parentObj =& $grid->getParentObject(); if (is_a($parentObj, 'Dataface_Table')) { $record = new Dataface_Record($parentObj->tablename, array()); } else { $record = new Dataface_RelatedRecord($parentObj, $grid->relationship, array()); } } else { $record =& df_get_record_by_id($this->recordid); } $rowdata =& $grid->data[$this->rowid]; $savedata = array(); foreach ($this->params['cells'] as $key) { $savedata[$key] = $rowdata[$key]; } $record->setValues($savedata); if ($this->recordid == '__new__' and is_a($record, 'Dataface_RelatedRecord')) { import('Dataface/IO.php'); $io = new Dataface_IO($parentObj->_table->tablename); $io->addRelatedRecord($record); } else { $record->save(); } }
/** * Returns the subrows rooted at $rowid (not including $rowid's row) as html * <tr> tags. * @param string $rowid The id of the row whose subrowse we wish to retrieve. * @param integer $depth How far down the tree do we want to go. * @return string HTML for the subrows. */ function getSubrowsAsHTML($rowid, $depth = 3, $treetableid = 'treetable') { if (isset($this->relationship)) { $rel =& $this->record->_table->getRelationship($this->relationship); $table = $rel->getDomainTable(); if (PEAR::isError($table)) { $destTables =& $rel->getDestinationTables(); $table = $destTables[0]->tablename; } } else { $table = $this->record->_table->tablename; $rel =& $this->record->_table->getChildrenRelationship(); } $default_order_column = $rel->getOrderColumn(); $resultList = new Dataface_ResultList($table); $columns = $resultList->_columns; $rows = array(); $null = null; $this->getSubrows($rows, $rowid, $null, $depth); ob_start(); foreach (array_keys($rows) as $curr_rowid) { $path = explode('-', $curr_rowid); $level = count($path); $class = $rows[$curr_rowid]['hasChildren'] ? 'folder' : 'doc'; echo "<tr id=\"" . df_escape($curr_rowid) . "\">"; /* $keyString = implode('-',$rows[$curr_rowid]['record']->getValuesAsStrings( array_keys($rows[$curr_rowid]['record']->_table->keys()) ) );*/ $relatedRecord = new Dataface_RelatedRecord($this->record, $this->relationship, $rows[$curr_rowid]['record']->vals()); $keyString = $relatedRecord->getId(); echo "<td class=\"\"><input id=\"remove_" . df_escape($keyString) . "_checkbox\" type=\"checkbox\" name=\"--remkeys[]\" value=\"" . df_escape($keyString) . "\"/></td>"; echo "\n\t\t\t\t<td><div class=\"tier{$level}\"><a href=\"#\" "; if ($class == 'folder') { echo "onclick=\"TreeTable.prototype.trees['{$treetableid}'].toggleRows(this)\" "; } $url = $rows[$curr_rowid]['record']->getURL(); $editURL = $rows[$curr_rowid]['record']->getURL('-action=edit'); $deleteURL = $rows[$curr_rowid]['record']->getURL('-action=delete'); echo "class=\"{$class}\"></a></td>\n\t\t\t\t<td><a href=\"" . df_escape($url) . "\">" . df_escape($rows[$curr_rowid]['record']->getTitle()) . "</a></td>"; foreach ($columns as $col) { echo "<td>"; if ($col == $default_order_column) { // If this is the order column, we will provide links to move the record up or down in order. if ($path[count($path) - 1] !== '1') { echo "<a href=\"#\" onclick=\"moveUp(" . (intval($path[count($path) - 1]) - 1) . ")\" title=\"Move up\"><img src=\"" . DATAFACE_URL . "/images/arrowUp.gif\"/></a>"; } //if ( $i != $this->_start+$limit-1 ){ echo "\n\t\t\t\t\t\t\t\t<a href=\"#\" onclick=\"moveDown(" . (intval($path[count($path) - 1]) - 1) . ")\" title=\"Move down\"><img src=\"" . DATAFACE_URL . "/images/arrowDown.gif\"/></a>"; //} //echo "</td> // "; } else { if ($rows[$curr_rowid]['record']->_table->hasField($col)) { echo "<a href=\"" . df_escape($url) . "\">" . $rows[$curr_rowid]['record']->htmlValue($col) . "</a>"; } else { echo '--'; } } echo "\n\t\t\t\t</td>"; } echo "\n\t\t\t</tr>\n\t\t\t"; } $out = ob_get_contents(); ob_end_clean(); return $out; }
/** * @brief Adds a related record to the current context. This provides * a lense through which to view the destination records of this related * record so that their permissions are evaluated as if they are part * of the relationship. * * @param Dataface_RelatedRecord $rec The related record to add for context. * @returns void * @since 2.0 * @see getRecordContext() * @see clearRecordContext() */ function addRecordContext(Dataface_RelatedRecord $rec) { $this->getRecordContext(); $destRecords = $rec->toRecords(); foreach ($destRecords as $destRec) { $this->recordContext[$destRec->getId()] = $rec; } Dataface_PermissionsTool::addContextMask($rec); }
/** * @brief Gets a list of fields that are unconstrained (i.e. can be * edited. This is helpful when building forms for this record. * * @returns array($fieldname:string) * @since 2.0 */ function getUnconstrainedFields($sql = null) { //$fkCols = $this->getForeignKeyValues($sql); $tmp = new Dataface_RelatedRecord($this->_record, $this->_relationshipName, array()); $fkCols = $tmp->getForeignKeyValues($sql); if (PEAR::isError($fkCols)) { throw new Exception($fkCols->getMessage(), $fkCols->getCode()); } $unconstrainedFields = array(); $cols = $this->_relationship->fields(); foreach ($cols as $col) { $field = $this->_relationship->getField($col); //print_r($field); $tablename = $field['tablename']; $fieldname = $field['name']; //echo $absFieldname; if (array_key_exists($tablename, $fkCols) and array_key_exists($fieldname, $fkCols[$tablename])) { // This column is already specified by the foreign key relationship so we don't need to pass // this information using the form. // Actually - this isn't entirely true. If there is no auto-incrementing field // associated with this foreign key, then if ($this->_relationship->isNullForeignKey($fkCols[$tablename][$fieldname])) { $furthestField = $fkCols[$tablename][$fieldname]->getFurthestField(); if ($furthestField != $absFieldname) { // We only display this field if it is the furthest field of the key continue; } } else { continue; } } if (@$field['grafted'] && !@$field['transient']) { continue; } $unconstrainedFields[] = $col; } return $unconstrainedFields; }
function testPermissions() { $formulasTable = Dataface_Table::loadTable('formulas'); $formulasDel = $formulasTable->getDelegate(); $formulasDel->testPermissions = true; $formula = new Dataface_Record('formulas', array('formula_name' => 'test formula')); // Test the standard permissions on tables and fields $this->assertTrue($formula->checkPermission('view'), 'View permission should be set by default.'); $this->assertTrue(!$formula->checkPermission('list'), 'List permission should be denied by default.'); $this->assertTrue($formula->checkPermission('new'), 'New permission should be permitted by default.'); $this->assertTrue(!$formula->checkPermission('new', array('field' => 'formula_name')), 'New permission should be denied on the formula_name field.'); $this->assertTrue($formula->checkPermission('view', array('field' => 'formula_name')), 'The view permission should be allowed on the formula_name field.'); $this->assertTrue(!$formula->checkPermission('view', array('field' => 'formula_id')), 'The view permission should be denied on the formula_id field.'); // Test the nobubble parameter on getPermissions $this->assertTrue(!$formula->checkPermission('delete', array('field' => 'formula_name', 'nobubble' => 1)), 'Since we are not bubbling up to record, we should not have permission for the delete permission as it is not enabled at field level explicitly - only at record level.'); $this->assertTrue($formula->checkPermission('delete', array('field' => 'formula_name')), 'Now that we are allowing bubbling, we should return true for delete on teh formula_name field.'); $this->assertTrue($formula->checkPermission('copy', array('field' => 'formula_name', 'nobubble' => 1)), 'Even though there is no bubbling, we should still return true for the copy permission on the formula_name field since it is defined in the __field__permssions() method.'); $this->assertTrue($formula->checkPermission('view', array('field' => 'amount', 'relationship' => 'ingredients')), 'view permission of the amount field in the ingredients relationship should be allowed because it is granted in the rel_ingredients__amount__permissions() method of the formulas delegate class.'); $this->assertTrue($formula->checkPermission('view', array('field' => 'amount', 'relationship' => 'ingredients', 'nobubble' => 1)), 'view permission for amount field in ingredients relationship should be allowed even with nobubble=1 because it is permistted in the rel_ingredients__amount__permissions().'); $this->assertTrue($formula->checkPermission('link', array('field' => 'amount', 'relationship' => 'ingredients')), 'link permission on amount field of the ingredients relationship should be allowed because it is granted in the rel_ingredients__permissions() method of the formulas delegate class.'); $this->assertTrue(!$formula->checkPermission('link', array('field' => 'amount', 'relationship' => 'ingredients', 'nobubble' => 1)), 'link permission on the amount field of the ingredients relationship should not be allowed when nobubble=1 because although it is granted in the rel_ingredients__permissions() method of the formulas delegate class - this method shouldnt be consulted if nobubble=1. It should just check the specific field permissions of the relationship and then break.'); $this->assertTrue($formula->checkPermission('link', array('relationship' => 'ingredients')), 'link permission should be allowed on the ingredients relationship because it is granted in the rel_ingredients__permissions() method of the formulas delegate class.'); $this->assertTrue($formula->checkPermission('link', array('relationship' => 'ingredients', 'nobubble' => 1)), 'link permission should be allowed in the ingredients relationship even with nobubble=1 because it is granted in the rel_ingredients__permissions() method of the formulas delegate class. nobubble should just prevent it from looking past the relationship permissions.'); // Test related record permissions $formulaIngredientsTable = Dataface_Table::loadTable('formula_ingredients'); $formulaIngredientsDel = $formulaIngredientsTable->getDelegate(); $formulaIngredientsDel->testPermissions = true; $relatedRecord = new Dataface_RelatedRecord($formula, 'ingredients', array('ingredient_id' => 1, 'concentration' => 3, 'amount' => 4)); // Test the standard related permission $this->assertTrue(!$relatedRecord->checkPermission('view', array('field' => 'concentration')), 'There shouldn\'t be permission to view the concentration field as it is denied in the getPermissions() method and is not overridden in any of the function methods.'); $this->assertTrue($relatedRecord->checkPermission('view', array('field' => 'ingredient_id')), 'There should be permission to view the ingredient_id field since it is overridden in the ingredient_id__permissions() method of the formula_ingredients delegate class.'); $this->assertTrue($relatedRecord->checkPermission('view', array('field' => 'amount')), 'There should be permission to view the amount field since the rel_ingredients__amount__permissions() method is defined in the parent table delegate class and grants the permission.. This should table precedence.'); $ingredientRecord = new Dataface_Record('formula_ingredients', array('ingredient_id' => 1, 'concentration' => 3, 'amount' => 4)); $this->assertTrue(!$ingredientRecord->checkPermission('view', array('field' => 'amount')), 'There should be no permission for view of the amount field directly because it hasnt been granted in the formula_ingredients delegate class.'); // Test the display now. $this->assertEquals('NO ACCESS', $relatedRecord->display('concentration'), 'Concentration should be no access via the related record because we havent granted access yet.'); $this->assertEquals('4', $relatedRecord->display('amount'), 'Amount should display the proper value because view has been granted via the relationship.'); $this->assertEquals('NO ACCESS', $ingredientRecord->display('amount'), 'Amount should display "NO ACCESS" when accessing the record directly, but instead received the actual value.'); $formulasDel->testPermissions = false; }