The answer to my question ZF2 FormInput to show error class on validation fail is to create my own form view helper, overriding the render function. While this works beautifully for elements being rendered using forminput, it doesn't help on elements that inherit from forminput. For example, FormCheckbox inherits from forminput but not MY forminput:
<?php
namespace Zend\Form\View\Helper;
//...
class FormCheckbox extends FormInput {
//...
}
In this case I would need to create ANOTHER form view helper for formcheckbox exclusively to extend MY forminput. And again for any other view helpers I want to include (formdate, formemail, formpassword, etc).
Instead of creating multiple view helpers is it possible to create a single view helper and tell ZF2 to use that in all calls to the original view helper when made by a ZF2 view helper?
i.e. \Zend\Form\View\Helper\FormCheckbox would extend \RPK\Form\View\Helper\FormInput, which would extend \Zend\Form\View\Helper\FormInput.
A solution I can think of, is rewriting a part of the autoloader.
In the autoload function, you add an extra check to check if the requested class is \Zend\Form\View\Helper\FormInput, and if that's the case, you load your custom FormInput.
In your own FormInput you don't extend the Zend FormInput, but you create a copy of it, and modify the parts that are needed to be modified.
Unless ZF2 is using dependency injection for it's form helpers, this is the only way I can think of (without altering the base library code).
What I have used are view partial. With partials you can define your own html for every input-element and you have access to all attributes and messages (e.g error-messages) of the input-element:
in your partial phtml:
<?php
$options = $element->getOptions();
$t = $this->t();
$value = $element->getValue();
$messages = $element->getMessages();
$attr = $element->getAttributes();
you can use a partial like this:
$this->formRow($form->get('myelement'), null, null, 'mypartial');
I am using composer to install ZF2. As composer is generating my autoload functions I can specify an autoload path in the composer.json file:
"autoload": {
"psr-4": {
"Zend\\Form\\View\\Helper\\": "vendor/rpk/Rpk/Form/View/Helper"
}
},
This will search in my vendor folder for the class before looking in the zend folder.
This does not let me extend the FormInput, but calls my FormInput in its place. Calling extends on my FormInput puts the app into an infinite loop, so we need to copy the contents of FormInput into my class and make the changes there.
Related
how to use another controller function without extends in our controller
$this->load->library('../controllers/controllername');
already used
it is giving error =
Unable to locate the specified class: Session.php
Well you are not supposed to do that. If your controller uses repeatable logic, you should make class (Service for example), put the re-usable logic into it and call it in your controllers.
You can't use another controller function inside the controller. You can archive this in these two ways.
Create a Helper class
Create a generic model.
i want to create new function in helper, but it still failed :
Call to undefined function
i save my helper at app/Helper/Text_helper.php using namespace App\Helpers;
and load helpers on BaseController using protected $helpers = ['text'];
Reference : https://codeigniter4.github.io/userguide/general/helpers.html#extending-helpers
but it's still not working
It's not mentioned in documents but remember to add a suffix _helper to filename of your helper otherwise it will not work in codeigniter 4.
For example if you have created a helper xxx.php, change it to xxx_helper.php.
To load a helper you can use helper function (Like: helper('xxx.php');) or add it to $helpers array that is an protected property in BaseController
If your idea is to "extend" (replace) a function on the stystem/helpers/text_helper note the lowercase in the name of the file, you have to respect it.
Also, the helper doesn't need a namespace... the helper loader will search for it.
The helper() method will scan through all PSR-4 namespaces defined in app/Config/Autoload.php and load in ALL matching helpers of the same name. This allows any module’s helpers to be loaded, as well as any helpers you’ve created specifically for this application. The load order is as follows:
app/Helpers - Files loaded here are always loaded first.
{namespace}/Helpers - All namespaces are looped through in the order they are defined.
system/Helpers - The base file is loaded last
the namespace will be used to load a helper on other location, for example:
helper('Libraries\MyFunctions');
as long as that path can be found through a namespace that has been set up within the PSR-4
Reference:
https://codeigniter4.github.io/userguide/general/helpers.html#extending-helpers
You need to load the helper into the app/Config/Autoload.php and still not work then please try to run composer dump-autoload
I'm using Laravel to build a CMS and I have a View Site button that's available in my main layout file (if that's how you call it) app.blade.php. This file is where I yield my content and load all my css and js files.
I want the link of the View Site button to be dynamic, based on a base url set in my settings table. I can retrieve the variable like this:
$settings = DB::table('settings')->get();
return $settings->base_url;
But my question is: how do i retrieve this in my view the right way?
I'm having trouble doing this because usually I link a method to a specific page with the routes.php file, but since the app.blade.php is available everywhere I'm unable to do this (I guess).
You need a view composer. This is a function that can add data to a view every time it is being rendered. It makes the most sense to put your view composer inside of a service provider.
Make a new service provider inside app/Providers, then add your view composer inside of the boot() method.
ViewComposerServiceProvider
namespace App\Providers;
use DB;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('app', function($view) {
$settings = DB::table('settings')->get();
$view->with('base_url', $settings->base_url);
});
}
}
This would inject a variable called $base_url into app.blade.php every time it was rendered. Of course, instead of adding the view composer as a closure, you could move it out into its own class that just gets included inside the service provider, but this should give you the right idea.
Then just make sure to register your service provider inside config/app.php:
providers => [
//All other service providers
App\Providers\ViewComposerServiceProvider::class,
]
This is the preferred "Laravel way" to inject data into views every time they are rendered. This is the way that is the most flexible and scalable because it allows you to modify your views in really any way before rendering them. Laracasts has a really nice free video on the topic.
The best way is to create a helper function and use it in the view template.
In your app folder, create a file: helper.php
function getBaseURL()
{
return \App\Setting::get()->base_url ;
}
Now in your blade template app.blade.php, you can get it like:
Visit Site
You need to add this helper.php file to the composer autoload.
For that, in your compose.json file,
"files":[
"app/helper.php"
],
Add this in the autoload part.
Now do a composer dump-autoload
Is it possible to change the action class Yii2 uses somehow, similar to how you can set the class of many other components within the config file?
I want to extend this class so I can add another member variable to it.
I guess I could just add one to it anyway dynamically, but would prefer to do it in a proper fashion.
Edit: Looking at the list of core application components it isn't listed, so not sure if it's possible?
The proper way to solve this problem is to extend both controller and action classes. If you look at the source code, yii\base\Controller has a createAction method that, if no class action is found, will create an instance of InlineAction.
Since you're extending some kind of controller class every time you make your own controller (class MyController extends Controller), you can just override the original createAction method and in it use your own implementation of the InlineAction class.
It can be done with class map
Yii::$classMap['yii\base\InlineAction'] = '#common/InlineAction.php';
and should be placed into index.php, before the app is launched.
Regardless of its location, common/InlineAction.php should have the same yii\base namespace as the original class.
I tried to search here before creating this, but I couldn't find anything.
I have a simple project without modules and I'd like to load my models (which are inside application/models) without using any namespace and without usign any extra loading lines.
Basically what I want to do is to have my class Projects extends Zend_Db_Table_Abstract inside my models folder and to load it in my controller using $db = new Projects();
Is there anyway to do this? Is it recommended to use Model_Projects instead?
What If I had modules?
Edit:
I tried to use this without any other implementation and I got Class 'Projects' not found
It is because the Projects class is not autoloaded. Depending on your application namespace, (for example the default namespace 'Default') you have to name your class into something like: Default_Model_Projects