Having trouble navigating Magento documentation - magento

I am brand new to Magento and the documentation, primarily the phpDocs, are difficult to navigate. For example,
$attributeSet = Mage::getModel('eav/entity_attribute_set')->load($id);
In the php doc for Class Mage_Eav_Model_Entity_Attribute_Set there is no mention of the method getAttributeSetName() either in inherited methods or otherwise and yet this works.
$attributeSet = Mage::getModel('eav/entity_attribute_set')->load($id);
echo $attributeSet->getAttributeSetName();
So I suppose I have several questions.
Can someone explain to me why the documentation is this way?
Where I can find the mysterious getAttributeSetName() method in the phpDocs?
My theory is that there is some inheritance or a design pattern implementation going on that I'm not understanding, maybe someone can shed some light on this for me.

If you really want to fry your brain, take a look at the source code for Mage_Eav_Model_Entity_Attribute_Set and follow the inheritance chain all the way back. You won't find a getAttributeSetName method defined anywhere.
All Magento objects that inherit from Varien_Object can have arbitrary data members set on them. Try this.
$attributeSet = Mage::getModel('eav/entity_attribute_set')->load($id);
$attributeSet->setFooBazBar('Value');
var_dump($attributeSet->getFooBazBar());
var_dump($attributeSet->getData('foo_baz_bar'));
var_dump($attributeSet->setData('foo_baz_bar','New Value'));
var_dump($attributeSet->getFooBazBar());
You can also get all the data members by using
var_dump($attributeSet->getData());
but be careful dumping these, because if there's a data object that has a circular reference and you're not using something like xDebug, then PHP will have a fit trying to display the object.
Magento stores data properties in a special _data array property. You can get/set values in this array with getData and setData. Magento also has implemented magic getting and setter methods, so when you say something like
$object->getFooBazBar();
The method getFooBazBar is transformed into the data property foo_baz_bar. and then getData is called using this property. It's a little tricky to get your head around, but once you get it you'll start to see how much time you can save using this pattern.
One side effect of this is, of course, it's impossible to infer what data properties any object might have by looking at it's class file, so there's no phpDocs for these methods.

Related

Generating Navigation for different user types, MVC, PHP

I have this idea of generating an array of user-links that will depend on user-roles.
The user can be a student or an admin.
What I have in mind is use a foreach loop to generate a list of links that is only available for certain users.
My problem is, I created a helper class called Navigation, but I am so certain that I MUST NOT hard-code the links in there, instead I want that helper class to just read an object sent from somewhere, and then will return the desired navigation array to a page.
Follow up questions, where do you think should i keep the links that will only be available for students, for admins. Should i just keep them in a text-file?
or if it is possible to create a controller that passes an array of links, for example
a method in nav_controller class -> studentLinks(){} that will send an array of links to the helper class, the the helper class will then send it to the view..
Sorry if I'm quite crazy at explaining. Do you have any related resources?
From your description it seems that you are building some education-related system. It would make sense to create implementation in such way, that you can later expand the project. Seems reasonable to expect addition of "lectors" as a role later.
Then again .. I am not sure how extensive your knowledge about MVC design pattern is.
That said, in this situation I would consider two ways to solve this:
View requests current user's status from model layer and, based on the response, requests additional data. Then view uses either admin or user templates and creates the response.
You can either hardcode the specific navigation items in the templates, from which you build the response, or the lit of available navigation items can be a part of the additional information that you requested from model layer.
The downside for this method is, that every time you need, when you need to add another group, you will have to rewrite some (if not all) view classes.
Wrap the structures from model layer in a containment object (the basis of implementation available in this post), which would let you restrict, what data is returned.
When using this approach, the views aways request all the available information from model layer, but some of it will return null, in which case the template would not be applied. To implement this, the list of available navigation items would have to be provided by model layer.
P.S. As you might have noticed from this description, view is not a template and model is not a class.
It really depends on what you're already using and the scale of your project. If you're using a db - stick it there. If you're using xml/json/yaml/whatever - store it in a file with corresponding format. If you have neither - hardcode it. What I mean - avoid using multiple technologies to store data. Also, if the links won't be updated frequently and the users won't be able to customize them I'd hardcode them. There's no point in creating something very complex for the sake of dynamics if the app will be mostly static.
Note that this question doesn't quite fit in stackoverflow. programmers.stackexchange.com would probably be a better fit

Yii framework: How do I use CActiveRecord.beforeFind()?

I'm in a need to use beforeFind() in a child class of CActiveRecord.
Basically, I need to convert some data from before actual search in the DB is performed.
How do I alter the about-to-occur-find-operation that is about to take place, inside beforeFind()? Messing with $this attributes is not useful since its not even populated, which is a little surprise.
I've seen that the documentation mentions a "hidden CDbCriteria parameter" but I just couldn't guess how to use it... . Unfortunately, the documentation on this subject is slim.
What I need to do is rather simple: I've got a table column for storing IP addresses. The most efficient design from scalability perspective, is to use a VARBINARY(16) data type for the column. See for example this SO question page (and answers) on this.
So, the cleanest solution would be to have beforeFind(), afterFind() and beforeSave() work transparently for the users.
In the code stack, the IP addresses would be the normal dotted-quad and in the DB level, its whatever that goes into the field after utilizing PHP's inet_pton() method in those after/before hook methods.
It was supposed to be cool. and it is cool - with afterFind() and beforeSave(), where I have the ip_address attribute of the object at hand, at the mercy of my uber-manipulation powers.
Here's the point, and the need: thing is, I don't know how to achieve that on beforeFind(). I cannot do a blind mergeWith() as I need to check if ip_address attribute is part of the original criteria, and that I don't know how to do.
Help!
TIA :)
I've got this nice suggestion on yii forums.
Basically, I just need to override findByAttributes() in the child class and I'm done :)

Best practices when writing glue code

I asked this question to get some opinions on the subject of glue code.
For example, imagine you have a class (pseudocode):
class MyClass
int attribute a
string attribute b
And to represent that data model, you have BOTH a slider and a text box to represent a, and a text box and say... the window label to represent b.
Obviously, when one of these view objects is changed, you want to update the others. However, updating the entire view is obviously inefficient.
method onSomethingHappened(uiObject)
model.appropriateAttribute = uiObject.value
The question is, what is your opinion on what to do next? Should the model object implement a callback that notifies a listener when the value has been changed, allowing one to write glue code like:
method modelChangedCallback(model, attribute)
uiObject1.value = model.a
uiObject2.value = model.a
Where you might examine what the attribute that changed is, and respond accordingly? This is the model in Objective-C and Cocoa on Mac, for the most part.
OR, would you rather have the responsibility lie completely in the glue code?
method onSomethingHappened(uiObject)
model.appropriateAttribute = uiObject.value
self.updateForAttribute("appropriateAttribute")
Both of these approaches can get pretty hairy (as is the problem with glue code) when your project gets large. Maybe there are other approaches. What do you think?
Thanks for any input!
For me I think it comes down to where the behavior is needed. In the situation you describe, the fact that you are binding multiple controls to a property is what is driving the requirement, so it doesn't make sense to add code to the model to support that.
In a web-based model I would probably put the logic in the web page since that can be done rather cheaply using Javascript. If I don't have that luxury (i.e. I'm dealing with a "dumb" view), then it would probably make sense to do it in the controller, or model glue code. If this sort of thing becomes common enough, I may go as far as creating some form of generic helper to reduce the amount of boiler-plate code I have to deal with.

Philosophy Object/Properties Parameter Query

I'm looking at some code I've written and thinking "should I be passing that object into the method or just some of its properties?".
Let me explain:
This object has about 15 properties - user inputs. I then have about 10 methods that use upto 5 of these inputs. Now, the interface looks a lot cleaner, if each method has 1 parameter - the "user inputs object". But each method does not need all of these properties. I could just pass the properties that each method needs.
The fact I'm asking this question indicates I accept I may be doing things wrong.
Discuss......:)
EDIT: To add calrity:
From a web page a user enters details about their house and garden. Number of doors, number of rooms and other properties of this nature (15 in total).
These details are stored on a "HouseDetails" object as simple integer properties.
An instance of "HouseDetails" is passed into "HouseRequirementsCalculator". This class has 10 private methods like "calculate area of carpet", "caclulateExtensionPotential" etc.
For an example of my query, let's use "CalculateAreaOfCarpet" method.
should I pass the "HouseDetails" object
or should I pass "HouseDetails.MainRoomArea, HouseDetails.KitchenArea, HouseDetails.BathroomArea" etc
Based on my answer above and related to your edit:
a) You should pass the "HouseDetails"
object
Other thoughts:
Thinking more about your question and especially the added detail i'm left wondering why you would not just include those calculation methods as part of your HouseDetails object. After all, they are calculations that are specific to that object only. Why create an interface and another class to manage the calculations separately?
Older text:
Each method should and will know what part of the passed-in object it needs to reference to get its job done. You don't/shouldn't need to enforce this knowledge by creating fine-grained overloads in your interface. The passed-in object is your model and your contract.
Also, imagine how much code will be affected if you add and remove a property from this object. Keep it simple.
Passing individual properties - and different in each case - seems pretty messy. I'd rather pass whole objects.
Mind that you gave not enough insight into your situation. Perhaps try to describe the actual usage of this things? What is this object with 15 properties?, are those "10 methods that use upto 5 of these input" on the same object, or some other one?
After the question been edited
I should definitely go with passing the whole object and do the necessary calculations in the Calculator class.
On the other hand you may find Domain Driven Design an attractive alternative (http://en.wikipedia.org/wiki/Domain-driven_design). With regard to that principles you could add methods from calculator to the HouseDetails class. Domain Driven Design is quite nice style of writing apps, just depends how clean this way is for you.

How to construct two objects, with each other as a parameter/member

I have two classes that each need an instance of each other to function. Ordinarily if an object needs another object to run, I like to pass it in the constructor. But I can't do that in this case, because one object has to be instantiated before the other, and so therefore the second object does not exist to be passed to the first object's constructor.
I can resolve this by passing the first object to the second object's constructor, then calling a setter on the first object to pass the second object to it, but that seems a little clunky, and I'm wondering if there's a better way:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel();
I've never put any study into MVC; I suppose I'm dealing with a model here (the Backend), and a view or a controller (the Panel). Any insights here I can gain from MVC?
It's time to take a look at MVC. :-) When you have a model-view-controller situation, the consensus is that the model shouldn't be aware of the view-controller (MVC often plays out as M-VC), but the view is invariably aware of the model.
If the model needs to tell the view something, it does so by notifying its listeners, of which it may have multiples. Your view should be one of them.
In a circular construction scenario I'd use a factory class/factory method. I would normally make the construction logic private to the factory (using friend construct, package level protection or similar), to en sure that no-one could construct instances without using the factory.
The use of setter/constructor is really a part of the contract between the two classes and the factory, so I'd just use whichever's convenient.
As has been pointed out, you really should try to find a non-circular solution.
First of all, contrary to what others has said here, there's no inherent problem with circular references. For example, an Order object would be expected to have a reference to the Customer object of the person who placed the Order. Similarly, it would be natural for the Customer object to have a list of Orders he has placed.
In a refernce-based language (like Java or C#) there's no problem, at all. In a value-based language (like C++), you have to take care in designing them.
That said, you design of:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel(panel);
It pretty much the only way to do it.
It's better to avoid circular references. I would personally try to rethink my objects.
panel = new Panel(backend);
You do this in this routine something like
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd
BackEnd.MyPanel = Me
End Sub
You don't need BackEnd.SetPanel
It is better to use Proxies. A proxy links one object to another through raising a Event. The parent hands the child a proxy. When the child needs the parent it calls a GetRef method on the proxy. The proxy then raises a event which the parent uses to return itself to the proxy which then hands it to the child.
The use of the Event/Delegate mechanism avoids any circular reference problems.
So you have (assuming that the backend is the 'parent' here)
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd.Proxy
BackEnd.MyPanel = Me
End Sub
Public Property MyBackEnd() as BackEnd
Set (ByVal Value as BackEnd)
priBackEndProxy = BackEnd.Proxy
End Set
Get
Return priBackEndProxy.GetRef
End Get
End Property
Here is a fuller discussion on the problem of circular references. Although it is focused on fixing it in Visual Basic 6.0.
Dynamic Memory Allocation
Also another solution is aggregating Panel and BackEnd into another object. This is common if both elements are UI Controls and need to behave in a coordinated manner.
Finally as far as MVC goes I recommend using a a Model View Presenter approach instead.
Basically you have your Form Implement a IPanelForm interface. It registers itself with a class called Panel which does all the UI logic. BackEnd should have events that Panel can hook into for when the model changes. Panel handles the event and updates the form through the IPanelForm interface.
User clicks a button
The form passes to Panel that the user clicked a button
Panel handles the button and retrieves the data from the backend
Panel formats the data.
Panel uses IPanelForm Interface to show the data on the Form.
I've been delaying implementing the lessons learned here, giving me plenty of time to think about the exact right way to do it. As other people said, having a clear separation where the backend objects have listeners for when their properties change is definitely the way to go. Not only will it resolve the specific issue I was asking about in this question, it is going to make a lot of other bad design smells in this code look better. There are actually a lot of different Backend classes (going by the generic class names I used in my example), each with their own corresponding Panel class. And there's even a couple of places where some things can be moved around to separate other pairs of classes into Backend/Panel pairs following the same pattern and reducing a lot of passing junk around as parameters.
The rest of this answer is going to get language specific, as I am using Java.
I've not worried a whole lot about "JavaBeans," but I have found that following basic JavaBean conventions has been very helpful for me in the past: basically, using standard getters and setters for properties. Turns out there's a JavaBean convention I was unaware of which is really going to help here: bound properties. Bound properties are properties available through standard getters and setters which fire PropertyChangeEvents when they change. [I don't know for sure, but the JavaBeans standard may specify that all properties are supposed to be "bound properties." Not relevant to me, at this point. Be aware also that "standard" getters and setters can be very non-standard through the use of BeanInfo classes to define a JavaBean's exact interface, but I never use that, either.] (The main other JavaBean convention that I choose to follow or not as appropriate in each situation is a no-argument constructor; I'm already following it in this project because each of these Backend objects has to be serializable.)
I've found this blog entry, which was very helpful in cluing me into the bound properties/PropertyChangeEvents issue and helping me construct a plan for how I'm going to rework this code.
Right now all of my backend objects inherit from a common class called Model, which provides a couple of things every backend in this system needs including serialization support. I'm going to create an additional class JavaBean as a superclass of Model which will provide the PropertyChangeEvent support that I need, inherited by every Model. I'll update the setters in each Model to fire a PropertyChangeEvent when called. I may also have JavaBean inherited by a couple of classes which aren't technically Models in the same sense as these but which could also benefit from having other classes registered as listeners for them. The JavaBean class may not fully implement the JavaBean spec; as I've said, there are several details I don't care about. But it's good enough for this project. It sounds like I could get all this by inheriting from java.awt.Component, but these aren't components in any sense that I can justify, so I don't want to do that. (I also don't know what overhead it might entail.)
Once every Model is a JavaBean, complete with PropertyChangeEvent support, I'll do a lot of code cleanup: Models that are currently keeping references to Panels will be updated and the Panels will register themselves as listeners. So much cleaner! The Model won't have to know (and shouldn't have known in the first place) what methods the Panel should call on itself when the property updates.

Resources