I'm a new user of Magento and i work on the creation of a module to do Cross-Selling.
I already take all of the command who have more than 1 product to make relation with that. But now, to complete my code and module i wanted to know how can i recovery the command with more than 1 article and take also all the command of the customer (a lot of customer have buy 1 by 1 some products).
Sorry for my english but i hope you have understand.
Right now, the module put in a table (work with a cron), all data every day but let see the code :
My block :
class MyCompany_Crosssell_Block_Crosssell extends Mage_Catalog_Block_Product_Abstract {
public function _prepareLayout() {
return parent::_prepareLayout();
}
public function getTitle() {
$title = Mage::getStoreConfig('catalog/crosssell/title');
return $title;
}
public function getEnable() {
return Mage::getStoreConfig('catalog/crosssell/enable');
}
public function getProductsBought(){
return Mage::getModel('MyCompany_crosssell/crosssell')
->getBoughtProducts(Mage::helper('MyCompany_crosssell')->getcollectProductBoughtId(Mage::registry('current_product')))
->setPageSize(Mage::getStoreConfig('catalog/crosssell/products'));
}
}
My Helper :
class Mycompany_Crosssell_Helper_Data extends Mage_Core_Helper_Abstract {
public function getcollectProductBoughtId($product){
return explode(',',Mage::getModel('Mycompany_crosssell/crosssell')->load($product->getId())->getProducttype());
}
}
Model :
class Mycompany_Crosssell_Model_Observer extends Varien_Event_Observer {
public function __construct() {
}
public function crosssell($observer) {
$collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*');
$collection->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
$collection->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
$connexion = Mage::getSingleton('core/resource')->getConnection('core_write');
$connexion->query("TRUNCATE TABLE `crosssell_crosssell`");
$values = array();
$cpt = 0;
foreach ($collection as $product) {
$productids = Mage::getModel('Mycompany_crosssell/crosssell')->collectProductBoughtId($product);
/* $model = Mage::getModel('Mycompany_crosssell/crosssell');
$model->setData('productid', $product->getId());
$model->setData('producttype', implode(',', $productids));
$model->save(); */
if ($productids) {
$values[] = "(" . $product->getId() . ", '" . implode(',', $productids) . "')";
if ($cpt++ > 500) {
$connexion->query("
INSERT IGNORE INTO `crosssell_crosssell`(productid, producttype) VALUES " . implode(',', $values));
$cpt = 0;
$values = array();
}
}
}
$connexion->query("
INSERT IGNORE INTO `crosssell_crosssell`(productid, producttype) VALUES " . implode(',', $values));
}
}
class Mycompany_Crosssell_Model_Crosssell extends Mage_Core_Model_Abstract {
public function _construct() {
parent::_construct();
$this->_init('Mycompany_crosssell/crosssell');
}
public function collectProductBoughtId($product) {
$_order = '';
$_productOption = array();
$productOption = array();
$_orderId = '';
$_order = Mage::getResourceModel('sales/order_item_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('product_id', $product->getId());
foreach ($_order as $order) {
$_orderId[] = $order->getOrderId();
}
$_product = Mage::getResourceModel('sales/order_item_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('order_id', $_orderId)
->addAttributeToFilter('product_id', array('neq' => $product->getId()));
foreach ($_product as $_productData) {
$_productId[] = $_productData->getProductId();
}
return array_unique($_productId);
}
public function getBoughtProducts($product) {
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', array('in', $product));
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$attributes = Mage::getSingleton('catalog/config')->getProductAttributes();
$collection->addAttributeToSelect($attributes)
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents();
$collection->getSelect()->order(new Zend_Db_Expr('RAND()'));
return $collection;
}
}
class Mycompany_Crosssell_Model_Mysql4_Crosssell_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
public function _construct(){
$this->_init('Mycompany_crosssell/crosssell');
}
}
class Mycompany_Crosssell_Model_Mysql4_Crosssell extends Mage_Core_Model_Mysql4_Abstract
{
protected function _construct()
{
$this->_init('Mycompany_crosssell/crosssell', 'productid');
}
}
SQL:
<?php
$installer = $this;
$installer->startSetup();
$table = $installer->getConnection()
->newTable($installer->getTable('Mycompany_crosssell/crosssell'))
->addColumn('productid', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'auto_increment' => false,
'identity' => false,
'unsigned' => true,
'nullable' => false,
'primary' => true,
), 'ID product')
->addColumn('producttype', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
'auto_increment' => false,
'identity' => false,
'unsigned' =>false,
'nullable' =>false,
'primary' =>false,
), 'type product');
$installer->getConnection()->createTable($table);
$installer->endSetup();
Related
I have added a field to my Prestashop registration form and I want to display and update it from the user interface. I already have a good part since the field appears, we can fill it and it is displayed in the database. The problem is that I am missing an essential part; the possibility to display it in the user interface and the update, can someone help me ? I have a get function and I think I need a set function too to be able to update, but I don't know what to write in it
My module files
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
use PrestaShop\PrestaShop\Adapter\Presenter\Object\ObjectPresenter;
require_once dirname(__FILE__) . '/classes/CustomerFonction.php';
class AddJob extends Module
{
public function __construct()
{
$this->name = 'addjob';
$this->tab = 'others';
$this->version = '1.0.0';
$this->author = 'advisa';
$this->need_instance = 0;
$this->ps_versions_compliancy = [
'min' => '1.6',
'max' => '1.7.99',
];
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('AddJob');
$this->description = $this->l('Add job in registration form');
}
public function install()
{
return parent::install() &&
$this->installSql() &&
$this->registerHook('additionalCustomerFormFields') &&
$this->registerHook('actionCustomerAccountAdd');
}
public function uninstall()
{
return (
parent::uninstall()
);
}
/*
public function installSql()
{
$sqlInstall = "ALTER TABLE " . _DB_PREFIX_ . "customer "
. "ADD fonction VARCHAR(255) NULL";
return Db::getInstance()->execute($sqlInstall);
} */
public function installSql()
{
$sqlQuery = array();
$sqlQuery[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'addjob_addfonction` (
`id_addfonction` INT(10) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`id_customer` INT(10),
`fonction` VARCHAR(255)
)';
$db = Db::getInstance();
foreach ($sqlQuery as $query) {
if (!$db->execute($query)) {
return false;
}
}
return true;
}
public function hookAdditionalCustomerFormFields($param)
{
$field = array();
$field['fonction'] = (new FormField())
->setName('fonction')
->setType('text')
//->setRequired(true)
->setLabel($this->l('Fonction'));
if($this->context->customer->id !== null){
$data = new CustomerFonction($this->context->customer->id);
$field['fonction']->setValue($data->fonction ?? '');
}
return $field;
}
public function hookActionCustomerAccountAdd($param)
{
$customeField = new CustomerFonction();
$customeField->id_customer = $param['newCustomer']->id;
$customeField->fonction = Tools::getValue('fonction', '');
$customeField->add();
}
public function hookActionCustomerAccountUpdate($param)
{
$customerId = $this->context->customer->id;
$customerField = new CustomerFonction($customerId);
$customerField->id_customer = $customerId;
$customerField->fonction = Tools::getValue('fonction', '');
$customerField->save();
}
}
And my ObjectModel classes
<?php
class CustomerFonction extends ObjectModel
{
public $id_addfonction;
public $id_customer;
public $fonction;
public static $definition = [
'table' => 'addjob_addfonction',
'primary' => 'id_addfonction',
'multilang' => false,
'fields' => [
'id_customer' => ['type' => self::TYPE_INT],
'fonction' => ['type'=>self::TYPE_STRING, 'size'=> 255],
],
];
public static function getFonctionByCustomer($id_customer): ?string
{
$sql = new DbQuery();
$sql->select('fonction');
$sql->from('addjob_fonction');
$sql->where('id_customer = ' . $id_customer);
return Db::getInstance()->getValue($sql);
}
public static function getByCustomerId(): self
{
}
public static function setFonctionByCustomer(string $fonction, $id): self
{
}
}
I tried to set up a sign up logic but suffer a problem said
Message: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'member_login' cannot be null, query was: INSERT INTO members (member_login) VALUES (?)enter image description here
After struggling for hours, still no ideas which go wrong. Here is my source code.
Anyone can give me some ideas?
My Model.php
<?php
class Application_Model_Member
{
protected $_id;
protected $_member_login;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function __set($name, $value)
{
$method = 'set' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid member property');
}
$this->$method($value);
}
public function __get($name)
{
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid member property');
}
return $this->$method();
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setId($id)
{
$this->_id = (int) $id;
return $this;
}
public function getId()
{
return $this->_id;
}
public function setMemberLogin($text)
{
$this->_member_login = (string) $text;
return $this;
}
public function getMemberLogin()
{
return $this->_member_login;
}
}
My MemberMapper.php
<?php
class Application_Model_MemberMapper
{
protected $_dbTable;
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Application_Model_DbTable_Members');
}
return $this->_dbTable;
}
public function save(Application_Model_Member $member)
{
$data = array(
'member_login' => $member->getMemberLogin(),
);
if (null === ($id = $member->getId())) {
unset($data['member_id']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('member_id = ?' => $id));
}
}
public function find($id, Application_Model_Member $member)
{
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$member->setId($row->member_id)
->setMemberLogin($row->member_login);
}
public function fetchAll()
{
$resultSet = $this->getDbTable()->fetchAll();
$entries = array();
foreach ($resultSet as $row) {
$entry = new Application_Model_Member();
$entry->setId($row->member_id)
->setMemberLogin($row->member_login);
$entries[] = $entry;
}
return $entries;
}
}
DbTable:
class Application_Model_DbTable_Members extends Zend_Db_Table_Abstract
{
protected $_name = 'members';
}
Form: Registration.php
<?php
class Application_Form_Auth_Registration extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$this->addElement(
'text', 'member_login', array(
'label' => 'Username:',
'required' => true,
'filters' => array('StringTrim')
));
$this->addElement('submit', 'register', array(
'ignore' => true,
'label' => 'Sign up'
));
}
}
Signup controller:
public function signupAction()
{
$request = $this->getRequest();
$regform = new Application_Form_Auth_Registration();
if ($this->getRequest()->isPost()) {
if ($regform->isValid($request->getPost())) {
$member = new Application_Model_Member($regform->getValues());
$mapper = new Application_Model_MemberMapper();
$mapper->save($member);
return $this->_helper->redirector('/books/view');
}
}
$this->view->regform = $regform;
}
Finally I fix the bug. It go wrong with the naming of Element. For example, in your database you have "member_login", then the Element name should be sth like memberLogin.
I made a formbuilder, and now im thinking of validation and showing a form with the wrong values.
What is the right way to do this? I was thinking of making a new validation class, and a setter in the field class to decide wich validation you want, and then create the object.
And how can i return the wrong inputs, so the user has the chance to modify them? All i could think of, is making a setter for the value, so i can easily modify it. cause how my class is designed now, its not possible
EDIT: i know its not a finished class, and i have not commented the class. That's because its a WIP, and i need some tips before i continue.
<?php
/**
* form.class.php
**/
include 'form/field.class.php';
include 'form/input.class.php';
class Form {
private $_action;
private $_method;
protected $_formHtml;
protected $_atributes;
protected $_fields;
public function __construct($action,$method) {
$this->_action = $action;
$this->_method = $method;
}
protected function openForm() {
$this->_formOpen = '<form action="'.$this->_action.'" method="'.$this->_method.'" ';
if(isset($this->_atributes)) {
foreach($this->_atributes as $key => $value) {
$this->_formOpen .= ' '.$key.'="'.$value.'"';
}
}
$this->_formOpen .= '>'."\n";
return $this->_formOpen;
}
protected function closeForm() {
$this->_formClose = '</form>'."\n";
return $this->_formClose;
}
public function setAtribute($array) {
foreach($array as $key => $value) {
$this->_atributes[$key] = $value;
}
}
public function generateForm($array) {
echo $this->openForm();
foreach($array as $key) {
$key->generateField();
$key->display();
}
echo $this->closeForm();
echo $this->_formHtml;
}
public function showValues($submit) {
if(isset($_POST[$submit])) {
foreach($_POST as $key => $value) {
if($key !== $submit)
echo ''.$key.' : '.$value.'<br>';
}
}
}
}
?>
<?php
/**
* field.class.php abstract class
**/
abstract class Field {
protected $_error;
abstract protected function generateField();
abstract public function display();
abstract public function returnHtml();
public function setError($error) {
$this->_error = $error;
}
public function checkErrors() {
}
public function returnErrors() {
return $this->_error;
}
}
?>
<?php
/**
* input.class.php
**/
class Input extends Field {
protected $_elements;
var $_html;
public function __construct($array) {
foreach($array as $key => $value) {
$this->_elements[$key] = $value;
}
}
public function generateField(){
$this->_html = '<input';
foreach($this->_elements as $key => $value) {
$this->_html .= ' '.$key.'="'.$value.'"';
}
$this->_html .= '>'."\n";
}
public function returnHtml() {
return $this->_html;
}
public function display() {
echo $this->_html;
}
}
?>
<?php
/**
* index.php Voorbeeld
**/
require 'classes/form.class.php';
$username = new Input(array(
'type' => 'text',
'name' => 'username',
'placeholder' => 'Username'
));
$email = new Input (array(
'type' => 'email',
'name' => 'email',
'placeholder' => 'Email',
));
$password = new Input(array(
'type' => 'password',
'name' => 'password',
'placeholder' => 'Password'
));
$submit = new Input(array(
'type' => 'submit',
'name' => 'submit_login',
'value' => 'Login'
));
$form = new Form('','post');
$form->setAtribute(array('id' => 'test','class' => 'bla'));
$form->generateForm(array($username,$email,$password,$submit));
$form->showValues('submit_login');
I want to get 3 separate row from 'cms' table.but all time i only got first row why?
My Cms.php page is:
<?php
namespace Front\Model;
use Zend\Db\TableGateway\AbstractTableGateway;
class Cms extends AbstractTableGateway {
public function __construct($adapter) {
$this->table = 'cms';
$this->adapter = $adapter;
}
public function getCmsContent($id){
$id = (int) $id;
$rowset = $this->select(array('id'=>$id));
if (!$row = $rowset->current()){
throw new \Exception ('Row not found');
}
return $row;
}
}
My Controller is :FrontController.php is:
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Front\Model\Cms;
use Front\Model\Setting;
use Front\Model\Slider;
class FrontController extends AbstractActionController
{
public function indexAction()
{
$this->layout()->slider_data = $this->getSlider()->fetchAll();
$this->layout()->setting_data = $this->getSetting()->getSettingContent(1);
return array('cms_data'=>$this->getCms()->getCmsContent('1,2,3'));
}
public function getSlider(){
return $this->getServiceLocator()->get('Front/Model/Slider');
}
public function getCms(){
return $this->getServiceLocator()->get('Front\Model\Cms');
}
public function getSetting(){
return $this->getServiceLocator()->get('Front/Model/Setting');
}
}
My Model is:
namespace Front;
class Module
{
public function getAutoloaderConfig()
{
return array('Zend\Loader\StandardAutoloader' =>
array('namespaces' =>
array(__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
// Add this method:
public function getServiceConfig()
{
return array(
'factories' => array(
'Front\Model\AlbumTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Front\Model\AlbumTable($dbAdapter);
return $table;
},
'Front\Model\Cms' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Front\Model\Cms($dbAdapter);
return $table;
},
'Front\Model\Setting' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Front\Model\Setting($dbAdapter);
return $table;
},
'Front\Model\Slider' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Front\Model\Slider($dbAdapter);
return $table;
},
),
);
}
}
?>
My View:index.php Page is:
<?php print_R($cms_data); ?>
try this code block and change the $condition according to you
public function getCmsContent($id){
$id = (int) $id;
$select = new Select();
$select->from(array('t' => $this->table))
->where(array($condition));
$statement = $this->adapter->createStatement();
$select->prepareStatement($this->adapter, $statement);
$result = $statement->execute();
$rows = array();
if ($result->count()) {
$rows = new ResultSet();
return $rows->initialize($result)->toArray();
}
}
You try:
class Cms extends AbstractTableGateway {
public function __construct($adapter) {
$this->table = 'cms';
$this->adapter = $adapter;
}
public function getCmsContent($id){
return $this->select(array(
new Expression('id IN (?)', array($id)),
));
}
}
Get contents
$contents = $this->getCms()->getCmsContent(array(1, 2, 3));
$results = array();
foreach($contents as $content){
$results[] = $content;
}
print_r($results);
For my ZF2 form validation I need the entity manager in my custom validator. I Zend\ServiceManager\ServiceLocatorAwareInterface to get the service locator in my validator so I would be able to get the entitymanager from there.
My problem is that this Zend\ServiceManager\ServiceLocatorAwareInterface::setServiceLocator injects the "Zend\Validator\ValidatorPluginManager" and not the desired ServiceLocator.
Does anybody know how to solve this problem?
My abstract controller
abstract class AbstractController extends AbstractActionController
{
/**
* This property contains the doctrine entitymanager.
* #var Doctrine\ORM\EntityManager
*/
protected $_entityManager;
/**
* This method returns the doctrine entitymanager.
* #return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
var_dump(spl_object_hash($this->getServiceLocator())); echo '<br>';
if (null === $this->_entityManager)
$this->_entityManager = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
return $this->_entityManager;
}
}
My validator:
class EntityUnique extends AbstractValidator implements ServiceLocatorAwareInterface
{
protected $_serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
var_dump(spl_object_hash($serviceLocator)); echo '<br>';
$this->_serviceLocator = $serviceLocator;
}
function getServiceLocator()
{
return $this->_serviceLocator;
}
}
When executing this both var_dumps result in another object hash:
string(32) "000000005e4258390000000024a7f829"
string(32) "000000005e425a2d0000000024a7f829"
The reason for this is that in your validator you are getting the Zend\Validator\ValidatorPluginManager injected. If you want the the Service Manager call getServiceLocator on the Zend\Validator\ValidatorPluginManager.
For example look at the someMethod() method bellow:
class EntityUnique extends AbstractValidator implements ServiceLocatorAwareInterface
{
protected $_serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
var_dump(spl_object_hash($serviceLocator)); echo '<br>';
$this->_serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->_serviceLocator;
}
public function someMethod()
{
$validatorPluginManager = $this->getServiceLocator();
$serviceLocator = $validatorPluginManager->getServiceLocator(); // HERE
}
}
Hope this helps :)
Stoyan
I got it working in the end. I don't know if this is the best practice so if you have any feedback don't hesitate. My validator ended up like this:
<?php
namespace Flex\Validator;
use Doctrine\ORM\EntityManager;
use Zend\Stdlib\ArrayUtils;
use Zend\ServiceManager\ServiceManager;
use Zend\Validator\AbstractValidator;
class EntityUnique extends AbstractValidator
{
const EXISTS = 'exists';
protected $messageTemplates = array(
self::EXISTS => 'A %entity% entity allready exists.',
);
protected $messageVariables = array(
'entity' => '_entity',
);
protected $_context;
protected $_entity;
protected $_excludes = array();
protected $_filters = array();
protected $_property;
protected $_serviceLocator;
public function __construct($options = null)
{
if ($options instanceof \Traversable)
$options = ArrayUtils::iteratorToArray($options);
if (is_array($options))
{
if (isset($options['entity']))
$this->_entity = $options['entity'];
if (isset($options['exclude']))
{
if (!is_array($options['exclude']))
throw new \Exception('Exclude option should be an array');
if (isset($options['exclude']['property']) && isset($options['exclude']['value']))
$this->_excludes[] = array(
'property' => $options['exclude']['property'],
'value' => $options['exclude']['value'],
);
else
foreach ($options['exclude'] as $exclude)
{
if (!isset($exclude['property']) || !isset($exclude['value']))
throw new \Exception('exclude shoud contain a property and value');
$this->_excludes[] = array(
'property' => $exclude['property'],
'value' => $exclude['value'],
);
}
}
if (isset($options['filter']))
{
if (!is_array($options['filter']))
throw new \Exception('Filter option should be an array');
if (isset($options['filter']['property']) && isset($options['filter']['value']))
$this->_filters[] = array(
'property' => $options['filter']['property'],
'value' => $options['filter']['value'],
);
else
foreach ($options['filter'] as $filter)
{
if (!isset($filter['property']) || !isset($filter['value']))
throw new \Exception('Filters shoud contain a property and value');
$this->_filters[] = array(
'property' => $filter['property'],
'value' => $filter['value'],
);
}
}
if (isset($options['property']))
$this->_property = $options['property'];
if (!isset($options['serviceLocator']))
throw new \InvalidArgumentException(__CLASS__ . ' requires the option serviceLocator.');
$ServiceManagerInstance = 'Zend\ServiceManager\ServiceManager';
if (!($options['serviceLocator'] instanceof $ServiceManagerInstance))
throw new \InvalidArgumentException(__CLASS__ . ' expects the option serviceLocator to be an instance of Zend\ServiceManager\ServiceManager.');
$this->_serviceLocator = $options['serviceLocator'];
}
parent::__construct(is_array($options) ? $options : null);
}
public function isValid($value, $context = null)
{
$this->setValue($value);
$this->_context = $context;
$entityManager = $this->_serviceLocator->get('doctrine.entitymanager.orm_default');
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->from($this->_entity, 'e')
->select('COUNT(e)')
->where('e.' . $this->_property . ' = :value')
->setParameter('value', $this->getValue());
if (count($this->_excludes))
foreach ($this->_excludes as $key => $exclude)
{
$exclude['value'] = $this->parse($exclude['value']);
if ($exclude['value'] !== null)
$queryBuilder->andWhere('e.' . $exclude['property'] . ' = :exclude_' . $key)
->setParameter('exclude_' . $key, $exclude['value']);
else
$queryBuilder->andWhere('e.' . $exclude['property'] . ' IS NULL');
}
if (count($this->_filters))
foreach ($this->_filters as $key => $filter)
{
$filter['value'] = $this->parse($filter['value']);
if ($filter['value'] !== null)
$queryBuilder->andWhere('e.' . $filter['property'] . ' = :filter_' . $key)
->setParameter('filter_' . $key, $filter['value']);
else
$queryBuilder->andWhere('e.' . $filter['property'] . ' IS NULL');
}
$query = $queryBuilder->getQuery();
if ((integer) $query->getSingleScalarResult() !== 0)
{
$this->error(self::EXISTS);
return false;
}
return true;
}
private function parse($input, $current = null)
{
if (!is_array($input))
return $input;
if ($current === null)
$current = $this;
$currentKey = array_shift($input);
if (is_object($current) && property_exists($current, $currentKey))
$current = $current->$currentKey;
elseif (is_array($current) && array_key_exists($currentKey, $current))
$current = $current[$currentKey];
else
return null;
if (count($input))
return $this->parse($input, $current);
if (strlen($current) == 0)
return null;
return $current;
}
}
This is loaded in like this:
<?php
namespace FlexCategories\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
class CategoryForm extends Form implements InputFilterProviderInterface, ServiceManagerAwareInterface
{
private $_serviceManager;
public function init()
{
/* */
}
public function getInputFilterSpecification()
{
return array(
'name' => array(
'filters' => array(
array(
'name' => 'Zend\Filter\StringTrim'
),
),
'required' => true,
'validators' => array(
array(
'name' => 'Flex\Validator\EntityUnique',
'options' => array(
'entity' => 'FlexCategories\Entity\Category',
'filter' => array(
array('property' => 'parent',
'value' => array('_context', 'parent')),
),
'property' => 'name',
'serviceLocator' => $this->_serviceManager,
),
),
),
),
);
}
public function setServiceManager(ServiceManager $serviceManager)
{
$this->_serviceManager = $serviceManager;
$this->init();
return $this;
}
}
The form is registered in the service_manager => invokables and is retreived within the controller thorugh the service manager.
This worked for me. I hope somebody will be able to learn from this or give me feedbacl to create an better solution.