How do libraries work in 5.7? I am trying to utilize a custom library for use on a single page.
I have created the single page view and controller. I am able to access the controller from the view.
I also created a library in application/libraries/ called lobbreeldashboard.php.
In my controller I have Loader::library('lobbyreeldashboard'); Inside of the library there is only one function right now called sayHello()
In my controller I make a call to the function using: sayHello();. However, I receive the following error Call to undefined function sayHello().
What am I missing to make this work in 5.7?
single_pages/stats.php
<?php
defined('C5_EXECUTE') or die("Access Denied.");
$abc = new StatsController();
$abc->view();
controller/stats.php
<?php
defined('C5_EXECUTE') or die("Access Denied.");
Loader::library('lobbyreeldashboard');
class StatsController extends Controller {
public function view() {
$bob = sayHello();
}
}
libraries/library.php
<?php
defined('C5_EXECUTE') or die("Access Denied.");
function sayHello() {
return 'hello';
}
First thing is in the example you have "lobbyreeldashboard" being loaded, but your file is called library.php? If that's not the problem, we can go from there, but figured I'd go with the obvious first.
Related
I have been recently researching EventListeners for the kernal for Symfony4 and I thought I had grasped the basic concept of it but I seem to get a page isn't redirecting properly issue with my EventSubscriber.
Essentially I'd like to do the following logic:
if file_exists $file
redirect to file
else
carry on as normal
Which is how I originally came to kernel.response. Here is my current code:
<?php
namespace App\EventSubscriber;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class MaintenanceSubscriber implements EventSubscriberInterface
{
public function onKernelResponse(FilterResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
if (file_exists('maintenance.flag')) {
$response = new RedirectResponse('maintenance');
$event->setResponse($response);
}
}
public static function getSubscribedEvents()
{
return array(
KernelEvents::RESPONSE => 'onKernelResponse'
);
}
}
this does my logic more or less perfectly, when maintenance.flag doesn't exist it carries on the project as expected, but when I touch maintenance.flag it gets the infamous Firefox page of Page isn't redirecting properly.
I'm not sure if I'm missing something?
I've set up my route:
maintenance:
path: /maintenance
controller: App\Controller\Maintenance\FlagController::flag
which is just a render function - I have a feeling that this could be causing the issue (an endless loop of redirect to flag() which then performs the before action?) but I'm not sure how to render my template from the setResponse() method
Even with the routing conf commented out, I still get the error. So not 100% sure anymore that it's the flag() endless loop theory
I was right indeed about the endless loop being the issue, adding this conditional to exclude the /maintenance url got it to work:
if (strpos($event->getRequest()->getRequestUri(), 'maintenance') !== false) {
return;
}
I am using symfony 3.2.4 (got with console --version).
I am working the openclassroom tutorial.
That controller always return the error below.
Nevertheless, the file below exist with and is accessible.
src/OC/PlatformBundle/Resources/views/Advert/index.html.twig
I got crazy with that. Does someone have an idea ?
Thanks in advance.
<?php
// src/OC/PlatformBundle/Controller/AdvertController.php
namespace OC\PlatformBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class AdvertController extends Controller
{
public function indexAction()
{
$content = $this->get('templating')->render('OCPlatformBundle:Advert:index.html.twig');
return new Response($content);
}
}
Unable to find template "OCPlatformBundle:Advert:index.html.twig"
(looked into: /var/www/html/symfony/app/Resources/views,
/var/www/html/symfony/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form).
*
Did you try to create your template in app/Resources/views/Advert/index.html.twig ?
This is a better practice : Store all your application's templates in app/Resources/views/ directory. (From SF doc)...
So, you'll be able to "call" it by this way:
/***/
public function indexAction()
{
return $this->render('Advert/index.html.twig', []);
}
/***/
A few years ago I made a SilverStripe website and added too many fields to Page.php. I'm reworking some of this at the moment but cannot afford do reinvent the Project - now on SilverStripe 3.1.10.
I thought to declutter the UI for Page Sub-Classes, that do not need all the inherited fields, with a few Extensions.
An example how this extension could look
class NoClutter extends Extension {
public function updateCMSFields(FieldList $fields) {
$fields->removeFieldFromTab("Root.Main", "MenuTitle");
$fields->removeFieldFromTab("Root.Main", "Workflow");
}
}
config.yml
RedirectorPage:
extensions:
- NoClutter
This works on all classes for fields added in SiteTree (such as the MenuTitle field), but not for fields added in Page (such as the Workflow field). If the Extension is on UserDefinedForm, Workflow is also removed. But it does not work if the extension is on RedirectorPage. MenuTitle on the other hand is removed in both classes. My guess it's about order. My project is After: 'framework/','cms/' and hope I can make an extension like NoClutter work within the project.
How can I achieve this or how else could I work around the problem?
You need to add $this->extend('updateCMSFields', $fields) at the end of your Page getCMSFields() function.
class Page extends SiteTree {
// ...
public function getCMSFields() {
// call updateCMSFields after adding your fields
SiteTree::disableCMSFieldsExtensions();
$fields = parent::getCMSFields();
SiteTree::enableCMSFieldsExtensions();
// ...
$this->extend('updateCMSFields', $fields);
return $fields;
}
}
$this->extend('updateCMSFields', $fields) declares where your code updateCMSFields() function will get called.
The problem you are having is updateCMSFields() is getting called before you add your custom fields in the Page getCMSFields() function. So you are trying to remove the Workflow field before it is added. This is because the updateCMSFields extension hook is declared in the parent SiteTree getCMSFields() function.
UserDefinedForm solves this by calling $this->extend('updateCMSFields', $fields) at the bottom of its getCMSFields(). SiteTree::disableCMSFieldsExtensions() is required before parent::getCMSFields() is called for the extension hook to work.
I do have a twig extension which has a method that uses another method from a different controller to render a json output via dependency jsonResponse.
How can I render a controller within a twig extension?
The following code below doesn't seem to work, because render() needs a view file instead of a controller. And I am now referencing to a controller.
class AreaExtension extends \Twig_Extension {
public function add()
{
$outputJson = $this->container->get('templating')->render(new ControllerReference('CMSCoreBundle:Area:index'));
}
}
$ref = new ControllerReference('CMSCoreBundle:Area:index');
$this->handler->render( $ref, 'inline', $options );
Where $this->handler is the fragment.handler service.
In your case:
$outputJson = $this->container->get('fragment.handler')->render(new ControllerReference('CMSCoreBundle:Area:index'));
You can find a full example in this symfony twig extension, see:
https://github.com/symfony/symfony/blob/4.1/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php#L28
and
https://github.com/symfony/symfony/blob/4.1/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php#L41
I have been looking through the documentation, and I can't seem to find a way to do this. I know I can use headScript to add style sheets to individual views, but I would like to add a style sheet to all actions in a controller.
Has anyone done this? I am sure it is a simple task.
Thanks
What you need to do is hook into the dispatch event and, based on the type of controller that was dispatched, set the appropriate layout (recommended). You could also directly modify the view and add the required assets.
This can be achieved by using the following code in your Module class:
<?php
namespace App;
class Module
{
public function onBootstrap(MvcEvent $event)
{
$event->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, function (MvcEvent $event)
{
$application = $event->getApplication();
$services = $application->getServiceManager();
$view = $services->get('ViewRenderer');
$controller = $event->getTarget();
if ($controller instanceof \App\Controller\Entry)
{
$controller->layout('layout/app/entry');
// -- OR --
$view->headStyle()->appendStyle('body{background:red}');
}
}, 100);
}
}
I hope this answers your question!