alternatives of controller method - laravel-5.3

I am using this code in my laravel 5.3 project but it says that it is badcallmethodexception , I found that controller method is no longer available in new version , how to write this code?
this is my code:
Route::controller('notifications', 'NotificationController');
inside this controller there is this code:
public function getIndex()
{
return view('notification');
}
public function postNotify(Request $request)
{
$notifyText = e($request->input('notify_text'));
}

If you are not using default laravel controller methods you need to define which method should be called for route.
Route::get('notifications', 'NotificationController#getIndex');
Route::post('notifications', 'NotificationController#postNotify');

Write route as :
Route::post('notification','NotificationController#method-name');
Here post is method type that you can use as per your requirement. or else you can use resource as
Route::resource('notification','NotificationController');
Resource can be used only for index,create,store,update and destroy method.
Laravel document : https://laravel.com/docs/5.3/controllers#resource-controllers

Related

Api-Platform: using PUT for creating resources

I would like to use the PUT method for creating resources. They are identified by an UUID, and since it is possible to create UUIDs on the client side, I would like to enable the following behaviour:
on PUT /api/myresource/4dc6efae-1edd-4f46-b2fe-f00c968fd881 if this resource exists, update it
on PUT /api/myresource/4dc6efae-1edd-4f46-b2fe-f00c968fd881 if this resource does not exist, create it
It's possible to achieve this by implementing an ItemDataProviderInterface / RestrictedDataProviderInterface.
However, my resource is actually a subresource, so let's say I want to create a new Book which references an existing Author.
My constructor looks like this:
/**
* Book constructor
*/
public function __construct(Author $author, string $uuid) {
$this->author = $author;
$this->id = $uuid;
}
But I don't know how to access the Author entity (provided in the request body) from my BookItemProvider.
Any ideas?
In API Platform many things that should occur on item creation is based on the kind of request it is. It would be complicated to change.
Here are 2 possibilities to make what you want.
First, you may consider to do a custom route and use your own logic. If you do it you will probably be happy to know that using the option _api_resource_class on your custom route will enable some listeners of APIPlaform and avoid you some work.
The second solution, if you need global behavior for example, is to override API Platform. Your main problem for this is the ReadListener of ApiPlatform that will throw an exception if it can't found your resource. This code may not work but here is the idea of how to override this behavior:
class CustomReadListener
{
private $decoratedListener;
public function __construct($decoratedListener)
{
$this->decoratedListener = $decoratedListener;
}
public function onKernelRequest(GetResponseEvent $event)
{
try {
$this->decoratedListener->onKernelRequest($event);
} catch (NotFoundHttpException $e) {
// Don't forget to throw the exception if the http method isn't PUT
// else you're gonna break the 404 errors
$request = $event->getRequest();
if (Request::METHOD_PUT !== $request->getMethod()) {
throw $e;
}
// 2 solutions here:
// 1st is doing nothing except add the id inside request data
// so the deserializer listener will be able to build your object
// 2nd is to build the object, here is a possible implementation
// The resource class is stored in this property
$resourceClass = $request->attributes->get('_api_resource_class');
// You may want to use a factory? Do your magic.
$request->attributes->set('data', new $resourceClass());
}
}
}
And you need to specify a configuration to declare your class as service decorator:
services:
CustomReadListener:
decorate: api_platform.listener.request.read
arguments:
- "#CustomReadListener.inner"
Hope it helps. :)
More information:
Information about event dispatcher and kernel events: http://symfony.com/doc/current/components/event_dispatcher.html
ApiPlatform custom operation: https://api-platform.com/docs/core/operations#creating-custom-operations-and-controllers
Symfony service decoration: https://symfony.com/doc/current/service_container/service_decoration.html

Laravel Controller does not reflect changes made

I have a controller named FrontEndController.php in my Laravel 5.3 project. When I make any changes in a method, it does not reflect these changes. So, for testing i checked by making changes in other method and faced the same issue. I also created a new method in the same controller and renamed the name of method in route to the newly created method but it throws an exception that method does not exist.
So, just for testing, I renamed the controller to FrontEndController_Jan-17-2017.php and I was shocked to see that it did not throw any exception like FrontEndController.php does not exists.
Now, my question is that from where is laravel getting the FrontEndController.php file if it does not exist in actual or is there any problem of cache etc. which i'm not aware about. I have also tried by clearing the cache using php artisan cache:clear command but still not found any solution.
Route (Not contained in any group or prefix etc.)
Route::get('register', array('as' => 'register','uses' => 'FrontEndController#getRegister'));
Controller
<?php
namespace App\Http\Controllers;
use Activation;
use App\Http\Requests;
use App\Http\Requests\UserRequest;
use App\User;
use App\Contact;
use App\PNumber;
use Cartalyst\Sentinel\Checkpoints\NotActivatedException;
use Cartalyst\Sentinel\Checkpoints\ThrottlingException;
use File;
use Hash;
use Illuminate\Http\Request;
use Lang;
use Mail;
use Redirect;
use Reminder;
use Validator;
use Sentinel;
use URL;
use View;
use Helper;
class FrontEndController extends JoshController
{
/**
* Account Register.
*
* #return View
*/
public function getRegister()
{
// Show the page
return view('register');
}
}

How to fetch value from url in silverstripe

I want to print value 5 on the ss page.
www.xyz.com?a=5.
How to fetch url data in silverstripe? Any help is accepeted.
In your controller that your Silverstripe template is for, you can retrieve "GET" (aka. query string) by returning the result of $this->getRequest()->getVar('a') in a function on your controller.
It is good practice to use $this->getRequest()->getVar('a') over $_GET['a'] as SilverStripe will automatically sanitise the string.
When your code is not in the controller (so you can't make use of $this->getRequest()), you can request the current controller by using Controller::curr() which will make the complete call for getting a single var:
Controller::curr()->getRequest()->getVar('a')
If you want to get all "GET" variables, just call getVars() instead..
Also, you can access "POST" variables in a similar calling postVar('a') or postVars() instead. If you want to get the value from both "POST" or "GET", you can call requestVar('a') or requestVars().
Anyway, here is a basic mock-up of a controller using a function on the controller that is accessible in the template.
Controller
class TestPage_Controller extends Page_Controller
{
public function init()
{
parent::init();
}
public function MySpecialProperty()
{
return $this->getRequest()->getVar('a');
}
}
Template
<p> $MySpecialProperty </p>

symfony 1.4 - how to reuse validate method across modules

I have a quite complex validate method in module1/actions.php called from module1/executeMyAction
I would like to reuse this in module2 rather than duplicate very similar code.
It feels like I should use a component or something like this but I don't need to call validate from a template I need to call it as part of the module1/executeMyAction or module2/executeMyAction so I can then set various variables for the executeMyActionSuccess.php template to handlle.
Can anyone let me know how I should reuse this validation code, I considered moving it into the form class but that just means I can't set the template variiables and it seems like it is breaking the MVC structure a bit so I'm not happy with that.
Would really appreciate any guidance.
If you want to share some parts of code between actions you can create a custom class which will implement some methods you need. You can put the class in the lib directory of either the application or the whole project.
E.g. create a apps/frontend/lib/myUtil.class.php
class myUtil
{
public static function addNumbers($a, $b)
{
return $a + $b;
}
}
Then in your action you can just use:
$sum = myUtil::addNumbers(2, 3);
If your code depends on some other objects it's best if you don't implement static methods but create an object of the class. E.g.
class myUtil
{
protected $request;
public function __construct(sfWebRequest $request)
{
$this->request = $request;
}
public function sumFromRequest()
{
return $this->request->getParameter('a') + $this->request->getParameter('b');
}
}
then in your action
public function executeSomething(sfWebRequest $request)
{
$util = new myUtil($request);
$this->sum = $util->sumFromRequest();
}
If your code is strictly used for validation of form fields you can create a custom validator which can be then used in your form. (which will definitely be the best solution). You can read about creating custom validators in the Symfony docs.

Using reflection in PHPUnit

I'm testing a private method of a class used in Symfony2 project with PHPUnit.
I'm using the private methods testing strategy (through reflection) described by many developers such as http://aaronsaray.com/blog/2011/08/16/testing-protected-and-private-attributes-and-methods-using-phpunit/
But unfortunately, I got the following error:
There was 1 error: 1) My\CalendarBundle\Tests\Calendar\CalendarTest::testCalculateDaysPreviousMonth
ReflectionException: Class Calendar does not exist /Library/WebServer/Documents/calendar/src/My/CalendarBundle/Tests/Calendar/CalendarTest.php:47
<?php
namespace My\CalendarBundle\Tests\Calendar;
use My\CalendarBundle\Calendar\Calendar;
class CalendarTest
{
//this method works fine
public function testGetNextYear()
{
$this->calendar = new Calendar('12', '2012', $this->get('translator'));
$result = $this->calendar->getNextYear();
$this->assertEquals(2013, $result);
}
public function testCalculateDaysPreviousMonth()
{
$reflectionCalendar = new \ReflectionClass('Calendar'); //this is the line
$method = $reflectionCalendar->getMethod('calculateDaysPreviousMonth');
$method->setAccessible(true);
$this->assertEquals(5, $method->invokeArgs($this->calendar, array()));
}
}
Why?
Thank you in advance
You need to use the whole namespaced class name when creating your reflection method, even if you include a use statement.
new \ReflectionClass('My\CalendarBundle\Calendar\Calendar');
This is because you are passing the class name as a string to the constructor, so it doesn't know about your use statement and is looking for the class name in the global namespace.
Also, for what it's worth, you don't actually need to create a ReflectionClass, then call getMethod() on it. Rather, you can directly create a ReflectionMethod object.
new \ReflectionMethod('My\CalendarBundle\Calendar\Calendar', 'calculateDaysPreviousMonth');
That should be essentially the same, but a bit shorter.

Resources