how to make widget in Yii - php

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

Related

Wordpress: Overriding a function in a derived class

I need to override the function adforest_profile_full_top() from profile.php. This function is in a class called adforest_profile.
I added this code in my function.php:
add_action( 'after_setup_theme', function() {
class Myclass extends adforest_profile {
function adforest_profile_full_top() {
//original function code with my custom modifications
}
}
new Myclass();
});
With this, I received the following error:
Parse error syntax error unexpected '$user_pic'
This is the parent PHP file that contains the function I want to override:
<?php
if (!class_exists('adforest_profile')) {
class adforest_profile {
// user object
var $user_info;
public function __construct() {
$this->user_info = get_userdata(get_current_user_id());
}
// Full Width Profile Top
function adforest_profile_full_top() {
$user_pic = adforest_get_user_dp($this->user_info->ID, 'adforest-user-profile');
//and more code...
}
}
}
?>
Can you give me a good way to override this function in my function.php file? I don't want to override the entire class, just one function inside the class. Thank you.

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();

calling controller's action in another controller, making widget

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() {}

Access model from Thread in Yii

I have to parse a huge csv files in a Yii 1.1 Application.
Each row has to be validated and saved to the database.
I decided to use Multi Threading for this task.
So here is my code in the Controller action:
public function parseData($) {
$this->content = explode("\n", $this->content);
$thread_1 = new DatalogThread(array_slice($this->content, 0, 7000));
$thread_2 = new DatalogThread(array_slice($this->content, 7001));
$thread_1->start();
$thread_2->start();
}
And the Thread (I put it in models folder):
class DatalogThread extends Thread {
public $content;
public function __construct($content) {
$this->content = $content;
}
public function run() {
foreach ($this->content as $value) {
$row = str_getcsv($value);
$datalog = new Datalog($row);
$datalog->save();
}
}
}
The problem is that the Thread does not get access to the model file:
Fatal error: Class 'Datalog' not found in C:\xampp...\protected\models\DatalogThread.php
I tried Yii::autoload("Datalog"), but got The following error:
Fatal error: Cannot access property Yii::$_coreClasses in ...\YiiMain\framework\YiiBase.php on line 402
Yii uses a LOT of statics, this is not the best kind of code for multi-threading.
What you want to do is initialize threads that are not aware of Yii and reload it, I do not use Yii, but here's some working out to give you an idea of what to do:
<?php
define ("MY_YII_PATH", "/usr/src/yii/framework/yii.php");
include (MY_YII_PATH);
class YiiThread extends Thread {
public $path;
public $config;
public function __construct($path, $config = array()) {
$this->path = $path;
$this->config = $config;
}
public function run() {
include (
$this->path);
/* create sub application here */
}
}
$t = new YiiThread(MY_YII_PATH);
$t->start(PTHREADS_INHERIT_NONE);
?>
This will work much better ... I should think you want what yii calls a console application in your threads, because you don't want it trying to send any headers or anything like that ...
That should get you started ...

How to include a php and then remove it?

Well, I don't know if this post have the correct title. Feel free to change it.
Ok, this is my scenario:
pluginA.php
function info(){
return "Plugin A";
}
pluginB.php
function info(){
return "Plugin B";
}
Finally, I have a plugin manager that is in charge of import all plugins info to pool array:
Manager.php
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("pluginA.php", "pluginB.php");
foreach ($plugin_names as $name)
{
include_once $name;
$this->pool[] = info();
}
}
}
The problem here is that when I print pool array it only show me the info on the first plugin loaded. I supposed that the file inclusing override the info because it still calling the info() method from the first include.
Is there a way to include the info of both plugins having the info() function with the same name for all plugins files?
Thank you in advance
PS: a fatal cannot redeclare error is never hurled
you can use the dynamic way to create plugin classes
plugin class
class PluginA
{
public function info()
{
return 'info'; //the plugin info
}
}
manager class
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("pluginA", "pluginB"); //Plugin names
foreach ($plugin_names as $name)
{
$file = $name . '.php';
if(file_exists($file))
{
require_once($file); //please use require_once
$class = new $name(/* parameters ... */); //create new plugin object
//now you can call the info method like: $class->info();
}
}
}
}
Are you sure the interpreter isn't choking w/ a fatal error? It should be since you're trying to define the info function twice here.
There are many ways to achieve what you want, one way as in #David's comment above would be to use classes, eg.
class PluginA
{
function info() { return 'Plugin A'; }
}
class PluginB
{
function info() { return 'Plugin B'; }
}
then the Manager class would be something like this:
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("PluginA", "PluginB");
foreach ($plugin_names as $name)
{
include_once $name . '.php';
$this->pool[] = new $name();
}
}
}
Now you have an instance of each plugin class loaded, so to get the info for a plugin you would have $this->pool[0]->info(); for the first plugin. I would recommend going w/ an associative array though so you can easily reference a given plugin. To do this, the assignment to the pool would become:
$this->pool[$name] = new name();
And then you can say:
$this->pool['PluginA']->info();
for example.
There are many other ways to do it. Now that 5.3 is mainstream you could just as easily namespace your groups of functions, but I would still recommend the associative array for the pool as you can reference a plugin in constant time, rather than linear.

Categories