Phalcon php pass parameter in constructor - php

I would like to pass parameter to constructor in controller. Is it possible to do ?
I am trying to pass interface defination in constructor.
or is it possible to bind or set constructor in DI ?
below is my code.
<?php
use Phalcon\Repositories\IUsersRepository;
class UsersController extends ControllerBase
{
private $users;
public function __construct(IUsersRepository $usersRepository)
{
$this->users = $usersRepository;
}
?>

I have fixed by using below code in service.php
$di->set('usersRepository', array(
'className' => 'Phalcon\Repositories\UsersRepository'
));
$di->set('UsersController', array(
'className' => 'UsersController',
'arguments' => array(
array('type' => 'service', 'name' => 'usersRepository')
)
));

Yes you can.. take a look...
http://docs.phalconphp.com/en/latest/reference/di.html#instantiating-classes-via-the-service-container
If you want to send data on every request use dispatch Service
$di->set('IndexController', function() {
$component = new Component();
$component->private_method();
return $component;
}, true);
I wonder y u need this method!

Related

Access form request from Observer laravel

I am trying to cleanup my controller. I have a lot form fields so I want to use observer to insert for the other model that have relationship with the main model
I have already successfully insert the request to the database in a controller but it seems to long and heavy. See code below
function insert(Request $request){
$bankStatementName = time().'.'.request()->bankStatement->getClientOriginalExtension();
request()->bankStatement->move(public_path('bankStatement'), $bankStatementName);
$identityName = time().'.'.request()->identity->getClientOriginalExtension();
request()->identity->move(public_path('identity'), $identityName);
$passportName = time().'.'.request()->passport->getClientOriginalExtension();
request()->passport->move(public_path('passport'), $passportName);
$customer = Customer::find(Auth::user()->id);
$relations = new Customer_relationship([
'kinName' => $request->kinName,
'kinGender' => $request->kinGender,
'kinEmail' => $request->kinEmail,
'kinRelation' => $request->kinRelation,
'kinAddress' => $request->kinAddress
]);
$company = new Customer_company([
'compName' => $request->compName,
'compEmail' => $request->compEmail,
'compPhone' => $request->compPhone,
'compAddress' => $request->compAddress
]);
$bank = new Customer_bank([
'accNumber' => $request->accNumber,
'bankName' => $request->bankName,
'accName' => $request->accName
]);
$document = new Customer_document([
'identity' => $identityName,
'bankStatement' => $bankStatementName,
'passport' => $passportName
]);
$customer->relation()->save($relations);
$customer->company()->save($company);
$customer->bank()->save($bank);
$customer->document()->save($document);
Customer::where('user_id', Auth::user()->id)
->update([
'title' => $request->title,
'middlename' => isset($request->middlename) ? $request->middlename : "",
'phone' => $request->phone,
'gender' => $request->gender,
'DOB' => $request->DOB,
'marital' => $request->marital,
'residential_address' => $request->residential_address,
'city' => $request->city,
'state' => $request->state,
'lga' => $request->lga,
'nationality' => $request->nationality,
'complete_registration' => 1 ]);
}
So how can I access the form request field from Updating function from observer to do a controller cleanup
Welcome to SO!
If you want to use Observers here, you should start by reading up on https://laravel.com/docs/5.8/eloquent#observers and https://laravel.com/docs/5.8/queues
This will likely work if you have all the data needed on your parent model, since you would just pass that model into the job that was triggered by the observer. If not, then observer/job might not be the best solution in your case. Instead I would probably create some sort of service, where you move the responsibility for creating these relationships. That way you can keep a clean controller level that only calls a service to create the models and then returns the result.
An example of this could be:
namespace App\Http\Controllers;
use App\Models\Something\SomeService;
class SomeController extends Controller
{
/**
* #var SomeService
*/
private $someService;
public function __construct(SomeService $someService)
{
$this->someService = $someService;
}
public function store()
{
$request = request();
$name = $request->input('name');
$something = $this->someService->create($name);
return response()->json(['data' => $something]);
}
}
namespace App\Models\Something;
class SomeService
{
public function create(string $name): Something
{
// Do whatever in here...
}
}
This is a simplified example of how I would do it. Hope it helps you a bit.
If you still want to use a job to take care of this, then I still don't think an observer is the right solution for you, as those are triggered on model events, such as created. This mean that you will not have access to the request object at that time, but only was was created (The model). Instead you could dispatch a job directly from the controller/service. That is all described in the queue link I posted at the top of the answer.

How can I access Database Adapter in ZF2 Field Set?

I have followed an example and would like to pass the Database adapter to a fieldset to create a drop down menu.
The code below is how i call the fieldset.
How can i access the database adapter in the BrandFieldset class?
$this->add(array(
'type' => 'Application\Form\BrandFieldset',
'name' => 'brand',
'options' => array(
'label' => 'Brand of the product',
),
));
Instantiating a fieldset is responsibility of the FormElementManager. When you try to access a form, form element or fieldset, the FormElementManager knows where to find and how to create it. This behaviour summerized in Default Services section of the framework.
Since the proper way of accessing form elements is retrieving them from FormElementManager, I would write a BrandFieldsetFactory to inject that DB adapter or further dependencies to fieldset on construction to achieve this.
A ZF3 friendly fieldset factory would look like:
<?php
namespace Application\Form\Factory;
use Application\Form\BrandFieldset;
use Interop\Container\ContainerInterface;
class BrandFieldsetFactory
{
/**
* #return BrandFieldset
*/
public function __invoke(ContainerInterface $fem, $name, array $options = null)
{
// FormElementManager is child of AbstractPluginManager
// which makes it a ContainerInterface instance
$adapter = $fem->getServiceLocator()->get('Your\Db\Adapter');
return new BrandFieldset($adapter);
}
}
At this point, BrandFieldset should extend the Zend\Form\Fieldset\Fieldset and it's constructor may look like following:
private $dbAdapter;
/**
* {#inheritdoc}
*/
public function __construct(My/Db/Adapter $db, $options = [])
{
$this->dbAdapter = $db;
return parent::__construct('brand-fieldset', $options);
}
Finally, in module.config.php file I'd have a configuration to tell FormElementManager about this factory:
<?php
use Application\Form\BrandFieldset;
use Application\Form\Factory\BrandFieldsetFactory;
return [
// other config
// Configuration for form element manager
'form_elements' => [
'factories' => [
BrandFieldset::class => BrandFieldsetFactory::class
],
],
];
HINT: The BrandFieldset::init() method will be called automatically by FormElementManager after construction. You can put any post-initialization logic into this method.
Based of these docs I was able to find a solution.
https://framework.zend.com/manual/2.1/en/modules/zend.form.advanced-use-of-forms.html
'form_elements' => array(
'invokables' => array(
'fieldset' => BrandFieldsetFactory::class
)
)
I needed to call the form using the service locator in the controller like below.
$sl = $this->getServiceLocator();
$form = $sl->get('FormElementManager')->get('Application\Form\CreateForm');
In addition I changed the __construct to init.

Using REST controllers in Zend Framework 2 - map additional “action” methods (e.g. create form)

I want to use REST controllers in my website to map to routes similar to the following:
GET /article
GET /article/1
GET /article/create
GET /article/1/update
GET /article/1/delete
POST /article
PUT /article/1
DELETE /article/1
My controller is:
namespace Article\Controller;
// use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\Controller\AbstractRestfulController;
use Zend\View\Model\ViewModel;
use Article\Form\ArticleForm;
use Article\Model\Article;
class ArticleController extends AbstractRestfulController
{
protected $articleTable;
public function getList()
{
return new ViewModel(array(
'articles' => $this->getArticleTable()->fetchAll(),
));
}
public function get($id)
{
return new ViewModel(array(
'article' => $this->getArticleTable()->getArticle($id),
));
}
public function create()
{
$form = new ArticleForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$article = new Article();
$form->setInputFilter($article->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$article->exchangeArray($form->getData());
$this->getArticleTable()->saveArticle($article);
// Redirect to list of articles
return $this->redirect()->toRoute('article');
}
}
return array('form' => $form);
}
public function update()
{
//...
}
public function delete()
{
//...
}
public function getArticleTable()
{
if (!$this->articleTable) {
$sm = $this->getServiceLocator();
$this->articleTable = $sm->get('Article\Model\ArticleTable');
}
return $this->articleTable;
}
}
My module.config.php routes are as following:
'router' => array(
'routes' => array(
'article' => array(
'type' => 'segment',
'options' => array(
'route' => '/article[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Article\Controller\Article',
),
),
),
With the AbstractRestfulController I can achieve the first two GETs, POST and DELETE; but, I don't know how to get the following routes (which will render as forms):
GET /article/create .. maps to ArticleController::create
GET /article/1/update .. maps to ArticleController::update
GET /article/1/delete .. maps to ArticleController::delete
I read in the docs: "Additionally, you can map “action” methods to the AbstractRestfulController, just as you would in the AbstractActionController; these methods will be suffixed with “Action”, differentiating them from the RESTful methods listed above. This allows you to perform such actions as providing forms used to submit to the various RESTful methods, or to add RPC methods to your RESTful API." .. but I can't see an example, and I tried adding a createAction but route not found. I guess my router configuration needs modified?

Laravel 5.1 ERROR Call to undefined function App\Http\Controllers\Auth\sendRegistermail()

I am trying to send automated mails via Mandrill in my Laravel 5.1 project. It was working but I was setting up my Mandrill Calls in my AuthController now I wanna have a class App\Marketing where all my functions for sending email will be stored. So in my controllers after an actions happens I can just call up the function with 1 line of code, but this line is giving me troubles I think.
my App\Marketing class looks like this now
class Marketing{
private $mandrill;
/**
* Via construct injection
*
*/
public function __construct(Mail $mandrill)
{
$this->mandrill = $mandrill;
}
public function sendRegistermail()
{
// In template content you write your dynamic content if you use <mc:edit> tags.
$template_content = [];
$message = array(
'subject' => 'Welkom bij SP*RK! - Jouw accountgegevens',
'from_email' => 'noreply#spark.com',
'from_name' => 'SP*RK',
'to' => array(
array(
'email' => $request->input('email'),
'name' => $request->input('name'),
'type' => 'to'
)
),
'merge_vars' => array(
array(
'rcpt' => $request->input('email'),
'vars' => array(
array(
'name' => 'NAME',
'content' => $request->input('name')
),
array(
'name' => 'EMAIL',
'content' => $request->input('email')
)
)
)
)
);
//email validation
if (str_contains($request['email'], "#kuleuven.be")) {
MandrillMail::messages()->sendTemplate('registration-mail', $template_content, $message);
} else {
MandrillMail::messages()->sendTemplate('registration-mail-notactive', $template_content, $message);
}
}
// ----- OR -------
/**
* Via method injection
*
*/
public function sendMail(Mail $mandrill, $data)
{
$mandrill->messages()->sendTemplate($data)
}
// ----- OR -------
/**
* Via the Facade
*
*/
public function sendMailByFacade($data)
{
\MandrillMail::messages()->sendTemplate($data);
}
}
This is how I try to call the function after registration in my postRegister function:
sendRegistermail();
return redirect($this->redirectPath());
sendRegistermail is a method of your Marketing class, you should call it on an instance of that object
So, first of all you have to create a Marketing object instance in your controller. A good way to do this it's by injecting the dependency in the constructor, like this:
//your controller class
class Controller
{
protected $marketing;
//Your controller's constructor
public function __construct(Marketing $marketing)
{
$this->marketing = $marketing;
}
}
Or you can use one of the other methods you have provided in your code to inject the instance.
Once you have an instance of the Marketing class, you only need to call the sendRegistermail method on that instance. In your controller method:
//call the method on the marketing instance
$this->marketing->sendRegistermail();

Zend 2 Dynamic Content in Layout with View Helpers

I'm new in Zend FW 2 and I try to showing data from database in layout but I receive error:
Catchable fatal error: Argument 1 passed to Application\View\Helper\HotNews::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\htdocs\webtruonghoc\vendor\ZF2\library\Zend\ServiceManager\AbstractPluginManager.php on line 207 and defined in C:\xampp\htdocs\webtruonghoc\module\Application\src\Application\View\Helper\HotNews.php on li
Function getViewHelperConfig in Module.php:
public function getViewHelperConfig()
{
return array(
'factories' => array(
'hotNews' => function($sm) {
$adapter = $sm->getServiceLocator()->get('Application\Model\NewsTable');
return new HotNews($adapter);
},
),
);
}
Add code in module.config.php:
'view_helpers' => array(
'invokables' => array(
'hotnews' => 'Application\View\Helper\HotNews',
),
File HotNews.php:
<?php
namespace Application\View\Helper;
use Zend\Authentication\AuthenticationService;
use Zend\View\Helper\AbstractHelper;
use Zend\Db\Adapter\Adapter;
class HotNews extends AbstractHelper
{
protected $adapter;
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
}
public function __invoke()
{
$sql="SELECT * FROM news order by date DESC limit 0,4";
return $resultSet = $this->adapter->query($sql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
}
}
and final I showing data in layout:
<?php $hotnews = $this->hotNews();
var_dump($hotnews);
?>
Do I miss something?
It looks like you are expecting your model to be set up as a service. but may not have set up the service correctly. In your module.config.php file, there should be an entry under 'service_manager' => 'factories' :
return array(
'service_manager' => array(
'factories' => array(
'Application\Model\NewsTable' => function (ServiceLocatorInterface $serviceLocator) {
//... returns an instance of Application\Model\NewsTable
}
)
)
);
Your SQL has an error in it. Also, you should not be executing SQL statements inside a view helper, and passing the entire result set of a select * to the view is bad JuJu as well. I would place the SQL inside a Repository class which returns DTO objects representing your data model. You could then inject the repository into your ViewHelper and and use those DTOs in your view.

Categories