yii2 beginWidget -> unknown method - class

In yii I had such code which was roking OK
$form=$this->beginWidget('CActiveForm', array(
'id'=>'ride-form',
'enableClientValidation'=>false,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
now I am trying to use it in Yii 2 version.
But I'm getting error
Calling unknown method: yii\web\View::beginWidget()
Why ? and what class maybe I should additionally use to fix this problem ?

This error appears because yii\web\View class simply does not have the method beginWidget().
For working with forms in Yii2 use ActiveForm widget.
Replace your code with:
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'ride-form',
'enableClientValidation'=>false,
'validateOnSubmit' => true, // this is redundant because it's true by default
]);
// ...
ActiveForm::end();

2 things i would check for if a method is unknown.
1) is the class included before you call it?
2) Are you creating an instance of the class and calling the class from that instance variable?
include 'myClass.php';
$class = new myClassName();
$class->method();

Related

TYPO3 system extension "install" overwrite with my own class

I would like to override a method of TYPO3 system extension "instal" -> Class TYPO3\CMS\Install\SystemEnvironment\Check with my own class VENDOR\Examples\Xclass\Backend\Check but it's not working.
Other classes in the system extesion for example as TYPO3\CMS\Backend\Controller\LoginController or TYPO3\CMS\Backend\Template\DocumentTemplate can I without problems with the help of XLASS overwrite.
It is generally possible to overwrite the install tools classes from own extension?
<?php
defined('TYPO3_MODE') || die('Access denied.');
if (TYPO3_MODE === 'BE') {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Install\\SystemEnvironment\\Check'] = array(
'className' => 'ALEX\\Examples\\Xclass\\Backend\\Check'
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Backend\\Controller\\LoginController'] = array(
'className' => 'ALEX\\Examples\\Xclass\\Backend\\LoginController'
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Backend\\Template\\DocumentTemplate'] = array(
'className' => 'ALEX\\Examples\\Xclass\\Backend\\DocumentTemplate'
);
}
This is not possible as the class is not called via GeneralUtility::makeInstance. Furthermore it is also stated in the class:
#internal This class is only meant to be used within EXT:install and
is not part of the TYPO3 Core API.
If you are missing a feature or think you got a bug you should open an issue at https://forge.typo3.org/projects/typo3cms-core/issues

Typo3 BackendPreview getting cObj throws: Call to a member function enableFields() on null

In my BackendPreview for a custom content element in typo3 8.7 i'm trying to get a content object with following code in my own service class:
$conf = array(
'tables' => 'tt_content',
'source' => $uid,
'dontCheckPid' => 1
);
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$result = $this->objectManager->get(RecordsContentObject::class)->render($conf);
Doing this in frontendContext will return the cObj as expected but in BE Context, typo3 throws the exception: "Call to a member function enableFields() on null".
I've tried to initialize the configurationManager manually but no effects.
Anyone an idea?
The problem, hat the ContentObjectRenderer, (responsible for your TypoScript rendering) expect the TSFE (TypoScriptFrontendController), and since you are not in a FE context but a BE context it won't be initialized.
In theory, you can fake it, but of course it costs performance and I would not recommend it.
If you would like to have a privew, then use this approche:
https://docs.typo3.org/typo3cms/extensions/fluid_styled_content/7.6/AddingYourOwnContentElements/Index.html

Deprecated: ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along with the ServiceLocatorAwareInitializer

I am getting below error message while using service manager.
How can i resolve this via different approach like constuct....
Deprecated: You are retrieving the service locator from within the
class Users\Controller\LoginController. Please be aware that
ServiceLocatorAwareInterface is deprecated and will be removed in
version 3.0, along with the ServiceLocatorAwareInitializer. You will
need to update your class to accept all dependencies at creation,
either via constructor arguments or setters, and use a factory to
perform the injections. in
C:\wamp64\www\ZendSkeletonApplication-master\vendor\zendframework\zend-mvc\src\Controller\AbstractController.php
on line 258
Below code i have added in module.php
public function getServiceConfig() {
return array(
'abstract_factories' => array(),
'aliases' => array(),
'factories' => array(
// FORMS
'LoginForm' => function ($sm) {
$form = new \Users\Form\LoginForm();
$form->setInputFilter($sm->get('LoginFilter'));
return $form;
},
)
)
}
and from login controller, index action i calling below code
$form = $this->getServiceLocator()->get('LoginForm');
$viewModel = new ViewModel(array('form' => $form));
return $viewModel;
Any help is highly appreciated.
Currently i am using Zend framework 2.5.1 Version
In Zend framework 2.3 Version it was working fine.
Update
Now i am using below code in my controller
// Add this property:
private $table;
// Add this constructor:
public function __construct(LoginForm $table) {
$this->table = $table;
}
and in module.php
// FORMS
Model\AlbumTable::class => function ($sm) {
$form = new \Users\Form\LoginForm();
$form->setInputFilter($sm->get('LoginFilter'));
return Model\AlbumTable;
},
But still i am getting below error
Catchable fatal error: Argument 1 passed to
Users\Controller\LoginController::__construct() must be an instance of
Users\Form\LoginForm, none given, called in
C:\wamp64\www\ZendSkeletonApplication-master\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php
on line 252 and defined in
C:\wamp64\www\ZendSkeletonApplication-master\module\Users\src\Users\Controller\LoginController.php
on line 22
There was a lot of problem in the use of serviceLocator in ZF2, Zend tech' did a great job by removing the serviceLocatorAware from the framework, and remove the serviceManager from controllers.
Why ?
Just because some entry and experienced developpers used it in an ugly way, and way too much.
From my point of view, the serviceLocator is meant to be used only in factories.
That's why i keep advising other developper to create factories, without using anonymous function.
Here an example of a controller's factory (not the same as service's factories) : https://github.com/Grafikart/BlogMVC/blob/master/ZendFramework2/module/Blog/src/Blog/Factory/PostControllerFactory.php
And its config line https://github.com/Grafikart/BlogMVC/blob/master/ZendFramework2/module/Blog/config/module.config.controllers.php#L8
And here a Service's factory
<?php
namespace Blog\Factory;
use Blog\Service\CategoryService;
use Doctrine\Common\Persistence\ObjectManager;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class CategoryServiceFactory implements FactoryInterface
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return CategoryService
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
/** #var ObjectManager $em */
$em = $serviceLocator->get('orm_em');
return new CategoryService($em);
}
}
You can do a factory for almost all of your component, even form, you just need to declare those as factories in your config like this :
You can replace the key form_elements by :
controllers
service_manager
view_helpers
validators
It will works the same way :
'form_elements' => array(
'factories' => array(
'Application\Item\Form\Fieldset\ProfileFieldset' =>
'Application\Item\Factory\ProfileFieldsetFactory',
),
'invokables' => array(
'EntityForm' => 'Application\Entities\Form\EntityForm',
'PropertyForm' => 'Application\Item\Form\PropertyForm',
'ProfileForm' => 'Application\Item\Form\ProfileForm',
),
'initializers' => array(
'ObjectManagerInitializer' => 'Application\Initializers\ObjectManagerInitializer',
),
),
Your last error means that your controller is not correctly instanciated, you not give the LoginForm instance, maybe because you didn't create a factory ? Is your controller declared as an invokables ?
For an in depth discussion on deprecating the ServiceLocatorAwareInterface, please read this article by Matthew Weier O'Phinney. Basically, you should avoid hidden dependencies in your controllers by simply setter injecting them through factories as mentioned previously by Hooli.

Zend\Form: Call to a member function insert() on a non-object in Zend/Form/Fieldset.php

I am learning how to use Zend Framework 2 (2.1.4) forms and running into this error.
Call to a member function insert() on a non-object in ... /Zend/Form/Fieldset.php on line 178
I don't want use the form to automatically connect to a database, in fact I only want to use the form to help validate and will pull from and populate it with an array of values. How do I turn off the database connectivity in the form objects?
I am used to dealing with the ZF1 forms so this new form system is confusing. Once I thought about it though, the way we can use the form elements in our view scripts for formatting is going to be nice. Those old decorators were a pain. Anyway, for me, it would be nice to use the forms without dealing with bound database objects. Is this possible? It just seems so overly complicated to need a model class using InputFilterAwareInterface classes in addition to a simple form. One step at a time though, I can't even get the form to display.
I appreciate any help.
Below are my controller, form, and view scripts:
Form class:
namespace FBWeb\Form;
use Zend\Form\Form;
use Zend\Form\Element;
class ClientForm extends Form
{
public function __construct()
{
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'client',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Client Name',
),
'attributes' => array(
'type' => 'text',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Add'
),
));
}
}
Controller class:
namespace FBWeb\Controller;
use Zend\Debug\Debug;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use Zend\Http\Request;
use FBWeb\Form\ClientForm;
class ClientController extends AbstractActionController
{
public function indexAction()
{
$clientform = new ClientForm();
return array('form' => $clientform);
}
}
index.phtml view script:
<div id="clientformtable">
<?php
$form = $this->form;
$form->setAttribute('action','/app/client/add');
$form->prepare();
echo $this->form()->openTag($form);
$client = $form->get('client');
echo $this->formRow($client);
echo $this->form()->closeTag();
?>
</div>
This, and similar error messages, happen due to the fact that the form isn't properly set up. As you can see within the code above the __construct() function doesn't call the parents constructor. Therefore the internal "bootstrapping" doesn't happen and the error occurs.
You have to make sure to always call the parents constructor when dealing with Zend\Form\Form and/or Zend\Form\Fieldset.
parent::__construct('client-form');

Why does not work short names when I create custom form elements in Zend Framework 2?

I create custom element like here: ZF2Docs: Advanced use of Forms
1.Create CustomElement class in Application/Form/Element/CustomElement.php
2.Add to my Module.php function
public function getFormElementConfig()
{
return array(
'invokables' => array(
'custom' => 'Application\Form\Element\CustomElement',
),
);
}
If I use FQCN it works fine:
$form->add(array(
'type' => 'Application\Form\Element\CustomElement',
'name' => 'myCustomElement'
));
But if I use short name:
$form->add(array(
'type' => 'Custom',
'name' => 'myCustomElement'
));
throws Exception:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create
an instance for Custom
Problem
The error is probably due to how you are instantiating the $form object. If you just use the new Zend\Form\Form expression or something similar the form will not be set up with the correct service locator.
$form = new \Zend\Form\Form;
$form->add(array(
'type' => 'custom',
'name' => 'foobar',
));
Solution
The trick here is to use the FormElementManager service locator to instantiate the form.
// inside a controller action
$form = $this->getServiceLocator()->get('FormElementManager')->get('Form');
$form->add(array(
'type' => 'custom',
'name' => 'foobar',
));
Better yet, define a form() method in your controller as a shortcut to do this for you:
class MyController extends AbstractActionController
{
public function form($name, $options = array())
{
$forms = $this->getServiceLocator()->get('FormElementManager');
return $forms->get($name, $options);
}
public function createAction()
{
$form = $this->form('SomeForm');
// ...
}
}
Explanation
Each form object is attached to a form factory which is in turn attached to a service locator. This service locator is in charge of fetching all the classes used to instantiate new form/element/fieldset objects.
If you instantiate a new form object (all by itself), a blank service locator is instantiated and used to fetch later classes within that form. But each subsequent object is then attached to that same service locator.
The problem here is that getFormElementConfig configures a very specific instance of this service locator. This is the FormElementManager service locator. Once it's configured, all forms pulled from this service locator will then be attached to this service locator and will be used to fetch other elements/fieldsets etc.
Hope this solves your issue.