I want the zend form to override the setValue function so that the value given to the function can be manipulated. How can i implement this?
My current form structure is like this:
class My_Form_Login
{
public $Form;
public $Username;
public function __construct()
{
$this->Form = new Form_Abstract();
$this->init();
}
public function init()
{
$this->Username ->setValue('100');
}
}
class Form_Abstract extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setDecorators(array( 'FormElements','FormErrors','Form' ));
}
public function setValue($value)
{
$strippedValue = stripslashes($value);
return parent::setValue($strippedValue);
}
}
Thanks in advance..
You can extend the Zend_Form into your own class like:
My_Form extends Zend_Form
{
public function setValue($arg)
{
// My override code here
}
}
Then use this class instead of the Zend_Form directly
Consider using the Zend filter interface instead. For example
class My_Filter_Stripslashes implements Zend_Filter_Interface
{
public function filter($value)
{
return get_magic_quotes_gpc() ? $this->_clean($value) : $value;
}
protected function _clean($value)
{
return is_array($value) ? array_map(array($this, '_clean'), $value) : stripslashes($value);
}
}
Then apply this to your elements after adding them
$form->setElementFilters(array(new My_Filter_Stripslashes));
Related
I am new in codeigniter.
I need to do the following code in utility.php which is a custom library.
class Utility{
public $x=test("123");
public function test($name)
{
return $name;
}
echo $x;
}
Thanks in advance
This is showing syntax error.
Maybe this way?
class Utility
{
public $x;
public function __construct($name = 'default name')
{
$this->x = $this->test($name);
}
public function test($name)
{
return $name;
}
}
Then in controller you would go with
class Welcome extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function index($name = null)
{
$this->load->library('utility', [$name]);
echo $this->utility->x;
}
}
Ok so currently have this function in controller, which is called multiple times.
public function formatFloat($value)
{
return (float)sprintf('%0.6f', $value);
}
So I am trying to use getters and setters so I can just use
$model->$whatever;
and the formatting will be done.
In my model I have
public function getChargePeak()
{
return $this->charge_peak;
}
public function setChargePeak($value)
{
return $this->charge_peak = (float)sprintf('%0.6f', $value);
}
but when doing
$peak = $model->chargepeak;
var_dump($peak);die;
it is still returning as a string
If the charge_peak property is stored as string and you need a float in you app you should use
public function getChargePeak()
{
return floatval($this->charge_peak);
}
Anyway you should store the values in a coherent way as you use the values in your app ..
http://php.net/manual/en/function.floatval.php
So I suggest u another pattern: decorator and helpers. You should use a controller only to get data from request, prepare it for model and send it to view.
Formatting values is a helper logic. So create a new class
\common\helpers\Number.php
namespace common\helpers;
class Number
{
public static function formatFloat($value)
{
return (float)sprintf('%0.6f', $value);
}
}
Then create decorator for your model:
namespace common\models\decorators;
class YourModelDecorator
{
/**
* YourModel
*/
private $model;
public function __construct(YourModel $model)
{
$this->model = $model;
}
public function __get($name)
{
$methodName = 'get' . $name;
if (method_exists(self::class, $methodName)) {
return $this->$methodName();
} else {
return $this->model->{$name};
}
}
public function __call($name, $arguments)
{
return $this->model->$name($arguments);
}
public function getChargePeak()
{
return \common\helpers\Number::formatFloat($this->model->charge_peak);
}
}
and send it to view for example:
public function actionView($id)
{
$model = $this->loadModel($id);
$this->render('view', [
'model' => new \common\models\decorators\YourModelDecorator($model)
]);
}
I have a class that extends from Yii2's Model and I need to declare a class public property in the constructor, but I'm hitting a problem.
When I call
class Test extends \yii\base\Model {
public function __constructor() {
$test = "test_prop";
$this->{$test} = null; // create $this->test_prop;
}
}
Yii tries to call, from what I understand, the getter method of this property, which of course doesn't exist, so I hit this exception.
Also, when I actually do $this->{$test} = null;, this method gets called.
My question is: Is there a way to declare a class public property in another way? Maybe some Reflexion trick?
You could override getter/setter, e.g. :
class Test extends \yii\base\Model
{
private $_attributes = ['test_prop' => null];
public function __get($name)
{
if (array_key_exists($name, $this->_attributes))
return $this->_attributes[$name];
return parent::__get($name);
}
public function __set($name, $value)
{
if (array_key_exists($name, $this->_attributes))
$this->_attributes[$name] = $value;
else parent::__set($name, $value);
}
}
You could also create a behavior...
Ok, I received help from one of Yii's devs. Here is the answer:
class Test extends Model {
private $dynamicFields;
public function __construct() {
$this->dynamicFields = generate_array_of_dynamic_values();
}
public function __set($name, $value) {
if (in_array($name, $this->dynamicFields)) {
$this->dynamicFields[$name] = $value;
} else {
parent::__set($name, $value);
}
}
public function __get($name) {
if (in_array($name, $this->dynamicFields)) {
return $this->dynamicFields[$name];
} else {
return parent::__get($name);
}
}
}
Note that I'm using in_array instead of array_key_exists because the dynamicFields array is a plain array, not an associative one.
EDIT: This is actually wrong. See my accepted answer.
Try to set variable in init method.
Like this:
public function init() {
$test = "test_prop";
$this->{$test} = null; // create $this->test_prop;
parent::init();
}
I have the following PHP code as chain of resposibility, I am using PHP5.4.9.
abstract class Logger
{
protected $next;
public function next($next)
{
$this->next = $next;
return $this->next;
}
public function run(){
$this->invoke();
if(null!=$this->next){
$this->next->invoke();
}
}
abstract public function invoke();
}
class EmailLogger extends Logger
{
public function invoke()
{
print_r("email\n");
}
}
class DatabaseLogger extends Logger
{
public function invoke()
{
print_r("database\n");
}
}
class FileLogger extends Logger
{
public function invoke()
{
print_r("file \n");
}
}
$logger = new EmailLogger();
$logger->next(new DatabaseLogger())->next(new FileLogger());
$logger->run();
the expect output is:
email
database
file
but the actually output:
email
database
I hope to implement chain of resposibility design pattern by PHP language, one abstract class and three or more classes to do something as a chain. but only the first two object works.
Anyting missing? Or PHP can not use this coding style under PHP5.4.9?
Thanks.
Replace
public function run() {
$this->invoke ();
if (null != $this->next) {
$this->next->invoke();
}
}
With
public function run() {
$this->invoke ();
if (null != $this->next) {
$this->next->run ();
}
}
please try $this->next->invoke() change $this->next->run()
There is a bug that says that if you use fetch_object('classname') it will call the _set method before the _construct. So how do you get the object instantiated before it calls the __set method.
this Bug/Feature is an interesting PHP Flaw. It is handy in cases like this:
class MyModel {
public $id;
public $column2;
public $column3;
public function __construct() {
//work with prefilled properties from database here
}
}
$model = $mysqli->query()->fetch_object('MyModel');
and it even works in this case:
class MyModel {
public $data;
public function __construct() {
//work with $this->data here
}
public function __set($name, $value) {
$this->data[$name] = $value;
}
}
$model = $mysqli->query()->fetch_object('MyModel');
but it bites you in cases like this:
class MyModel {
public $data;
public function __construct($someOtherService) {
$this->service = $someOtherService;
}
public function __set($name, $value) {
$this->service->workWith($name, $value);
$this->data[$name] = $value;
}
}
$model = $mysqli->query()->fetch_object('MyModel');