Cakephp 3: how to implement events in helper - cakephp

in Cakephp 3 im trying to implement events in the helper class, this is example of what im trying to do:
protected $_View;
public function __construct(View $View, $config = [])
{
//debug($View);die;
$this->_View = $View;
parent::__construct($View, $config);
$this->_setupEvents();
}
/**
* setup events
*/
protected function _setupEvents() {
$events = [
'filter' => [$this, 'filter'],
];
foreach ($events as $callable) {
$this->_View->eventManager()->on("Helper.Layout.beforeFilter", $callable);
}
}
public function filter(&$content, $options = array()) {
preg_match_all('/\[(menu|m):([A-Za-z0-9_\-]*)(.*?)\]/i', $content, $tagMatches);
for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
$regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))+.)[\'"]?/i';
preg_match_all($regex, $tagMatches[3][$i], $attributes);
$menuAlias = $tagMatches[2][$i];
$options = array();
for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
$options[$attributes[1][$j]] = $attributes[2][$j];
}
$content = str_replace($tagMatches[0][$i], $this->menu($menuAlias, $options), $content);
}
return $content;
}
But im getting warning for the line where im calling constructor of parent Helper class:
Warning (4096): Argument 1 passed to App\View\Helper\MenusHelper::__construct() must be an instance of App\View\Helper\View, instance of App\View\AppView given, called in C:\wamp\www\CookieCMS\vendor\cakephp\cakephp\src\View\HelperRegistry.php on line 142 and defined [APP/View\Helper\MenusHelper.php, line 26]
Is it possible to implement events in helper this way and what is it that im doing wrong?

The Helper class is already implements EventlistenerInterface, so as explained in the manual all you have to do in your custom helper is return a proper array with required event name to callback mapping from implementedEvents() method.
So something like:
public function implementedEvents()
{
$mapping = parent::implementedEvents();
$mapping += [
'Helper.Layout.beforeFilter' => 'someMethodOfYourHelper',
];
return $mapping;
}

Related

controller store function array laravel 5.5

I need some help. I have a problem with store function with array in laravel. When I submit my form, I got error massage that "ksort() expects parameter 1 to be array, string given".
This is my store function :
public function store(request $request) {
$input=$request->all();
$images=array();
$total = count($request->path_scan_ijazah);
// return $total;
if($files=$request->file('path_scan_ijazah')){
for ($i=0; $i < $total; $i++) {
$nip[] = $request->nip;
$instansi[] = $request['nama_instansi_pendidikan'][$i];
$jurusan[] = $request['nama_jurusan'][$i];
$jenjang[] = $request['jenjang_pendidikan'][$i];
$gelar[] = $request['gelar'][$i];
$thn_masuk = $request['tahun_masuk'][$i];
$thn_lulus = $request['tahun_lulus'][$i];
$path = $request['path_scan_ijazah'][$i]->store('public/upload/ijazah');
$images[] = $path;
$data[] = Education::insert([
'nip_employee' => $nip,
'nama_instansi_pendidikan' => $instansi,
'nama_jurusan' => $jurusan,
'jenjang_pendidikan' => $jenjang,
'gelar' => $gelar,
'tahun_masuk' => $thn_masuk,
'tahun_lulus' => $thn_lulus,
'path_scan_ijazah' => $images
]);
}
// dd($data);
}
Please help me, what should I do?

Persist array store in session symfony

It's been several days since I've been blocking to persist items from an order into session to database.
I stock articles in session in an array and I do not know how to persist the array. I try to convert the array into an object, I can not. This is my service:
public function addArticle($id)
{
$sessionCart = $this->session;
$article = $this->doctrine->getRepository('AppBundle:Article')->find($id);
$cart = $sessionCart->get('cart');
$cart[] = $article;
$sessionCart->set('cart', $cart);
// use later for delivery
$sessionCart->get('commande');
return $sessionCart;
}
public function panier()
{
$articles = $this->session->get('cart');
return $articles;
}
public function delivery(Request $request)
{
$commande = new Commande();
$articles = $this->session->get('cart');
$form = $this->form->create(CommandeType::class, $commande);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid())
{
$data = $form->getData();
$this->session->set('commande', $data);
$response = new RedirectResponse('payment');
$response->send();
}
return [$form, $articles];
}
public function payment(Request $request)
{
$articles = $this->session->get('cart');
$commande = $this->session->get('commande');
if ($request->isMethod('POST')) {
$em = $this->doctrine;
$em->persist($articles);
$em->persist($commande);
$em->flush();
}
return[$articles, $commande];
}
Error : "EntityManager#persist() expects parameter 1 to be an entity object, array given."
The order is persisted but not the items.
Thanks
I can't understand these two lines
$cart = $sessionCart->get('cart');
$cart[] = $article;
$sessionCart->set('cart', $cart);
$cart is an array and should be an entity isn't it ?
The persist is waiting for an entity,
maybe you can persist in a foreach loop:
foreach($articles as $article){
$em->persist($article);
}
or use a doctrineCollection instead of an array

Get file information form directory Laravel

I use the following method to get all files from a folder and my method returns some basic information about the files inside directory
public function getUploaded()
{
$files = [];
$filesInFolder = File::files(base_path() .'/'. self::UPLOAD_DIR);
foreach($filesInFolder as $path)
{
$files[] = pathinfo($path);
}
return response()->json($files, 200);
}
How would I get the size and the base name like ?
$files['name'] = ....
$files['size'] = ....
You could solve this quite neatly with a Laravel collection and SplFileInfo. Something along the following lines;
public function getUploaded()
{
$files = collect(File::files(base_path() . "/" . self::UPLOAD_DIR))->map(function ($filePath) {
$file = new \SplFileInfo($filePath);
return [
'name' => $file->getName(),
'size' => $file->getSize(),
];
});
return response()->json($files);
}
You can modify your code as follows:
foreach ($filesInFolder as $path) {
$file = pathinfo($path);
$file['size'] = File::size($path);
$file['name'] = File::name($path);
$files[] = $file;
}

Declaration of Upload::beforeSave() should be compatible with Model::beforeSave($options = Array) [APP/Model/Upload.php, line 5]

I am being shown the following error on top of my page when using beforeSave method in my Upload model.
Strict (2048): Declaration of Upload::beforeSave() should be
compatible with Model::beforeSave($options = Array)
[APP/Model/Upload.php, line 5]
Could someone point out what I'm doing wrong?
Here is my model:
<?php
App::uses('AppModel', 'Model');
class Upload extends AppModel {
protected function _processFile() {
$file = $this->data['Upload']['file'];
if ($file['error'] === UPLOAD_ERR_OK) {
$name = md5($file['name']);
$path = WWW_ROOT . 'files' . DS . $name;
if (is_uploaded_file($file['tmp_name'])
&& move_uploaded_file($file['tmp_name'], $path) ) {
$this->data['Upload']['name'] = $file['name'];
$this->data['Upload']['size'] = $file['size'];
$this->data['Upload']['mime'] = $file['type'];
$this->data['Upload']['path'] = '/files/' . $name;
unset($this->data['Upload']['file']);
return true;
}
}
return false;
}
public function beforeSave() {
if (!parent::beforeSave($options)) {
return false;
}
return $this->_processFile();
}
}
?>
Just change this line
public function beforeSave() {
to this, so you have correct method declaration
public function beforeSave($options = array()) {
The beforeSave() function executes immediately after model data has been successfully validated, but just before the data is saved. This function should also return true if you want the save operation to continue.
This callback is especially handy for any data-massaging logic that needs to happen before your data is stored. If your storage engine needs dates in a specific format, access it at $this->data and modify it.
Below is an example of how beforeSave can be used for date conversion. The code in the example is used for an application with a begindate formatted like YYYY-MM-DD in the database and is displayed like DD-MM-YYYY in the application. Of course this can be changed very easily. Use the code below in the appropriate model.
public function beforeSave($options = array()) {
if (!empty($this->data['Event']['begindate']) &&
!empty($this->data['Event']['enddate'])
) {
$this->data['Event']['begindate'] = $this->dateFormatBeforeSave(
$this->data['Event']['begindate']
);
$this->data['Event']['enddate'] = $this->dateFormatBeforeSave(
$this->data['Event']['enddate']
);
}
return true;
}
public function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString));
}
Make sure that beforeSave() returns true, or your save is going to fail.

Using session component in custom component

I'm trying to use Session component in custom component (CakePHP 2.3) but when I call Session component functions I get: Fatal error: Call to a member function read() on a non-object in ...\app\Controller\Component\CartComponent.php on line 7
My CartComponent looks like that:
<?php
App::uses('Component', 'Controller');
class CartComponent extends Component {
public $components = array('Session');
function hasItems() {
$cart = $this->Session->read('Cart');
return $cart != null && count($cart) > 0;
}
}
?>
And I use it in controller:
<?php
class OrdersController extends AppController {
public $name = 'Orders';
public $components = array('Cart', 'Email');
function beforeFilter() {
parent::beforeFilter();
if ($this->Cart->hasItems()) {
$this->Auth->allow('add_item', 'remove_item', 'cart');
} else {
$this->Auth->allow('add_item', 'remove_item', 'cart', 'make');
}
}
}
?>
For using session inside the custom component I tried with
public $components = array('Session');
and then called it by using
$this->Session->read('Cart');
but I cant able to use it and I start to use
CakeSession::read('Cart')
Now it works Hope it will used for you note I used in cake php version > 2
If you want to use Session in your Component Use-
$test = CakeSession::read('user');
print_r($test);
You should use as bellow
class YourComponent extends Component {
public function initialize(Controller $controller){
$this->controller = $controller;
if (!isset($this->controller->presetVars)) {
$this->controller->presetVars = true;
}
$model = $this->controller->modelClass;
if (!empty($settings['model'])) {
$model = $settings['model'];
}
if ($this->controller->presetVars === true) {
// auto-set the presetVars based on search definitions in model
$this->controller->presetVars = array();
$filterArgs = array();
if (!empty($this->controller->$model->filterArgs)) {
$filterArgs = $this->controller->$model->filterArgs;
}
foreach ($filterArgs as $key => $arg) {
if ($args = $this->_parseFromModel($arg, $key)) {
$this->controller->presetVars[] = $args;
}
}
}
foreach ($this->controller->presetVars as $key => $field) {
if ($field === true) {
if (isset($this->controller->$model->filterArgs[$key])) {
$field = $this->_parseFromModel($this->controller->$model->filterArgs[$key], $key);
} else {
$field = array('type' => 'value');
}
}
if (!isset($field['field'])) {
$field['field'] = $key;
}
$this->controller->presetVars[$key] = $field;
}
/* now you can use Component existing in your Component :) */
public function sayHello(){
$this->controller->Session->setFlash(__('Hello you'));
}
}

Resources