/** * @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 testRelatedRecord() { $fragrance = df_get_record('fragrances', array('fragrance_id' => '=1')); $relatedRecord = new Dataface_RelatedRecord($fragrance, 'formulas'); $this->assertEquals($fragrance, $relatedRecord->getParent(), 'getParent() returned wrong record.'); $relatedRecord->setValue('formula_name', 'Test'); $fkvals = $relatedRecord->getForeignKeyValues(); $this->assertEquals(array('formulas' => array('fragrance_id' => '1', 'formula_name' => 'Test')), $fkvals, 'getForeignKeyValues() returned wrong structure.'); $relatedRecord->setValue('ingredients', array(0 => array('ingredient_id' => 3, 'concentration' => 10, 'concentration_units' => 1, 'amount' => 10, 'amount_units' => 2, '__id__' => 'new', '__order__' => 0), '__loaded__' => 1)); $fkvals = $relatedRecord->getForeignKeyValues(); $this->assertEquals(array('formulas' => array('fragrance_id' => '1', 'formula_name' => 'Test')), $fkvals, 'getForeignKeyValues() returned wrong structure.'); $formulaRecord = $relatedRecord->toRecord('formulas'); $this->assertTrue($formulaRecord instanceof Dataface_Record, 'toRecord() is expected to return a Dataface_Record object.'); $this->assertEquals('Test', $formulaRecord->val('formula_name'), 'toRecord() failed to transfer basic value to resulting Dataface_Record object.'); $this->assertEquals(array(0 => array('ingredient_id' => 3, 'concentration' => 10, 'concentration_units' => 1, 'amount' => 10, 'amount_units' => 2, '__id__' => 'new', '__order__' => 0), '__loaded__' => 1), $formulaRecord->val('ingredients'), 'toRecord() failed to transfer value of transient field to resulting Dataface_Record object.'); $records = $relatedRecord->toRecords(); $this->assertEquals(1, count($records), 'toRecords() returned wrong number of records.'); $this->assertTrue($records[0] instanceof Dataface_Record, 'toRecords should return an array of Dataface_Record objects.'); }