Ответы пользователя по тегу Zend Framework
  • Что значит передача интерфейса в качестве параметра?

    27cm
    @27cm
    TODO: Написать статус
    Метод сохраняет модель, то есть объект класса реализующего интерфейс ModelInterface. При этом срабатывают определённые события (model.save.before и model.save.after), обработчикам которых может потребоваться доступ к сохраняемому объекту ($model). Этот доступ можно получить через расшариваемый объект класса ModelEvent, который внутри себя и содержит объект $model.
    Ответ написан
  • Роли в Zend Fraemwork - как проверить при авторизации?

    27cm
    @27cm
    TODO: Написать статус
    1 вариант
    Использовать Zend_Acl

    2 вариант
    Задать дополнительное условие в SQL запросе авторизации:
    $authAdapter->getDbSelect()->where('status = "admin"');


    Кстати, лучше не подменять пароль на его MD5 хеш вот так:
    $authAdapter->setIdentity($email)->setCredential(md5($password));

    а сделать вот так:
    $authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());
                    
    // указываем таблицу, где необходимо искать данные о пользователях
    // колонку, где искать имена пользователей, а также колонку, где хранятся пароли
    $authAdapter->setTableName('users')
                ->setIdentityColumn('email')
                ->setCredentialColumn('password')
                ->setCredentialTreatment('MD5(?)');
                    
    // получаем введённые данные
    $email = $this->getRequest()->getPost('email');
    $password = $this->getRequest()->getPost('password');
                
    // подставляем полученные данные из формы
    $authAdapter->setIdentity($email)
                ->setCredential($password);
    
    // получаем экземпляр Zend_Auth
    $auth = Zend_Auth::getInstance();
    
    // делаем попытку авторизировать пользователя
    $result = $auth->authenticate($authAdapter);

    или ещё короче:
    $authAdapter = new Zend_Auth_Adapter_DbTable(
        Zend_Db_Table::getDefaultAdapter(),
        'users', 'email', 'password', 'MD5(?)'
    );
    
    // получаем введённые данные
    $email = $this->getRequest()->getPost('email');
    $password = $this->getRequest()->getPost('password');
                
    // подставляем полученные данные из формы
    $authAdapter->setIdentity($email)
                ->setCredential($password);
    
    // получаем экземпляр Zend_Auth
    $auth = Zend_Auth::getInstance();
    
    // делаем попытку авторизировать пользователя
    $result = $auth->authenticate($authAdapter);
    Ответ написан
    Комментировать
  • Как разбить меню на кастомные селекты в zf2?

    27cm
    @27cm
    TODO: Написать статус
    Если я правильно понял, то начать можно с того, что задать ссылкам классы, соответствующие тематическим группам.
    framework.zend.com/manual/current/en/modules/zend....

    По массиву из одной страницы сложно понять, что там и как у вас лежит. Есть ли какая-то иерархия страниц?

    Далее перебираю линки, какое-то количество вывожу, какое-то объединяю в дроп-даун.

    Зачем сами перебираете ссылки, а не используете view helper?
    Ответ написан
    Комментировать
  • Где целесообразнее искать Zend программиста?

    27cm
    @27cm
    TODO: Написать статус
    Попробуйте здесь в раздел "Работа и собственные проекты" написать:
    zendframework.ru/forum
    Ответ написан
    Комментировать
  • В чем идея методов getServiceLocatior/setServiceLocator?

    27cm
    @27cm
    TODO: Написать статус
    Если вопрос именно о ServiceLocator в Zend Framework, то эти методы предоставляют доступ к ServiceManager, который позволяет получать другие объекты (сервисы) приложения.

    Например, есть класс User, и мы хотим в нём обращаться к сервису для аутентификации. Это можно сделать так:
    namespace Application\Entity;
    
    use Zend\ServiceManager\ServiceLocatorAwareInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class User implements ServiceLocatorAwareInterface
    {
        protected $serviceLocator = null;
    
        public function __construct(ServiceLocatorInterface $serviceLocator) 
        {
            $this->setServiceLocator($serviceLocator);
        }
    
        public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
        {
            $this->serviceLocator = $serviceLocator;
            return $this;
        }
    
        public function getServiceLocator()
        {
            return $this->serviceLocator;
        }
    
        public function getAuthService()
        {
            return $this->getServiceLocator()->get('AuthService');
        }
    }


    Тоже самое можно написать короче, используя трейт:
    namespace Application\Entity;
    
    use Zend\ServiceManager\ServiceLocatorAwareInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\ServiceLocatorAwareTrait;
    
    class User implements ServiceLocatorAwareInterface
    {
        use ServiceLocatorAwareTrait;
    
        public function __construct(ServiceLocatorInterface $serviceLocator) 
        {
            $this->setServiceLocator($serviceLocator);
        }
    
        public function getAuthService()
        {
            return $this->getServiceLocator()->get('AuthService');
        }
    }


    В качестве альтернативы можно использовать Dependency Injection.
    Ответ написан
    5 комментариев
  • Откуда ошибка "Route with name "" not found" при изменении Template?

    27cm
    @27cm
    TODO: Написать статус
    Проверьте сам шаблон (realestate/index). Возможно где-то есть что-то вроде:
    <?= $this->url('') ?>
    <!-- или -->
    <?= $this->url('/poi/') ?>
    Ответ написан
    Комментировать
  • Tesp prep zend certification: откуда взять устаревшие версии?

    27cm
    @27cm
    TODO: Написать статус
    "Zend PHP 5 Certification Study Guid" есть в открытом доступе. На хабре также полно статей с полезными ссылками.

    А цена такая отчасти потому что туда входят несколько попыток для пробного тестирования, ровно в том виде, в котором они будут у вас при сдаче экзамена. В качестве альтернативы попробуйте: zendexam.com
    Ответ написан
    3 комментария
  • Как зарегистрировать слушателей в onBootstrap(zf2)?

    27cm
    @27cm
    TODO: Написать статус
    ZF2 Shared Modules Event Manager

    Попробуйте так:
    $sem = $e->getApplication()->getEventManager()->getSharedManager();
    $sem->attach('Application\Controller\IndexController', '%name%', %function%);


    Ещё про SharedEventManager неплохо написано тут:
    videoforme.ru/wp-content/uploads/2011/09/RM.pdf
    Ответ написан
    Комментировать
  • Откуда лучше брать парамерты в ZF2-приложении?

    27cm
    @27cm
    TODO: Написать статус
    Вместо $_GET['id'] можно писать $this->params()->fromQuery('id'). Хотя для получения GET-параметров ничто не обязывает использовать плагин Params.

    В чем концептуальная разница?

    1. В том, как они выглядят в URL-адресе страницы. Сравните:
    GET: site.com/test?name=example
    ROUTE: site.com/test/example

    2. В GET можно помещать массивы:
    site.com/test?arr[]=1&arr[]=2&arr[]=3

    Ничто не мешает использовать сразу оба варианта:
    GET+ROUTE: site.com/test/example?name=example
    $this->params()->fromQuery('name');
    $this->params()->fromRoute('name');
    Ответ написан
    Комментировать
  • Как реализовать сложную логику проверки привилегий пользователя в Zend Framework 2?

    27cm
    @27cm
    TODO: Написать статус
    Zend\Permissions\Acl не предполагает использование базы данных (см. framework.zend.com/manual/current/en/modules/zend....).

    Получается из assertion-а к БД никак не обратиться?

    Можно было бы и там оставить, но тогда придётся отключить кеширование, да вот беда - BjyAuthorize такой возможности не предоставляет. Описать им проблему в issue не хотите?

    Надо делать запросы в каком-то другом месте?

    Если хотите оставить кеширование, то придётся делать в каком-то другом месте.

    Могут предложить "грязное" / временное решение проблемы, за которое мне будет стыдно, но всё же.
    Не хранить ObjectManager внутри IsUserDrunkAssertion, а получать его через статический метод другого класса:
    class IsUserDrunkAssertionFactory implements FactoryInterface
    {
        static protected $objectManager;
    
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            static::$objectManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
            $assertion = new IsUserDrunkAssertion();
            return $assertion;
        }
    
        static public function getObjectManager()
        {
            return static::$objectManager;
        } 
    }
    
    class IsUserDrunkAssertion implements AssertionInterface
    {
        public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null)
        {
            $objectManager = IsUserDrunkAssertionFactory::getObjectManager();
            $decision = // ... здесь бы запрос сделать
            return $decision;
        }
    }
    Ответ написан
  • Как лучше сделать уведомление о некорректной работе?

    27cm
    @27cm
    TODO: Написать статус
    Для вывода сообщений об ошибках валидации есть помощник представления formElementErrors.

    Достаточно добавить нужные валидаторы для формы, но можно конечно и явно задавать сообщение об ошибке с помощью метода setMessages() элемента формы:
    if ($form->isValid()) {
        $data = $form->getData($form::VALUES_AS_ARRAY);
    
        $authService = $this->getServiceLocator()->get('AuthenticationService');
        $authService->getAdapter()->setIdentity($data['identity'])->setCredential($data['password']);
        $result = $authService->authenticate();
    
        if (!$result->isValid()) {
            switch ($result->getCode()) {
                case $result::FAILURE_IDENTITY_NOT_FOUND :
                    $form->get('identity')->setMessages(['Неверный логин']);
                break;
                case $result::FAILURE_CREDENTIAL_INVALID :
                    $form->get('password')->setMessages(['Неверный пароль']);
                break;
                default :
                    $form->get('identity')->setMessages(['Ошибка авторизации']);
                break;
            }
        }
    }
    Ответ написан
    Комментировать
  • Почему глобальный массив $_POST приходит пустой?

    27cm
    @27cm
    TODO: Написать статус
    А так, как Вы написали в коде по ссылке, разве не работает?
    $birthDate = $this->_getParam('birthdate');
    $address = $this->_getParam('address');
    $country = $this->_getParam('country');
    $postal = $this->_getParam('postal');
    Ответ написан
  • Как переделать форму в SocialEngine (Zend Framework) на email?

    27cm
    @27cm
    TODO: Написать статус
    Если я правильно понял, попробуйте так:
    public function sendAction()
      {
        $page_id = $this->_getParam('page_id');
        $topic_id = $this->_getParam('topic_id');
        $subject = $this->_getParam('subject');
        $message = $this->_getParam('message');
        $senderName = $this->_getParam('sender_name');
        $senderEmail = $this->_getParam('sender_email');
        $birthDate = $this->_getParam('birthdate'); //
        $address = $this->_getParam('address'); //
        $country = $this->_getParam('country'); //
        $postal = $this->_getParam('postal'); //
    
        $pagesTbl = Engine_Api::_()->getDbTable('pages', 'page');
        $select = $pagesTbl->select()
            ->from(array($pagesTbl->info('name')), array('displayname'))
            ->where('page_id = ?', $page_id);
        $query = $select->query();
        $result = $query->fetchAll();
        $pageName = $result[0]['displayname'];
    
        $viewer = $this->_helper->api()->user()->getViewer();
        $user_id = $viewer->getIdentity();
    
        $topicsTbl = Engine_Api::_()->getDbTable('topics', 'pagecontact');
        $emails = $topicsTbl->getEmails($page_id, $topic_id);
    
        $i = 0;
        $emails = explode(',',$emails);
    
        foreach($emails as $email) {
          $emails[$i] = trim($email);
          $i++;
        }
    
        if ($user_id != 0) {
          $senderName = $viewer['displayname'];
          $senderEmail = $viewer['email'];
        }
    
        $message .= "\r\nBirthdate: " . $birthDate 
                 .  "\r\nAddress: " . $address 
                 .  "\r\nCountry: " . $country 
                 .  "\r\nPostal: " . $postal;
        foreach($emails as $email) {
          // Make params
          $mail_settings = array(
            'date' => time(),
            'page_name' => $pageName,
            'sender_name' => $senderName,
            'sender_email' => $senderEmail,
            'subject' => $subject,
            'message' => $message,
          );
    
          // send email
          Engine_Api::_()->getApi('mail', 'core')->sendSystem(
            $email,
            'pagecontact_template',
            $mail_settings
          );
        }
      }
    Ответ написан
  • Zend Framework 2. Как в рендер JSON добавить символы переноса?

    27cm
    @27cm
    TODO: Написать статус
    1 вариант
    Задать callback-функцию JsonModel::setJsonpCallback()

    2 вариант
    Написать класс-наследник JsonModel и использовать его в своём приложении. Получится что-то вроде этого:
    namespace Application\View\Model;
    
    use Zend\View\Model\JsonModel as ZendJsonModel;
    
    class JsonModel extends ZendJsonModel
    {
        /**
         * {@inheritDoc}
         */
        public function serialize()
        {
            return (parent::serialize() . "\r\n");
        }
    }


    3 вариант
    Написать обработчик события MvcEvent::EVENT_RENDER, задав нужный приоритет, или MvcEvent::EVENT_FINISH. В нём уже модифицировать результат.
    Ответ написан
    Комментировать
  • Как заменить стандартный escapeHtmlHelper в форме (элемент textarea) в zf2?

    27cm
    @27cm
    TODO: Написать статус
    namespace Application\View\Helper;
    
    use Zend\View\Helper\AbstractHelper;
    use Zend\Form\View\Helper\FormTextarea;
    use Zend\Form\ElementInterface;
    
    use HTMLPurifier;
    use HTMLPurifier_Config;
    use HTMLPurifier_ConfigSchema;
    use Soflomo\Purifier\View\Helper\Purifier;
    
    use Zend\ServiceManager\ServiceLocatorAwareInterface;
    use Zend\ServiceManager\ServiceLocatorAwareTrait;
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\AbstractPluginManager;
    
    class PurefierFormTextarea extends FormTextarea implements ServiceLocatorAwareInterface
    {
        protected $serviceLocator = null;
    
        public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
        {
            $this->serviceLocator = $serviceLocator;
            return $this;
        }
    
        public function getServiceLocator()
        {
            return $this->serviceLocator;
        }
    
        public function getMainServiceLocator()
        {
            if ($this->serviceLocator instanceof AbstractPluginManager) {
                return $this->serviceLocator->getServiceLocator();
            }
            return $this->serviceLocator;
        }
    
        public function render(ElementInterface $element)
        {
            // ...
    
            $this->getMainServiceLocator()->get('HTMLPurifier'); 
    
            // ...
        }
    }
    Ответ написан
    Комментировать
  • Как заставить Zend\Form\Factory при создании форм создавать используемые фильтры через FilterPluginManage?

    27cm
    @27cm Автор вопроса
    TODO: Написать статус
    Работает такой вариант:
    $filterManager = $this->getServiceLocator()->get('FilterManager');
    $factory = new Zend\Form\Factory();
    $factory->getInputFilterFactory()
            ->getDefaultFilterChain()
            ->setPluginManager($filterManager);


    Ещё судя по обсуждению здесь фильтры должны будут подхватываться, если перечислить их в методе Module::getFilterConfig():
    class Module implements Zend\ModuleManager\Feature\FilterProviderInterface
    {
        // ...
    
        /**
         * {@inheritDoc}
         */
        public function getFilterConfig()
        {
            return [
                'invokables' => [
                    'myfilter' => \Application\Filter\MyFilter::class,
                ],
            ];
        }
    }

    Но он не работает, да и вообще было бы странным, если работал. Всегда полагал, что нет разницы в том, где объявлять: в методах модуля или module.config.php
    Ответ написан
    Комментировать
  • Как правильно сделать динамическую форму с помощью zf2?

    27cm
    @27cm
    TODO: Написать статус
    Сделать можно.

    В Zend Framework 2 есть элемент формы Collection. В Вашем случае получается, что форма будет состоять из кнопок и коллекции (разделов) коллекций (строк) Fieldset'ов, включающих input'ы, select'ы.

    Пример из документации:
    framework.zend.com/manual/current/en/modules/zend....
    Ответ написан
    Комментировать