Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validator ZFDoctrine_Validate_Unique #24

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/ZFDoctrine/Controller/Helper/ModelForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function direct(ZFDoctrine_Form_Model $form, $action = null, $controller

/**
* Handle Create or Update Workflow of a ZFDoctrine_Form_Model instance
*
*
* @throws ZFDoctrine_DoctrineException
* @param ZFDoctrine_Form_Model $form
* @param string $action
Expand Down Expand Up @@ -100,7 +100,7 @@ public function handleForm(ZFDoctrine_Form_Model $form, $action = null, $control
$actionParams
));

if ($request->isPost() && $form->isValid($request->getPost())) {
if ($request->isPost() && $form->isValid($request->getParams())) {
$form->save();

$redirector = $actionController->getHelper('redirector');
Expand Down
10 changes: 6 additions & 4 deletions library/ZFDoctrine/Form/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

/**
* Class for autogenerating forms based on Doctrine models
*
*
* @author Jani Hartikainen <firstname at codeutopia net>
*/
class ZFDoctrine_Form_Model extends Zend_Form
Expand Down Expand Up @@ -106,7 +106,9 @@ public function __construct($options = null) {
if($this->_adapter == null) {
$this->setAdapter(new ZFDoctrine_Form_Model_Adapter_Doctrine());
}


$this->addElementPrefixPath('ZFDoctrine', 'ZFDoctrine');

$this->_preGenerate();
$this->_generateForm();
$this->_postGenerate();
Expand Down Expand Up @@ -306,7 +308,7 @@ protected function _columnsToFields()
$field->addMultiOption($text, ucwords($text));
}
} else if($definition['foreignKey'] && $field instanceof Zend_Form_Element_Multi) {
$options = array('------');
$options = array(null => '------');
foreach ($this->_adapter->getAllRecords($definition['class']) AS $record) {
$options[$this->_adapter->getRecordIdentifier($record)] = (string)$record;
}
Expand Down Expand Up @@ -380,7 +382,7 @@ public function save($persist = true) {
}

foreach($this->getSubForms() as $subForm) {
if ($subForm instanceof ZFDoctrine_Form_ModelSubForm) {
if ($subForm instanceof ZFDoctrine_Form_Model_SubForm) {
$subForm->save($persist);
}
}
Expand Down
203 changes: 203 additions & 0 deletions library/ZFDoctrine/Validate/Unique.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<?php
class ZFDoctrine_Validate_Unique extends Zend_Validate_Abstract
{
/** Error constants
*/
const ERROR_RECORD_FOUND = 'recordFound';

/**
* @var array Message templates
*/
protected $_messageTemplates = array(
self::ERROR_RECORD_FOUND => 'A record matching "%value%" was found.',
);

/**
* Model name
* @var string
*/
private $_model;

/**
* Returns the field names
*
* @var array
*/
private $_fields;

/**
* Returns the model name
*
* @return string Model name
*/
public function getModel ()
{
return $this->_model;
}

/**
* Returns the fields
*
* @return array Fields
*/
public function getFields ()
{
return $this->_fields;
}

/**
* Returns true if multiple fields are configured
*
* @return boolean True if multiple fields are configured
*/
private function hasMultipleFields()
{
return count($this->_fields) > 1;
}

/**
* Sets the model name
*
* @param string $model Model name
*/
public function setModel($model)
{
$this->_model = $model;
}

/**
* Sets the field names
*
* @param array $fields Field names
*/
public function setFields ($fields)
{
$this->_fields = $fields;
}

/**
* Constructor
*
* The following option keys are supported:
* 'model' => The model to validate against
* 'fields' => The fields to check for a match
*
* @param array|Zend_Config $options Options to use for this validator
*/
public function __construct($options)
{
if ($options instanceof Zend_Config) {
$options = $options->toArray();
} else if (func_num_args() > 1) {
$options = func_get_args();
$temp['model'] = array_shift($options);
$temp['fields'] = array_shift($options);

$options = $temp;
}

if (!array_key_exists('model', $options)) {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Model option missing!');
}
$this->setModel($options['model']);

if (!array_key_exists('fields', $options)) {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Fields option missing!');
}
if (!is_array($options['fields'])) {
$options['fields'] = array($options['fields']);
}

$this->setFields($options['fields']);
}

/**
* Returns true if and only if $value meets the validation requirements
*
* @param mixed $value Value
* @param array $context Context
* @return boolean True if $value is valid in context of $context
* @throws Zend_Valid_Exception If validation of $value is impossible
* @see Zend_Validate_Interface::isValid()
*/
public function isValid($value, $context = null)
{
if ($this->hasMultipleFields() && is_null($context)) {
throw new Zend_Validate_Exception('Multiple fields configured but no context passed.');
}

$table = ZFDoctrine_Core::getTable($this->getModel());

$fields = $this->getFields();

$method = 'findOneBy'.implode(array_map('ucfirst', $fields), 'And');

if (!$this->hasMultipleFields()) {
$record = call_user_func(array($table, $method), $value);
} else {
foreach ($this->getFields() as $f) {
if (!isset($context[$f])) {
throw new Zend_Validate_Exception(sprintf('Field "%s" not in context.', $f));
}
}

$params = $context;
foreach (array_keys($params) as $key) {
if (!in_array($key, $fields)) {
unset($params[$key]);
}
}

$record = call_user_func_array(array($table, $method), $params);
}

// if no object or if we're updating the object, it's ok
if (!$record || $this->isUpdate($record, $context)) {
return true;
}

$this->_setValue($value);
$this->_error(self::ERROR_RECORD_FOUND);

return false;
}

/**
* Returns whether the object is being updated.
*
* @param Doctrine_Record Doctrine record
* @param array An array of values
*
* @return bool True if the object is being updated, false otherwise
*/
protected function isUpdate(Doctrine_Record $record, $values)
{

// check each primary key column
foreach ($this->getPrimaryKeys() as $column) {
if (!isset($values[$column]) || $record->$column != $values[$column]) {
return false;
}
}

return true;
}

/**
* Returns the primary keys for the model.
*
* @return array An array of primary keys
*/
protected function getPrimaryKeys()
{
$primaryKeys = Doctrine_Core::getTable($this->getModel())->getIdentifier();

if (!is_array($primaryKeys)) {
$primaryKeys = array($primaryKeys);
}

return $primaryKeys;
}
}
50 changes: 39 additions & 11 deletions library/ZFDoctrine/View/Helper/ModelList.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,18 @@ class ZFDoctrine_View_Helper_ModelList extends Zend_View_Helper_Abstract
* @var array
*/
static private $_defaultOptions = array(
'pageParamName' => 'page',
'paginationStyle' => 'Sliding',
'paginationScript' => null,
'addRecordAction' => null,
'editRecordAction' => null,
'pageParamName' => 'page',
'paginationStyle' => 'Sliding',
'paginationScript' => null,
'addRecordAction' => null,
'editRecordAction' => null,
'deleteRecordAction' => null,
'itemsPerPage' => 30,
'listScript' => null,
'addRecordUrl' => null,
'editRecordUrl' => null,
'deleteRecordUrl' => null,
'itemsPerPage' => 30,
'listScript' => null,
'recordIdParam' => 'id',
);

static private $_enabledView = array();
Expand Down Expand Up @@ -94,12 +98,36 @@ public function modelList($modelName, array $options = array(), Doctrine_Query_A
$fieldNames = $options['showFieldNames'];
}

if (isset($options['addRecordAction'])) {
if (!isset($options['addRecordUrl'])) {
$options['addRecordUrl'] = array();
}

$options['addRecordUrl']['action'] = $options['addRecordAction'];
}

if (isset($options['editRecordAction'])) {
if (!isset($options['editRecordUrl'])) {
$options['editRecordUrl'] = array();
}

$options['editRecordUrl']['action'] = $options['editRecordAction'];
}

if (isset($options['deleteRecordAction'])) {
if (!isset($options['deleteRecordUrl'])) {
$options['deleteRecordUrl'] = array();
}

$options['deleteRecordUrl']['action'] = $options['deleteRecordAction'];
}

return $this->view->partial($options['listScript'], array(
'modelName' => $modelName,
'paginator' => $paginator,
'modelName' => $modelName,
'paginator' => $paginator,
'currentPage' => $currentPage,
'options' => $options,
'fieldNames' => $fieldNames,
'options' => $options,
'fieldNames' => $fieldNames,
));
}

Expand Down
30 changes: 16 additions & 14 deletions library/ZFDoctrine/View/Helper/files/scripts/list.phtml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="zfdoctrine-modellist zfdoctrine-model-<?php echo $this->modelName; ?>">
<?php if ($this->options['addRecordAction']): ?>
<?php if ($this->options['addRecordUrl']): ?>
<ul class="zfdoctrine-add">
<li><a href="<?php echo $this->url(array('action' => $this->options['addRecordAction'])); ?>">Add</a></li>
<li><a href="<?php echo $this->url($this->options['addRecordUrl']); ?>">Add</a></li>
</ul>
<?php endif; ?>

Expand All @@ -15,7 +15,7 @@
<th><?php echo $this->escape($name); ?></th>
<?php endif; ?>
<?php endforeach; ?>
<?php if ($this->options['editRecordAction'] || $this->options['deleteRecordAction']): ?>
<?php if ($this->options['editRecordUrl'] || $this->options['deleteRecordUrl']): ?>
<th>Options</th>
<?php endif; ?>
</tr>
Expand All @@ -26,14 +26,14 @@
<?php foreach ($this->fieldNames AS $name): ?>
<td class="zfdoctrine-field-<?php echo $name; ?>"><?php echo $this->escape($record->$name); ?></td>
<?php endforeach; ?>
<?php if ($this->options['editRecordAction'] || $this->options['deleteRecordAction']): ?>
<?php if ($this->options['editRecordUrl'] || $this->options['deleteRecordUrl']): ?>
<td class="zfdoctrine-options">
<?php if ($this->options['editRecordAction']): ?>
<a href="<?php echo $this->url(array('action' => $this->options['editRecordAction'], 'id' => $record->identifier())); ?>">Edit</a>
<?php if ($this->options['editRecordUrl']): ?>
<a href="<?php echo $this->url(array_merge($this->options['editRecordUrl'], array($this->options['recordIdParam'] => $record->identifier()))); ?>">Edit</a>
<?php endif; ?>

<?php if ($this->options['deleteRecordAction']): ?>
<a href="<?php echo $this->url(array('action' => $this->options['deleteRecordAction'], 'id' => $record->identifier())); ?>">Delete</a>
<?php if ($this->options['deleteRecordUrl']): ?>
<a href="<?php echo $this->url(array_merge($this->options['deleteRecordUrl'], array($this->options['recordIdParam'] => $record->identifier()))); ?>">Delete</a>
<?php endif; ?>
</td>
<?php endif; ?>
Expand All @@ -42,10 +42,12 @@
</tbody>
</table>

<?php
$paginationControl = $this->paginationControl(
$this->paginator, $this->options['paginationStyle'], $this->options['paginationScript']
);
echo $paginationControl;
?>
<?php if ($this->options['itemsPerPage']): ?>
<?php
echo $this->paginationControl(
$this->paginator, $this->options['paginationStyle'], $this->options['paginationScript']
);
?>
<?php endif; ?>

</div>