The controller for URI {url} is not callable - php

currently I am learning Pimcore which is made with Symfony (and I am a Laravel guy :3 ) So I have his error:
The controller for URI "/article/1132/This%20is%20my%20first%20post%20in%20Pimcore" is not callable:
Expected method "blogarticleAction" on class "AppBundle\Controller\DefaultController".
I am trying to get an object (of blogpost) based on its ID and then to display that blogpost to the user.
I have made that controller with blogarticleAction method:
<?php
namespace AppBundle\Controller;
use Pimcore\Controller\FrontendController;
use Symfony\Component\HttpFoundation\Request;
use Pimcore\Model\DataObject;
class MyContentController extends FrontendController
{
public function defaultAction(Request $request)
{
//$this->view->blogpostList = new DataObject\Blogpost\Listing();
$list = new DataObject\Blogpost\Listing();
$paginator = new \Zend\Paginator\Paginator($list);
$paginator->setCurrentPageNumber( $request->get('page') );
$paginator->setItemCountPerPage(3);
$this->view->paginator = $paginator;
}
public function blogarticleAction(Request $request)
{
$this->view->blogarticle = DataObject\Blogpost::getById($this->getParameter('id'));
}
}
Also, here is my static route from the Pimcore admin panel:
https://prnt.sc/w96ya3
Links seem to be formed correctly:
https://prnt.sc/w96zvn
but when I click on that link to go to a single blogpost I get this:
https://prnt.sc/w970kg

The error states that the method should exist on DefaultController and not on MyContentController. In the screenshot of your static route, you have used the DefaultController only.

Related

Doctrine Entity from other Bundle in Symfony Controller

I try to use the Entity of another Bundle in my Symfony Controller:
use Acme\TestBundle\Entity\Neighbour;
use AppBundle\Entity\Home;
class TestController extends Controller {
public function testAction(Home $home, Neighbour $neighbour) {
//
}
}
but this throws an 404 Error:
Acme\TestBundle\Entity\Neighbour object not found
this is different to a real not existing object like NeighbourX, there it throws an 500 error:
Acme\TestBundle\Entity\Neighbour does not exist
The object exists, and it should work, because this works:
use Acme\TestBundle\Entity\Neighbour;
use AppBundle\Entity\Home;
class TestController extends Controller {
public function testAction(Home $home) {
$thread = new ForumThread();
}
}
Ok I already found the answer myself. I had to specify the route variable:
/home/{id}/neighbour/{nid} #before
/home/{id}/neighbour/{neighbour} #after
But I don't fully understand it. Why doesn't {id} has to be {home}? Is {id} just the first parameter-id by default?
And why is the error message that misleading..

Symfony - Filter Request with FOSRestBundle and body_listener without Annotations?

I am using Symfony2 with the FOSRestBundle. Is it possible to have the functionality of the #QueryParam and #RequestParam annotations without using annotations?
I am trying to build a json api (format), so I want to allow query params like include, page, filter, fields, and sort. My ideal way to handle this would be:
Use the format_listener to detect it is json.
Use a custom body_listener json handler to process the request so that it's similar to this.
Have the controller validate the query/request params inside the action function, and throw an exception to be handled by the exception controller if it's invalid. (The body_listener would act as a helper to make extracting the data from the request easier in the controller, but the controller makes the decisions of what to do with that data.)
I'm mostly stuck on how to make a custom body_listener. I'm not sure if I would need to make a custom decoder or normalizer, and what that class might look like since they don't give any examples.
Rough code of what controller would look like:
<?php
namespace CoreBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View\View;
use FOS\RestBundle\Context\Context;
use Psr\Http\Message\ServerRequestInterface;
class SiteController extends FOSRestController
{
public function getAction($id, ServerRequestInterface $request)
{
try {
// Validate $request. This is where the query/request
// param annotation functionality would be replaced.
} catch (Exception $e) {
throw new InvalidRequestException($e);
}
$siteService = $this->get('app.site_service');
$site = $siteService->getSite($id);
$context = new Context();
$context->setVersion($request->getVersion());
// Ex: /sites/63?fields[sites]=name,address&fields[company]=foo,bar
if ($request->hasIncludeFields()) {
$context->addAttribute('include_fields', $request->getIncludeFields()); // Or however to do this
}
$view = new View($site, 200);
$view->setContext($context);
return $view;
}
}
You can define parameters dynamically in param fetcher. It's described in documentation.
For example:
With annotations:
<?php
namespace ContentBundle\Controller\API;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Request\ParamFetcher;
class PostController extends FOSRestController
{
/**
* #QueryParam(name="sort", requirements="(asc|desc)", allowBlank=false, default="asc", description="Sort direction")
*/
public function getPostsAction(ParamFetcher $paramFetcher)
{
$sort = $paramFetcher->get('sort');
}
}
Without annotations:
<?php
namespace ContentBundle\Controller\API;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Request\ParamFetcher;
class PostController extends FOSRestController
{
public function getPostsAction(ParamFetcher $paramFetcher)
{
$sort = new QueryParam();
$sort->name = 'sort';
$sort->requirements = '(asc|desc)';
$sort->allowBlank = false;
$sort->default = 'asc';
$sort->description = 'Sort direction';
$paramFetcher->addParam($sort);
$param = $paramFetcher->get('sort');
//
}
}

Unable to use helper in controller of laravel app

I'm building an application, now i'm created a helper
class Students{
public static function return_student_names()
{
$_only_student_first_name = array('a','b','c');
return $_only_student_first_name;
}
}
now i'm unable to do something like this in controller
namespace App\Http\Controllers;
class WelcomeController extends Controller
{
public function index()
{
return view('student/homepage');
}
public function StudentData($first_name = null)
{
/* ********** unable to perform this action *********/
$students = Student::return_student_names();
/* ********** unable to perform this action *********/
}
}
this is my helper service provider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class HelperServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
foreach(glob(app_path().'/Helpers/*.php') as $filename){
require_once($filename);
}
}
}
i event added it as an alias in config/app.php file
'Student' => App\Helpers\Students::class,
Try putting use App\Helpers\Student; at the top of your controller beneath the namespace delcaration:
namespace App\Http\Controllers;
use App\Helpers\Student;
class WelcomeController extends Controller
{
// ...
Look more into PHP namespaces and how they are used, I believe you may have a deficient understanding about them. Their only purpose is to make so you can name and use two classes with the same name (e.g. App\Helpers\Student vs maybe App\Models\Student). If you needed to use both of those classes inside of the same source file, you can alias one of them like this:
use App\Helpers\Student;
use App\Models\Student as StudentModel;
// Will create an instance of App\Helpers\Student
$student = new Student();
// Will create an instance of App\Models\Student
$student2 = new StudentModel();
You do not need to have a service provider for this, just the normal language features. What you would need a service provider for is if you wanted to defer the construction of your Student object to the IoC:
public function register()
{
$app->bind('App\Helpers\Student', function() {
return new \App\Helpers\Student;
});
}
// ...
$student = app()->make('App\Helpers\Student');
You should never have to include or require a class file in laravel because that is one of the functions that composer provides.
You do not need a service provider to make it works. Just lets the Students class as you did:
class Students{
public static function return_student_names()
{
$_only_student_first_name = array('a','b','c');
return $_only_student_first_name;
}
}
all its methods should be static
You added the Facade correctly:
'Student' => App\Helpers\Students::class,
Finally, looks like your problem is caused by forgetting a backslash at facade name. Uses \Students instead of Students:
public function StudentData($first_name = null)
{
$students = \Student::return_student_names();
}
When using a facade, it is not necessary makes nay include, the facades were made to avoid complex includes in everywhere.

Why is my code returning a non response error? I am new to symfony2 and trying to implement the blog example explained in the symfony book

This is the code in my controller. Now according to the symfony book, this should allow the URL /blog/my-blog-post to be loaded with the slug variable acquiring a value of my-blog-post. However on execution, my controller returns an error "The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?" Any idea on how to resolve this?
Controller code
<?php
namespace Acme\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class BlogController extends Controller
{
/**
* #Route("/blog/{slug}", name="blog_show")
*/
public function showAction($slug)
{
//...
}
}
As you do not have the #Template annotation, you should render a template in your action return:
// renders app/Resources/views/hello/greetings/index.html.twig
return $this->render('hello/greetings/index.html.twig', array(
'name' => $name
));
More here: http://symfony.com/doc/current/book/controller.html#rendering-templates

How do I use a misc function in Symfony2?

Where do I store misc functions? How do I use them? Should it be a DependencyInjection? Should it just be a class and do I do something like use Acme\Bundle\AcmeBundle\Misc\ClientIPChecker?
Say I have a function:
<?php
class ClientIPChecker {
public static function isLocal(Request $request){
return in_array('127.0.0.1', $request->getClientIp())
}
}
And I want to use this function in two controllers. How do I do this in Symfony2?
If you have a set of consistent function put them in a class/service. If functions do different things put them in the appropriate class/service. In this particular case, I'll go for either custom Request or custom Controller (probably the latter, avoding messing app.php or app_dev.php).
With custom controller this doesn't work:
// Automatic binding of $request parameter
public function indexAction(Request $request)
{
// Won't work with custom controller
if ($request->isLocal)) {
// ...
}
// You have to do
if ($this->getRequest()->isLocal()) {
// stuff
}
}
Option 1: extend Symfony Request
namespace My\HttpFoundation;
use Symfony\Component\HttpFoundation\Request as BaseRequest;
class Request extends BaseRequest
{
public function isLocal()
{
return in_array('127.0.0.1', $this->getClientIp());
}
}
Then in web/app.php and web/app_dev.php modify:
use Symfony\Component\HttpFoundation\Request;
to be:
use My\HttpFoundation\Request;
Option 2: create a BaseAbstractController and use it instead of Symfony controller
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
abstract class BaseAbstractController extends Controller
{
public function isRequestLocal()
{
return in_array('127.0.0.1', $this->getRequest()->getClientIp())
}
}
Option 3: custom service as explained here

Categories