I'm trying to use setData in my Address object.
Here is the code:
//code inside another class
$this->getAddress()->setData('abc', 'abc')->collectShippingRates()->save();
class Mage_Sales_Model_Quote_Address extends Mage_Customer_Model_Address_Abstract
{
...
public function collectShippingRates()
{
...
$found = $this->requestShippingRates();
...
return $this;
}
public function requestShippingRates(Mage_Sales_Model_Quote_Item_Abstract $item = null)
{
//I knkow it's getting here, because when I echo 'blablabla', it works.
//When I use $this->setData('abc', 'abc') here, the code bellow print 'abc'
//The problem is when I use setData outside the class
echo $this->getData('abc');exit; //prints nothing
...
}
...
}
As you can see, I setData in my Address model, but inside the class getData returns nothing.
Can someone please explain what's happening?
When I try to use Mage::register, it does not work too.
Possible avenues of exploration.
Your call to getAddress isn't returning a Mage_Sales_Model_Quote_Address object, or is returning a different instance of an address object.
Your call to setData('abc', 'abc') happens later in Magento's code execution than the first call to requestShippingRates.
Code between your call to getAddress and the execution of requestShippingRates is re-instantiating or initializing the address object.
Based on your comments about Mage::register, my money is on number two.
Related
I wrote a simple access control system which reads an array of access strings, and return true or false depending on the result.
I would call it as follows (for example in a method list_user_data of class User): `
if (current_user_can(__CLASS__, __METHOD__)) {
...
}
and inside there, it checks if the current user has permission to access method list_user_data in class User.
It works, but I find it annoying that I always have to specify __CLASS__ and __METHOD__ in the call. Is there a way to get those values from within the current_user_can function for the calling function so that I can simply call current_user_can() without having to pass the magic constants?
My code works as is, but I am thinking it could be improved.
Is this possible?
The return value from debug_backtrace should return the calling function in the 2nd entry (index 1), for example:
<?php
function current_user_can()
{
$backtrace = debug_backtrace(false, 2);
// ToDo: Check if $backtrace[1] (and especially the class-key of that) actually exist...
// It should always (although the class key might not if this function isn't called from within a class), since this function is being called
// but it's still a good habbit to check array keys before accessing the array
$callerClass = $backtrace[1]["class"];
$callerMethod = $backtrace[1]["function"];
// ToDo: implementation of check, in this example $callerClass would be "User" and $callerMethod would be "list_user_data"
return true;
}
class User {
public function list_user_data() {
if (current_user_can())
{
}
}
}
$user = new User();
$user->list_user_data();
I have two class like this:
class one
{
public $var1 = 'anythig';
}
class two
{
public $var2 = 'anythig';
}
I want to know when I create a object instance of these classes what happens? My point is about the values stored in the memory. In reality I have some big class, and my resources are limited. then I want to know, If I put NULL into my class when don't need to it anymore is good ? and help to optimizing ?
I have a switch() to include the desired class. something like this:
switch{
case "one":
require_once('classes/one.php');
break;
case "two":
require_once('classes/two.php');
break;
}
Every time I only need one class. When I define a new object ($obj = new class) what happens to my class previously defined as object instance? that is remain in memory? and if I put NULL is helpful ? Please guide me ..
Edit:
The last line is useful or not ?
$obj = new myvlass;
echo $obj->property; // there is where that my class is done
$obj=NULL;
What determines when a class object is destroyed in PHP?
The PHP manual states that "the destructor method will be called as soon as all references to a particular object are removed" which is true (although can lead to some undesirable behaviour.)
It wouldn't really matter if you explicitly set an object variable to be NULL, PHP would destruct it anyway.
i would recommend my best way to implement class as follow :
<?php
class scSendMail
{
protected $from;
protected $toList;
protected $replyTo;
protected $subject;
protected $message;
public function __construct()
{
register_shutdown_function(array($this,'__destruct'));
$this->setFrom("updates#planetonnet.com");
$this->setReplyTo("noreply#planetonnet.com");
$this->setSubject("Update from PlanetOnNet.com");
}
public function __destruct()
{
unset($this->from);
unset($this->toList);
unset($this->replyTo);
unset($this->subject);
unset($this->message);
}
public function sendMail()
{
// ..... body
}
}
?>
in this way whenever object is not needed, it will destruct itself and free ups memory by unsetting variables used.
you can initiate another object anytime to replace with new object but be careful to use methods according to what object currently it is holding.
you can set to NULL to free ups memory whenever you dont need to use it anymore and use new variable to use new object.
How to combine two variables to obtain / create new variable?
public $show_diary = 'my';
private my_diary(){
return 1;
}
public view_diary(){
return ${"this->"}.$this->show_diary.{"_diary()"}; // 1
return $this->.{"$this->show_diary"}._diary() // 2
}
both return nothing.
Your class should be like following:
class Test
{
public $show_diary;
function __construct()
{
$this->show_diary = "my";
}
private function my_diary(){
return 707;
}
public function view_diary(){
echo $this->{$this->show_diary."_diary"}(); // 707
}
}
It almost looks from your question like you are asking about how to turn simple variables into objects and then how to have one object contain another one. I could be way off, but I hope not:
So, first off, what is the differnce between an object and a simple variable? An object is really a collection of (generally) at least one property, which is sort of like a variable within it, and very often functions which do things to the properties of the object. Basically an object is like a complex variable.
In PHP, we need to first declare the strucutre of the object, this is done via a class statement, where we basicaly put the skeleton of what the object will be into place. This is done by the class statement. However, at this point, it hasn't actually been created, it is just like a plan for it when it is created later.
The creation is done via a command like:
$someVariable= new diary();
This executes so create a new variable, and lays it out with the structure, properties and functions defined in the class statement.
From then on, you can access various properties or call functions within it.
class show_diary
{
public $owner;
public function __construct()
{
$this->owner='My';
}
}
class view_diary
{
public $owner;
public $foo;
public function __construct()
{
$this->foo='bar';
$this->owner=new show_diary();
}
}
$diary= new view_diary();
print_r($diary);
The code gives us two classes. One of the classes has an instance of the other class within it.
I have used constructors, which are a special type of function that is executed each time we create a new instance of a class - basically each time we declare a variable of that type, the __construct function is called.
When the $diary= new view_diary(); code is called, it creates an instance of the view_diary class, and in doing so, the first thing it does is assigns it's own foo property to have the value 'bar' in it. Then, it sets it's owner property to be an instance of show_diary which in turn then kicks off the __construct function within the new instance. That in turn assigns the owner property of the child item to have the value 'My'.
If you want to access single properties of the object, you can do so by the following syntax:
echo $diary->foo;
To access a property of an object inside the object, you simply add more arrows:
echo $diary->owner->owner;
Like this?
$diary = $this->show_diary . '_diary';
return $this->$diary();
I have created a class in following way
class History
{
private $historyArray;
private $cacheFileNameArray=array();
public function __construct()
{
$this->historyArray=array();
}
public function writeToHistory($query)
{
$cacheFileName=$this->getCacheFileName();
$query=$query.chr(219)."1".chr(219).$cacheFileName;
array_push($this->historyArray,$query);
print_r($this->historyArray);
}
}
Now i have created an object of class History as h,then i'm calling the function writeToHistory() two times with 2 different argument by i wonder that array_push() is not working cause in time of 2nd calling of the function the query should be written in the 1 index of the array but actually the first element of the array is being replaced.Any idea why?
Yes, #shapeshifter is right. it's static.
You could even do
array_push(History->$historyArray, $query);
or
array_push(self::$historyArray, $query);
or
History->$historyArray[] = $query;
PHP manual says "If you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function."
(Note from http://php.net/manual/en/function.array-push.php);
Your historyArray is static. Try,
array_push(self::$historyArray,$query);
Why are you declaing historyArray as an array in the constructor?
Also, where is the function '' defined in your class? if its not defined, that might be causing you trouble... getCacheFileName();
and, give us an example of what you are passing to your writeToHistory function '$query' variable so that we can mode easily see whats going on please
Change you code to the following:
class History
{
private $historyArray = array();
private $cacheFileNameArray= array();
public function __construct()
{
}
public function writeToHistory($query)
{
$cacheFileName=$this->getCacheFileName();
$query=$query.chr(219)."1".chr(219).$cacheFileName;
array_push($this->historyArray,$query);
print_r($this->historyArray);
}
}
I've been trying to learn cakephp recently but I'm struggling to find any tutorials that deal with storing data into a table after it's been modified. I'm used having complete control where everything goes in PHP, so it's been a struggle adjusting to the automated processe of MVC.
I thought a good first experiment would be to take an input and concatenate a letter to it(let's just say "m"). Then, store both the original value and the concatenated value in a table with fields "orignal" and "concatenated". So, if I typed "hello", the value in the original field would be "hello" and the concatenated field would be "hellom".
My question is would the model be responsible for concatenating the original value? Would it also do the saving or is that the controllers responsibility?
Here is my code: I'm getting the following error.
Fatal error: Call to a member function save() on a non-object in /Applications/XAMPP/xamppfiles/htdocs/cake/app/Model/Concatenate.php on line 6
View/Concatenates/add.php
<h1>Add Something</h1>
<?php
echo $this->Form->create('Concatenate');
echo $this->Form->input('original');
echo $this->Form->end('Add Numbers');
?>
Now for the model
class Concatenate extends AppModel {
function saveConcat($original,$concatenated) {
$this->set(array(
'original' => $original,
'concatenated' => $concatenated));
$this->save();
}
}
?>
Now for the controller
<?php
class ConcatenatesController extends AppController {
public $helpers = array('Html', 'Form');
public $components = array('Session');
public function index() {
$this ->set('concatenates', $this->Concatenate->find('all'));
}
public function add() {
if ($this->request->is('post')) {
$original = $this->request->data['Concatenate']['original'];
$concatenated = $original."m" ;
$this->Concatenate->saveConcat($original,$concatenated);
}
}
function isempty(){ //used to check if there is data in the table. If there isn't any, "no data" will be displayed
$mysorts = $this->Concatenate->find('all');
$this->set('concatenates', $mysorts);
}
}
?>
This is the never ending debate (or preference) about fat model/skinny controller and vice versa.
As far as saving goes, the model should definitely handle the logic for that. Although, you would most likely call it from the controller like $myModel->save($data);
In concatenating values, I would personally handle that in the controller because it is business logic that isn't directly related to the model. For example, you may wish to concatenate a string and send it to the view instead.
[EDIT]
Disclaimer: I have almost zero experience with CakePHP but the fundamentals are the same.
You mentioned you can't get it to work, so one thing I am noticing is you have a function called Concatenate() in your model. This is the PHP4 style of constructors and is no longer "best practice" (unless of course you are running PHP4 but why on earth would you be doing that). In fact, it is likely to be deprecated entirely in the near future. The PHP5 way of doing constructors is with the __construct() function. If you do decide to use a constructor, I'd make sure to call parent::__construct(); in it to ensure the parent AppController class loads correctly.
In looking at the Concatenate() method's functionality, I doubt you intend to have that as your constructor anyway. Rename that function to something clear like saveConcat(). Also, I'm not sure I would be using $this->request->data as your source in case you want to be able to reuse this function and call it with any value. In that case, I'd add a parameter to the function
class Concatenate extends AppModel {
function saveConcat($data) {
if ($this->Concatenate->save($data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
Then somewhere in your controller, you will have to actually call this function. Modify your add() function from your controller to be something like this:
public function add() {
if ($this->request->is('post')) {
// Put data into array for saving
$data[] = array( 'original' => $this->request->data );
$data[] = array( 'concatenated' => $original."m" );
// Call model function to save it
$this->Concatenate->saveConcat($data);
}
}
[EDIT 2]
I just can't figure out why I'm getting the error: Call to a member function save() on a non-object.
When you call $this->Concatenate->save from inside the Concatenate class, that means you are trying to access a variable inside the class called Concatenate and execute a function. Neither of which exist of course. The reason is you need to call the object itself as such:
$this->save("blah blah");
That method (I'm assuming is a parent method from the AppModel class) will be called referencing the current instance of the Concatenate object.