Shared base controller between modules - phalcon

I am setting up a multi-module application, so far I have it setup like this example http://docs.phalconphp.com/en/latest/reference/applications.html.
But I was wandering if its possible to have shared base controller that both the backend and frontend controllers extend from. This is so I can have a single ACL in the base controller. How would I set that up?
According to the docs I can create a controllerbase anywhere and then just require this file directly in the bootstrap file or cause to be loaded using any autoloader. So I created a folder called apps/shared/controllers/ControllerBase.php and required this file directly in the bootstrap file but this does not work.
If I try to load a controller like so:
class AdminController extends ControllerBase
{
public function indexAction()
{
echo "<h1>Hello admin!</h1>";
}
}
I get an error ...Backend\Controllers\ControllerBase' not found in......
So how do I cause to be loaded using any autoloader as per the docs? Do I need to register it as its own namespace or something?

You not using the full namespace path for your base controller so the autoloader attempts to find it under in the same namespace of the child class.
Try something like this:
namespace MyApp\Backend\Controllers;
use MyApp\Shared\Controllers\ControllerBase;
class AdminController extends ControllerBase
{
public function indexAction()
{
echo "<h1>Hello admin!</h1>";
}
}
This answer consider that you have applied the PSR-0 and PSR-4 properly.

Related

How does a Laravel Controller call Authorize function?

Looking at the laravel docs for controllers, they have an example where they authorize actions via a policy inside a Controller class:
$this->authorize('action',$model);
Yet checking the laravel doc api, I can see that the base controller class has no authorize method. How does this work?
If I take a look at a standard controller that is scaffolded by Laravel, you'll see that it extends a "base" controller in your app/Http/Controllers folder;
use App\Http\Controllers\Controller;
class YourController extends Controller
{
//...
If you go and take a look at this "base" Controller class:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
You can see that this is using the AuthorizesRequests trait.
If you go and take a look in the AuthorizesRequests trait you'll see these authorisation methods.
One of which is:
public function authorize($ability, $arguments = [])
{
[$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
This is how the authorize method works and is provided to your controllers.

Specify class loader for loading dependencies of an advice's dependency

I have an advice class that makes use of another class that's part of the agent jar, but this other class has a dependency on a class that's not present in the agent jar. This class that's not present in the agent jar is present in another jar that's on the application class loader. The agent jar is on the system class loader. So I run into NoClassDefFoundError. I have tried using Transformer.ForAdvice as suggested in this other post, but that only works for the advice class.
// In agent jar on system class loader
MyAdviceClass {
#Advice.OnMethodEnter
public static void onMethodEnter() {
YetAnotherClass.doSomething(); // works fine as Transformer.ForAdvice makes use of the correct class loader while inlining this code
AnotherClass.doSomething(); // NoClassDefFoundError happens inside this method call
}
}
// In agent jar on system class loader
public class AnotherClass {
public static void doSomething() {
YetAnotherClass.doSomething(); // NoClassDefFoundError happens here because the system class loader is used to load YetAnotherClass, but that class is only present on the application class loader
}
}
// In user jar on application class loader
public class YetAnotherClass {
public static void doSomething() {
// do something else
}
}
Transform looks like this:
.transform(new AgentBuilder.Transformer
.ForAdvice()
.include(getClass().getClassLoader())
.advice(methodMatcher, "com.something.advice.MyAdvice.class"));
MyAdviceClass and AnotherClass are present in the agent jar. YetAnotherClass is present in user jar that's not on the system class loader, its on the application class loader. How can I solve this problem? i.e. is there a way by which I can force the use of the application class loader in AnotherClass?
I assume that AnotherClass is not visible from the class being instrumented. In this case, you should not include the class in ypur agent jar but place it in a seperate jar that you append to the boot loader via Instrumentation.appendToBootSearchPath. Classes on the boot loader are universally visible and should therefore be accessible to your instrumented class.
If the injected classes reference classes of the instrumented class loader you might however need to inject classes into the class loader using a ClassInjector.

PHP/Laravel can not resolve parent Class

Using php 7, Laravel 5.5. All models are in default app/ folder, Prototype is in app/ folder too. Nothing was moved
What is most frustrating - this worked all right for controllers (everything is in their default folders)
My Prototype Class:
class Prototype extends Model
{
//other code
}
My child Class:
class Tree extends Prototype
{
//other code
}
Exception:
include(/var/www/html/app/Prototypephp): failed to open stream: No such file or directory
I need help to fix this issue. Thanks!
After a few hrs of working over this issue solved it by moving Prototype Class to other namespace (and folder). Did the same to PrototypeController for code readability.

Override and use front controller features in a prestashop module [1.6.x.x]

I would like to edit and add features to the prestashop Store Locator page.
Prestashop's documentation isn't really clear, and i would like to know if it's possible to implement a Controller in a custom module.
I would like to create a module which is able to extends StoreFrontController and it's features without starting from scratch.
Is it possible ? Have you some documentation for me ?
A beginner,
Best.
As you have many requirements, you will have to go with an override of class StoresController.php.
Your module folder should look like this:
/mymodule
/mymodule.php
/config.xml
/override
/controllers
/front
StoresController.php
/views
/templates
/front
stores.tpl
In StoresController.php you will have to override initContent():
<?php
class StoresController extends StoresControllerCore
{
/**
* Assign template vars related to page content
* #see FrontController::initContent()
*/
public function initContent()
{
parent::initContent();
// here add any smarty variables you want
$this->setTemplate(_PS_MODULE_DIR_.'mymodule/views/templates/front/stores.tpl');
}
}
Now you can add as many variables as you want in this controller and customized its template in your own module.
We you create an override in a module, it will be only parsed once at installation. If your module is already installed you will have to uninstall it and install it again. Then your override file will be copied to the root /override folder.
Any change made in your module override will not be reflected to the root override folder. So you will have to uninstall and install your module each time you want to make a change.
So I advise you to make all your changes directly in the root override folder, and when you're done copy this file back into your module folder. And if you don't want to uninstall your module and install it again to declare this file, you can put it directly in the root override folder and delete the file /cache/class_index.php so that Prestashop knows that an overrides has been added.
If you have any questions :)
You can start by overriding front controller like
`"/modules/mymodule/override/controllers/front/StoresController.php" and in this fine add class "class StoresControllerCore extends FrontController {
public function initContent()
{
parent::initContent();
//here do whatever you like
}
}"
though you must know coding to proceed further.

Override Prestashop Core controller using a module

Working on a project that consist to create thumbs for the product's features,
is there a way to override the core controller *AdminFeaturesController*using a module?
In your module you can create a /override directory. Under this directory you will create this file /override/controllers/admin/AdminFeaturesController.php.
This file should look as follow:
<?php
class AdminFeaturesController extends AdminFeaturesControllerCore
{
// Only override the functions that should be modified
public function function_that_i_want_to_override() {
}
}
The override will be effective after module installation.