calling controller's action in another controller, making widget - php

I have a problem in Yii framework, I want to call a controller's action in the layout/main.php page which is belong to the siteController, I did this:
$a = UsersController::actionRequestAlert($s);
then I got this error:
Non-static method UsersController::actionRequestAlert() should not be called statically, assuming $this from incompatible context
so how can I solve this problem?
ok,
now I want to create a widget, here is the steps I made:
created folder 'widgets' in folder 'protected'.
created folder 'views' in folder 'widgets'.
added this in config/main.php : 'application.widgets.*'
this is the code of widgets/Alert.php :
class AlertWidget extends CWidget
{
public $alert = null;
private $_data = null;
public function init()
{
$s = Yii::app()->session['userId'];
$r = Requests::model()->findAll('idUser='.$s.' and confirm =0 and unconfirm=0 and cancel=0');
$i=0;
foreach($r as $x)
$i++;
if($i<=0)
$alert=null;
else
$alert="(".$i.")";
$this->_data = new CActiveDataProvider($alert);
}
public function run()
{
$this->render('alert', ['data' => $this->_data]);
}
}
this is the code of widgets/views/alert.php:
echo $data;
this is the code to how I use the widget in a view:
$this->widget('application.widgets.Alert');
finally I got these errors:
( ! ) SCREAM: Error suppression ignored for
( ! ) Fatal error: Cannot redeclare class AlertWidget in C:\wamp\www\mediastore\protected\widgets\Alert.php on line 27

About first question:
You must define method actionRequestAlert() as static
public static actionRequestAlert() {}

Related

PHP 8 migration Fatal error: Declaration must be compatible

We are moving forward to PHP 8 from PHP 7.4, we are facing Declaration must be compatible Fatal error in our code to custom parameter type, we need a proper solution with less code changes.
Kindly refer below code snippet
ERROR
Fatal error: Declaration of ClientReactieView::getUrlAddData(?ClientReactie $clientReactie = null) must be compatible with Overview\BaseView::getUrlAddData(?Storm\Model $model = null) in /var/www/html/system/tmp/class_client_reactie_view.php on line 102
abstract class file : abstract_class_base_view.php
<?php
namespace Overview;
use Storm;
abstract class BaseView {
public static function getUrlAddData(Storm\Model $model = null){
// ...
return $urlAddData;
}
}
Child class file : class_client_reactie_view.php
<?php
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(ClientReactie $clientReactie = null){
// ...
return $urlAddData;
}
}
Custom parameter type class_client_reactie.php
class ClientReactie extends Storm\Model {
// ...
}
Our application is already developed & working fine with PHP 7.4, We require solution to resolve this fatal error with less code changes
The error is telling your code is illogical.
The definition of BaseView makes a promise: you can call getUrlAddData and pass any instance of Storm\Model, or null.
The definition of ClientReactieView says that it extends BaseView, so inherits that promise. But then it changes that promise: you can call getUrlAddData, but you're not allowed to pass anything that's not a ClientReactie.
This is "covariance of input", and has always been forbidden for non-static methods - if $foo instanceof BaseView is true, then $foo->getUrlAddData(...) would have to accept all values that the definition in BaseView allowed.
What's new in PHP 8 is that this is enforced for static methods as well, so that the same guarantee applies to "late static binding" calls such as this:
abstract class BaseView {
public static function getUrlAddData(Storm\Model $model = null){
// ...
return $urlAddData;
}
public static function doSomethingElse(Storm\Model $model = null){
$urlAddData = static::getUrlAddData($model);
// ...
}
}
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(ClientReactie $clientReactie = null){
// ...
return $urlAddData;
}
}
ClientReactieView::doSomethingElse(new Storm\Model);
// ERROR! The call goes to BaseView::doSomethingElse, which accepts any Model
// But static::getUrlAddData resolves to ClientReactieView::getUrlAddData
// and that has an incompatible signature
So the correct fix is to honour the promise made by the parent class:
class ClientReactieView extends Overview\BaseView {
public static function getUrlAddData(Storm\Model $model = null){
if ( ! $model instanceof ClientReactie ) {
// Figure out what to do with such calls
}
// ...
return $urlAddData;
}
}

How To Pass Arguments To new Class & Define Variables

I'm trying to modify the plugin function in the original PHP class named My_Widget_Admin which i have copied over from a plugin to my theme, but get Fatal error Too few arguments to function My_Widget_Admin
Here is the code i added in my theme :
class Custom_Admin extends My_Widget_Admin {
function item_select() {
// Code
}
}
$new = new Custom_Admin;
$new->item_select();
I think it has something to do with this code from the plugin :
private $_instance;
private $_widget_object;
function __construct( $instance, $widget_object ) {
$this->_instance = $instance;
$this->_widget_object = $widget_object;
$this->form();
}
I need to pass these 2 arguments $instance, $widget_object to the new function Custom_Admin.
How do i do that?
Passing arguments to a constructor must be done when the class gets instantiated. This is done with the new keyword.
class Custom_Admin extends My_Widget_Admin {
function item_select() {
// Code
}
}
$new = new Custom_Admin($instance, $widget_object);
$new->item_select();

Using $this when not in object context in

I'm stuck probably at a fairly simple question... I'm working on a implementation with YAML to enable the duplication of the application.
However, setting up the config model is the part where I'm stuck.
class ConfigModel {
public $configSection = null;
private $configArray = array();
public function loadYML(){
$this->configArray = Spyc::YAMLLoad('../config/config.yml');
}
public function setConfigSection($configSection){
$this->configSection = $configSection;
}
public function getConfig($configSection){
$this->loadYML(); //Line 33
}
}
Through a test script I request the specific contents of the YML file:
$mysqlSettings = ConfigModel::getConfig('mysql');
But then I'm getting the error:
Fatal error: Using $this when not in object context in Line 33
The loadYML works and outputs a Array. And to my onderstanding the this->loadYML(); is allowed to be used there...
You trying to call ConfigModel::getConfig() as static method. It is is wrong to use $this in static method. You must declare $configArray as static property and loadYML() and getConfig() as static methods if you need to call getConfig() as static

how to make widget in Yii

I want to create a widget, here is the steps I made:
created folder widgets in folder protected.
created folder views in folder widgets.
added this in config/main.php : 'application.widgets.*'
this is the code of widgets/Alert.php:
class AlertWidget extends CWidget
{
public $alert = null;
private $_data = null;
public function init()
{
$s = Yii::app()->session['userId'];
$r = Requests::model()->findAll('idUser='.$s.' and confirm =0 and unconfirm=0 and cancel=0');
$i=0;
foreach($r as $x)
$i++;
if($i<=0)
$alert=null;
else
$alert="(".$i.")";
$this->_data = new CActiveDataProvider($alert);
}
public function run()
{
$this->render('alert', ['data' => $this->_data]);
}
}
this is the code of widgets/views/alert.php:
echo $data;
this is the code to how I use the widget in a view:
$this->widget('application.widgets.Alert');
finally I got these errors:
( ! ) SCREAM: Error suppression ignored for
( ! ) Fatal error: Cannot redeclare class AlertWidget in C:\wamp\www\mediastore\protected\widgets\Alert.php on line 27
if you're going to access the widget using $this->widget('application.widgets.Alert'); then, the widget class name should be Alert (like: public class Alert extends CWidget...) and the filename should remain Alert.php

PHP OOP error that I cannot understand

I try to extend the CheckfrontAPI class with my new class.
In my case I use the Singleton pattern in order to load only one instance at a time of my class and I get that error
Fatal error: Declaration of CheckFrontIntegrator::store() must be compatible with that of CheckfrontAPI::store() in /home/my_web_site/public_html/wp-content/plugins/checkfront/class/Checkfront_Integration.php on line 83
Any idea on how to solve that issue ?
Here is the CheckfrontAPI source code : https://github.com/Checkfront/PHP-SDK/blob/master/lib/CheckfrontAPI.php
And here is my class that extends that class:
<?php
class CheckFrontIntegrator extends CheckfrontAPI
{
private static $instance = null;
public $tmp_file = '.checkfront_oauth';
final protected function store($data = array())
{
$tmp_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR. $this->tmp_file;
if(count($data))
{
file_put_contents(
$tmp_file,
json_encode(
$data,
true
)
);
}
elseif(is_file($tmp_file))
{
$data = json_decode(
trim(
file_get_contents(
$tmp_file
)
),
true
);
}
return $data;
}
public function session($session_id, $data = array())
{
$_SESSION['checkfront']['session_id'] = $session_id;
}
public static function instance($data)
{
if(!isset(self::$instance))
{
self::$instance = new CheckFrontIntegrator($data);
}
return self::$instance;
}
public function __construct($data)
{
if(session_id() == '')
{
session_start();
}
parent::__construct($data, session_id());
}
}
?>
And I initiate the new instance of that class like that:
$this->checkfront_integrator = CheckFrontIntegrator::instance($args);
where args are all the important information needit by the class to initiate a new object
AFTER EDIT
I have change my method store from:
final protected function store($data = array())
....
to
protected function store($data)
....
and the problem still occure :(
CheckfrontAPI is an abstract class? in this case your CheckFrontIntegrator::store() arguments count must be identical to original declaration
EDIT
I see on github
abstract protected function store($data);
your override must be:
protected function store($data) {
}
You are extending CheckfrontAPI. CheckfrontAPI has a method store(). If you override that method you must do it properly.
Post the code of CheckfrontAPI and your class Checkfront_Integration: when can understand what's the problem.
When you want to extent the functionality of an existing class by writing your own class and the class you are extending is is an abstract one, you'll need to make sure that the function calls are compatible.
What does this mean?
If the class you are extending has this function call for example :
function walk($direction, $speed = null);
Then you will have to honor the function signature in your implementation - that means you'll still have to have to pass two function arguments in your version.
You will not be able to alter is to be like this :
function walk($direction, $speed, $clothing);

Categories