Here is my code:
// Yoda namespace
namespace Yoda\Application\Config\Feature;
// use zend config
use Zend\Config\Config;
// CacheConfig class
class CacheConfig extends Config
{
/**
* Default cache type for now
*
* #var string
*/
const DEFAULT_CACHE_TYPE = 'filesystem';
/**
* Default cache ttl for now
*
* #var integer
*/
const DEFAULT_CACHE_TTL = 3600;
/**
* Constructor. Creates config data for caching
*/
public function __construct()
{
$config=[
'name'=> static::DEFAULT_CACHE_TYPE,
'options' => [
'ttl' => static::DEFAULT_CACHE_TTL,
'cache_dir' => '/var/www/html/yoda/data/cache'
]
];
parent::__construct($config,true);
}
}
When I use this code the application breaks and says The localhost page isn't working however when I just pass the config array into a standard Zend Config object it works fine.
Here's my usage code:
$config=[
'name'=> 'filesystem',
'options' => [
'ttl' => 3600,
'cache_dir' => '/var/www/html/yoda/data/cache'
]
];
//works fine
$configCache = new Config($config);
//breaks
$configCache = new CacheConfig();
Not sure whats wrong here.
It's because in the Config class the constructor loads a static instance of itself. WHen I did this:
public function __construct()
{
$config=[
'name'=> static::DEFAULT_CACHE_TYPE,
'options' => [
'ttl' => static::DEFAULT_CACHE_TTL,
'cache_dir' => yoda::registry('cache_dir')
]
];
$this->allowModifications = true;
foreach ($config as $key => $value) {
if (is_array($value)) {
$this->data[$key] = new Config($value, $this->allowModifications);
} else {
$this->data[$key] = $value;
}
}
}
It seems to work when I replace it with Config
Instead of modifying zend config class you can do following in your configCache constructor. When config class will call cache class with array you pass the control back to config class with received array. It will then set the config object properly.The error is because of Static Bindings.
/**
* Constructor. Creates config data for caching
*/
public function __construct( $arr = [])
{
$config=[
'name'=> static::DEFAULT_CACHE_TYPE,
'options' => [
'ttl' => static::DEFAULT_CACHE_TTL,
'cache_dir' => '/var/www/html/yoda/data/cache'
]
];
if (count($arr) > 0)
{
parent::__construct($arr,true);
}
else
{
parent::__construct($config,true);
}
}
$configCache = new CacheConfig();
print_r($configCache);
Related
Hi I'm new to Laravel framework and I'm trying to inject process ID into every log passed to Google Logging service.
I've been able to see the log passed into Google Logging service now, but I've no idea how I could inject more info(Process ID in this case) into my log message.
So far I've tried "tap" method and I can see addition info injected into my log while reading laravel.log file, but same method doesn't seems to work while using Google Cloud Logging plugin.
Below is my script for Google Logging service.
Inside config/logging.php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['stackdriver'],
],
'stackdriver' => [
'driver' => 'custom',
'via' => App\Logging\CreateStackdriverLogger::class,
'level' => 'debug',
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'tap' => [App\Logging\ProcessorTap::class],
],
];
CreateStackdriverLogger.php
use Google\Cloud\Logging\LoggingClient;
use Monolog\Handler\PsrHandler;
use Monolog\Logger;
class CreateStackdriverLogger
{
/**
* Create a custom Monolog instance.
*
* #param array $config
* #return \Monolog\Logger
*/
public function __invoke(array $config)
{
$logName = isset($config['logName']) ? $config['logName'] : 'app';
$psrLogger = LoggingClient::psrBatchLogger($logName);
$handler = new PsrHandler($psrLogger);
$logger = new Logger($logName, [$handler]);
return $logger;
}
}
Code for 'tap' method, I'm able to see 'pid' inside 'extra', but same method don't work with 'stackdriver'.
ProcessorTab.php
namespace App\Logging;
use Illuminate\Log\Logger;
use Illuminate\Support\Arr;
use Monolog\Formatter\LineFormatter;
class ProcessorTap
{
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->pushProcessor(function ($record) {
return Arr::add($record, 'prefix', getmypid());
});
$handler->setFormatter($this->getLogFormatter());
$handler->pushProcessor([$this, 'processLogRecord']);
}
}
public function processLogRecord(array $record): array
{
$record['extra'] += [
'pid' => getmypid(),
];
return $record;
}
protected function getLogFormatter()
{
$format = "[%datetime%] %channel%.%level_name%: %prefix%.%message% %context% %extra%\n";
return new LineFormatter($format, null, true, true);
}
}
In my laravel application there's need to format a message I need to send into slack. Hence I set a slack log channel into config/logging.php:
'slack' => [
'driver' => 'slack',
'url' => /*Censored Hook URL*/,
'username' => 'MyApp',
'emoji' => ':gear:',
'level' => 'debug',
],
Also as seen on documentation I can do a monolog formater, hence I did the following:
namespace App\Logging;
class SlackLogFormatter
{
/**
* Customize the given logger instance.
*
* #param \Illuminate\Log\Logger $logger
* #return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(...);
}
}
}
And specified it as tap into my log:
'slack' => [
'driver' => 'slack',
'tap' => [App\Logging\SlackLogFormatter::class]
'url' => /*Censored Hook URL*/,
'username' => 'MyApp',
'emoji' => ':gear:',
'level' => 'debug',
],
But in my formater where do I process the log entry itself? I mean:
The $handler->setFormatter does not seem to be a method of \Illuminate\Log\Logger class.
I cannot find out what method I need to override when I need to provide a custom format. I mean I have the invoke method then afterwards what?
Dimitrios is almost right (or perhaps this worked on older versions) but as Xavier said, if you copy that code exactly you will get the error
Return value of Monolog\Handler\AbstractProcessingHandler::processRecord() must be of the type array, null returned
You are going to want to do something like this instead :
<?php
namespace App\Logging;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\SlackWebhookHandler;
use Request;
class CustomiseFormatter
{
protected $request;
public function __construct(Request $request = null)
{
$this->request = $request;
}
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
if ($handler instanceof SlackWebhookHandler) {
$handler->setFormatter(new LineFormatter(
'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
));
$handler->pushProcessor([$this, 'processLogRecord']);
}
}
}
public function processLogRecord(array $record): array
{
$record['extra'] += [
'url' => env("APP_URL"),
];
return $record;
}
}
Equally, as with how extra has be modified, you can change any other value.
The formatter for slack should be the following:
namespace App\Logging;
use Monolog\Formatter\LineFormatter;
class SlackLogFormatter
{
/**
* Customize the given logger instance.
*
* #param \Illuminate\Log\Logger $logger
* #return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
if ($handler instanceof SlackWebhookHandler) {
$format=""; // Look on the Monolog's Line formatter documentation
$formatter= new LineFormatter($format,"Y-m-d H:i:s");
$handler->pushProcessor(function ($record) {
//Append extra info of formatting here
});
$handler->setFormatter($formatter);
}
}
}
}
And config the slack not to send attachment nessesary for the formatter to work:
'slack' => [
'driver' => 'slack',
'tap' => [App\Logging\SlackLogFormatter::class]
'url' => /*Censored Hook URL*/,
'username' => 'MyApp',
'emoji' => ':gear:',
'level' => 'debug',
'attachment' => FALSE,
],
The setFormatter method takes a new Monolog Formatter as seen in: https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md#formatters
Also the pushProcessor allows you to populate extra fields on your message eg. Showing an emoji on your log message:
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
if ($handler instanceof SlackWebhookHandler) {
$format="%emoji% %message%";
$formatter= new LineFormatter($format,"Y-m-d H:i:s");
$handler->pushProcessor(function ($record) {
$record['emoji']=":poop:";
});
$handler->setFormatter($formatter);
}
}
}
I'm trying to implement my zend navigation from a container in ZF3. I have successfully created navigation with this quick start tutorial introducing navigation directly in config/autoload/global.php or config/module.config.php files:
https://docs.zendframework.com/zend-navigation/quick-start/
But now I need to make it work these with the helpers to allow navigation modifications from the controller, using the "Navigation setup used in examples" section:
https://docs.zendframework.com/zend-navigation/helpers/intro/
This is my Module.php
namespace Application;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\View\HelperPluginManager;
class Module implements ConfigProviderInterface
{
public function getViewHelperConfig()
{
return [
'factories' => [
// This will overwrite the native navigation helper
'navigation' => function(HelperPluginManager $pm) {
// Get an instance of the proxy helper
$navigation = $pm->get('Zend\View\Helper\Navigation');
// Return the new navigation helper instance
return $navigation;
}
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
$this->getViewHelperConfig()
);
},
],
];
}
}
And this is my IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Navigation\Navigation;
use Zend\Navigation\Page\AbstractPage;
class IndexController extends AbstractActionController
{
private $navigationHelper;
public function __construct(
$navigationHelper
){
$this->navigationHelper = $navigationHelper;
}
public function indexAction()
{
$container = new Navigation();
$container->addPage(AbstractPage::factory([
'uri' => 'http://www.example.com/',
]));
$this->navigationHelper->plugin('navigation')->setContainer($container);
return new ViewModel([
]);
}
}
But then I get the following error:
Fatal error: Call to a member function plugin() on array in /var/www/html/zf3/module/Application/src/Controller/IndexController.php on line 50
In the tutorial they use the following statement:
// Store the container in the proxy helper:
$view->plugin('navigation')->setContainer($container);
// ...or simply:
$view->navigation($container);
But I don´t know what this $view is, so I assume is my $navigation from my Module.php. The problem is that, because is an array, it throws the error. The questions are:
What am I doing wrong?
Where this $view of the tutorial come from?
What I should pass from my Module.php to get it work?
Thanks in advance!
Add into module.config.php
'service_manager' => [
'factories' => [
Service\NavManager::class => Service\Factory\NavManagerFactory::class,
],
],
'view_helpers' => [
'factories' => [
View\Helper\Menu::class => View\Helper\Factory\MenuFactory::class,
],
'aliases' => [
'mainMenu' => View\Helper\Menu::class,
],
],
Create Factory in Service Directory:
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Application\Service\NavManager;
class NavManagerFactory {
/**
* This method creates the NavManager service and returns its instance.
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$authService = $container->get(\Zend\Authentication\AuthenticationService::class);
$viewHelperManager = $container->get('ViewHelperManager');
$urlHelper = $viewHelperManager->get('url');
return new NavManager($authService, $urlHelper);
}
}
Create NavManager file :
namespace Application\Service;
class NavManager {
/**
* Auth service.
* #var Zend\Authentication\Authentication
*/
private $authService;
/**
* Url view helper.
* #var Zend\View\Helper\Url
*/
private $urlHelper;
/**
* Constructs the service.
*/
public function __construct($authService, $urlHelper) {
$this->authService = $authService;
$this->urlHelper = $urlHelper;
}
/**
* Menu render based on user role
*
* #return array
*/
public function getMenuItems() {
$navItem = array();
$url = $this->urlHelper;
$items = [];
$items[] = [
'label' => 'Dashboard',
'icon' => 'dashboard',
'link' => $url('home'),
'route' => ['home'],
];
$items[] = [
'label' => 'About Us',
'icon' => 'business',
'link' => $url('about', ['action'=>'index']),
'route' => ['about'],
];
$items[] = [
'label' => 'Service',
'icon' => 'service',
'link' => $url('service', ['action'=>'index']),
'route' => ['service'],
];
return $items;
}
Create Helper Factory
namespace Application\View\Helper\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\View\Helper\Menu;
use Application\Service\NavManager;
/**
* This is the factory for Menu view helper. Its purpose is to
instantiate the helper and init menu items. */
class MenuFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$navManager = $container->get(NavManager::class);
// Get menu items.
$items = $navManager->getMenuItems();
// Instantiate the helper.
return new Menu($items);
}
}
Create Helper :
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
/**
* This view helper class displays a menu bar.
*/
class Menu extends AbstractHelper {
/**
* Menu items array.
* #var array
*/
protected $items = [];
/**
* Active item's ID.
* #var string
*/
protected $activeItemId = '';
/**
* Constructor.
* #param array $items Menu items.
*/
public function __construct($items=[]) {
$this->items = $items;
}
/**
* Sets menu items.
* #param array $items Menu items.
*/
public function setItems($items) {
$this->items = $items;
}
/**
* Sets ID of the active items.
* #param string $activeItemId
*/
public function setActiveItemId($activeItemId) {
$this->activeItemId = $activeItemId;
}
/**
* Renders the menu.
* #return string HTML code of the menu.
*/
public function render() {
if (count($this->items)==0) {
return ''; // Do nothing if there are no items.
}
// Render items
foreach ($this->items as $item) {
$result .= $this->renderItem($item);
}
return $result;
}
protected function renderItem($item) {
// here you can integrate with HTML
return $item;
}
}
After add above codes,just add below code in your layout file :
echo $this->mainMenu()->render();
Can implement dynamic validation on element level? I used this example to implement validation of one element dependent on the value of the other element. But for this purpose I'll need to implement this for every single form where I use this element (comment) with this validation. I have many forms like that. Is there way to do the following:
to take this filter/validation logic to the element level using some kind of "data-comment-for" attribute and retrieving the value of the element on which it depends from the parent form.
This is my current code (but I need to have it for every form now. It does not look elegant at all) :
class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends InputFilter
{
public function isValid($context = null)
{
$figradeCommentName = 'applJusticeFIGrade'.'Comment';
$forGrade = $this->get('applJusticeFIGrade');
$gradeComment = $this->get($figradeCommentName);
$applJusticeFIGradeRawValue = $forGrade->getRawValue('applJusticeFIGrade');
if(is_numeric($applJusticeFIGradeRawValue)){
$gradeValue = intval($applJusticeFIGradeRawValue);
}else{
$gradeValue = $applJusticeFIGradeRawValue;
}
if ($gradeValue != 'na' && $gradeValue > 0) {
$gradeComment->setRequired(true);
$validatorChain = new Validator\ValidatorChain();
$validatorChain->attach(
new Validator\NotEmpty(),
true
);
$gradeComment->setValidatorChain($validatorChain);
}
return parent::isValid($context);
}
public function __construct(){
$this->add(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));
$this->add(array(
'name' => 'studEvalId',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));
}
}
EDIT:
I added code for the custom element to the question. There are some "leftovers" of my attempts to place this logic to the element level.
Comment Element
class Comment extends Element implements InputProviderInterface
{
/**
* #var ValidatorInterface
*/
protected $validator;
// set its type
protected $attributes = array(
'type' => 'comment'
);
public function init()
{
if (null === $this->validator) {
$validator = new StringLength();
$validator->setMax(10);
$validator->setMessage('The comment should not exceed 1000 letters!', StringLength::INVALID);
$this->validator = $validator;
}
}
/**
* Get a validator if none has been set.
*
* #return ValidatorInterface
*/
public function getValidator()
{
return $this->validator;
}
/**
* #param ValidatorInterface $validator
* #return $this
*/
public function setValidator(ValidatorInterface $validator)
{
$this->validator = $validator;
return $this;
}
/**
* remove require and validator defaults because we have none
*
* #return array
*/
public function getInputSpecification()
{
// return array(
// 'name' => $this->getName(),
// 'required' => false,
// 'validators' => array(
// $this->getValidator(),
// ),
// 'filters' => array(
// new FIGradeCommentDynamicBufferFilter()
// ),
// );
return array(
'name' => $this->getName(),
'required' => false,
'filters' => array(
array('name' => 'Zend\Filter\StringTrim'),
),
'validators' => array(
$this->getValidator(),
),
);
}
// tell it where to find its view helper, so formRow and the like work correctly
public function getViewHelperConfig()
{
return array('type' => '\OnlineFieldEvaluation\View\Helper\FormComment');
}
}
You could make a base abstract input-filter class and an interface and make all your form filters extend the base class that implements the interface with the methods you expect inside your form classes to make the thing work correctly.
Make an interface with the methods:
interface GradeCommentFormFilterInterface()
{
protected function getGradeInput();
protected function getCommentInput();
}
Then you move the common code to your base class:
abstract class BaseGradeCommentFormFilter extends InputFilter implements GradeCommentFormFilterInterface
{
protected function getGradeInput()
{
return $this->get(static::GRADE_NAME);
}
protected function getCommentInput()
{
return $this->get(static::GRADE_NAME . 'Comment');
}
public function isValid($context = null)
{
$gradeInput = $this->getGradeInput();
$commentInput = $this->getCommentInput();
$rawValue = $this->getRawValue($gradeInput);
if(is_numeric($rawValue))
{
$gradeValue = intval($rawValue);
}
else
$gradeValue = $rawValue;
if ($gradeValue != 'na' && $gradeValue > 0) {
$commentInput->setRequired(true);
$validatorChain = new Validator\ValidatorChain();
$validatorChain->attach(
new Validator\NotEmpty(),
true
);
$commentInput->setValidatorChain($validatorChain);
}
return parent::isValid($context);
}
}
Now you can use your abstract class like this:
class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends BaseGradeCommentFormFilter
{
const GRADE_NAME = 'applJusticeFIGrade';
//... other code
}
I quickly tried to make it work for your case, but this isn't tested, and probably there are ways to optimize this, but it gives you an idea of what you can do.
I am creating a form which needs dynamic options based on the route value of survey_question_reference
'main-surveyquestions'=> [
'type' => 'segment',
'options' => [
'route' => '/survey-questions[/:survey_question_reference][/:answer]',
'constraints' => [
'survey_question_reference' => '[0-9]*',
'answer' => '(answer)',
],
'defaults' => [
'controller' => 'Main\Controller\Main',
'action' => 'surveyquestions'
]
]
],
This is the Form code which calls the FormElement:
/**
* Init
*/
public function init()
{
/**
* Survey Answer
*/
$this->add(
[
'type' => 'Main\Form\Element\SurveyAnswerRadio',
'name' => 'survey_answer',
'options' => [
'label' => 'survey_answer'
],
'attributes' => [
'id' => 'survey_answer'
]
]
);
}
The following is the code from the Form Element. Where I have hard coded 'sqReference' => '1' the 1 needs to be replaced with the value of survey_question_reference from the route.
namespace Main\Form\Element;
use Doctrine\ORM\EntityManager;
use Zend\Form\Element\Radio;
/**
* Class SurveyAnswerRadio
*
* #package Main\Form\Element
*/
class SurveyAnswerRadio extends Radio
{
/**
* #var EntityManager $entityManager
*/
protected $entityManager;
/**
* #param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* Get Value Options
*
* #return array
*
* #throws \Exception
*/
public function getValueOptions()
{
$array = [];
$result = $this->entityManager
->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
[
'sqReference' => '1'
],
[
'surveyAnswer' => 'ASC'
]
);
if (is_array($result) && count($result) > '0') {
/**
* #var \AMDatabase\Entity\TheVerse\SA $val
*/
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}
return $array;
}
}
What you're looknig for is to inject the survey_question_reference parameter to your FormElement. You could do that as suggested by #kuldeep.kamboj in his answers. But if you don't want to change your approach and keep your custom SurveyAnswerRadio element, you have to make some fiew changes in your code :
Make SurveyAnswerRadio implements Zend\ServiceManager\ServiceLocatorAwareInterface so that you could implement setServiceLocator and getServiceLocator, which are required by the ServiceManager to automatically inject the service locator when the element is instantiated.
Your form should also implements Zend\ServiceManager\ServiceLocatorAwareInterface.
Implement the getFormElementConfig method in your Module.php.
Let’s look through the code now. You'll have something like this :
SurveyAnswerRadio :
class SurveyAnswerRadio extends Radio implements ServiceLocatorAwareInterface
{
//Add these two methods
public function setServiceLocator(ServiceLocatorInterface $sl)
{
$this->serviceLocator = $sl;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function getValueOptions()
{
$array = [];
$serviceManager = $this->serviceLocator->getServiceLocator();
$em = $serviceManager->get('Doctrine\ORM\EntityManager');
$sqReference = $serviceManager->get('application')->getMvcEvent()
->getRouteMatch()->getParam('survey_question_reference');
$result = $em->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
['sqReference' => $sqReference],
['surveyAnswer' => 'ASC']
);
if (is_array($result) && count($result) > '0') {
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}
return $array;
}
}
Module.php :
Implement the getFormElementConfig method as follows. This allows the class ModuleName\Form\Element\SurveyAnswerRadio to be instantiated, or invoked, with the alias SurveyAnswerRadio.
class Module implements FormElementProviderInterface
{
// other stuff .....
public function getFormElementConfig()
{
return array(
'invokables' => array(
'SurveyAnswerRadio' => 'ModuleName\Form\Element\SurveyAnswerRadio'
)
);
}
}
No changes needed in the Form init method let it as it is.
Note that in your controller, you'll have to instantiate the Form via the FormElementManager :
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('ModuleName\Form\YourForm');
Please see more details in the documentation
See also this post which exaplains how to manage dependencies within a custom Select Element in Form.
I will suggest to change approach. First do not try to extends Radio Element which is not necessary at all. You can do same in your Form Class. Second your entity manager also not work in Radio/Form class until your find mechanism to pass.
So I would suggest solutions like below.
First register your form class into as factory in module.config.php
'form_elements' => array(
'factories' => array(
'Main\Form\YourFormName' => function($sm) {
$form = new Form\YourFormName();
$form->setEntityManager($sm->getServiceLocator()->get('Doctrine\ORM\EntityManager'));
$form->setServiceLocator($sm->getServiceLocator());
return $form;
},
),
),
Then implement entityManager and serviceLocator into your form class.
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class YourFormName extends Form implements ObjectManagerAwareInterface, ServiceLocatorAwareInterface
{
protected $entityManager;
protected $serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function setEntityManager(ObjectManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function getEntityManager()
{
return $this->entityManager;
}
Then in init method you have serviceLocator/entityManager is already initialized.
public function init()
{
$routeMatch = $this->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch();
$array = [];
$result = $this->entityManager
->getRepository('AMDatabase\Entity\TheVerse\SA')
->findBy(
[
'sqReference' => $routeMatch->getParam('survey_question_reference')
],
[
'surveyAnswer' => 'ASC'
]
);
if (is_array($result) && count($result) > '0') {
/**
* #var \AMDatabase\Entity\TheVerse\SA $val
*/
foreach ($result as $val) {
$array[$val->getReference()] = $val->getSurveyAnswer();
}
}
$this->add(
[
'type' => 'Zend\Form\Element\Radio',
'name' => 'survey_answer',
'options' => [
'label' => 'survey_answer',
'value_options' => $array,
],
'attributes' => [
'id' => 'survey_answer',
]
]
);