Magento - Correct Place to store values to be used for attributes - magento

I have an dropdown attribute that I am creating during my module setup.
I want to pre-populate this attribute with some values while my module is installing. I can do this no problem, currently by simply storing the values in an array and then creating adding the options to the attribute in the install script.
Where would be the correct place to store these values - in a model? If so would it be a source model utilizing the toOptionArray method? This is technically used for forms so it doesnt seem right. But neither does just storing the values in the setup script.
Any ideas?

Yes, the toOptionArray method would be in line with standard Magento practices.

Typically the toOptionArray() is found in Helpers, if that is what you are asking. Helpers extend far fewer classes, and therefore inherit far fewer methods than models. This makes them much lighter weight for simple tasks like setting up an array of options, provided that they are static.
If the values are stored in a new DB table, and can be expanded upon by the user, it may make more sense to put this in a Model that has direct access to your DB table.

Related

Global Variables in Laravel for Views, Controllers, Models etc

I know this question has been asked before, but I am struggling to find an answer that fits my needs, or is for the most up to date version of Laravel.
Basically, I have a load of variables that will be created using data from the Route and the database. For example, I need to use the Route to set a variable called "current_page" which extracts details from the "pages" table using the unique url column. ($current_page = Page::where('url', <url-taken-from-route>)->first();)
$current_page will need to contain several relationships. There are also other global variables such as $current_site (this is a kind of multi-site environment with one home page and nested microsites) etc.
I feel the configuration files are not the right place to create these variables as a) the value of the variables can be nested and complicated and b) they are not constants but data retrieved from a database.
View Composers obviously only work with views, and a Helper class just feels too generic considering we are dealing with pages, sites, and possibly other global variables.
I gather global variables are frowned upon, but these truly are global. The values will always be the same (albeit dynamic) on every occasion, and will be required by most views and controllers.
I have also thought about putting methods in my already existing Page and Site controllers so I can call Page::current(), but am not sure putting static methods in a mostly non-static controller is the right thing to do. Also, this would make a database call every time I called Page::current() rather than having the current page stored in memory somewhere.
For now, I have created a BaseController which all other controllers extend from. I have put these variables in the constructor and manually passed them to the view in each method. (I know that is messy and doesn't work for models).
So what is the best solution here? Where to declare a global variable that can be used anywhere, but doesn't feel hacky?
Thanks

Chef Ruby object and collections

I've dipped my toe in chef and am having a few difficulties with what should be simple concepts.
I'm obtains data from a node by running a search; my plan is to iterate over the results and create an object of type X setting its variables as I go.
I'd like to store these objects in a collection so that I can access them later in the recipe to carry out other tasks and so on.
My GoogleFu has so far come up short and I'm worried that I'm tackling this in the wrong way. My search is fine and returning the values, my separate class is also fine but the storing of these objects into a collection and then persisting that is proving more difficult. Many posts frown against using arrays for my purpose(if it's possible) and I've not found anything similar to an ArrayList or Map. Additionally, if I use a ruby collection, does it need to be maintained inside a ruby block?
Thanks for any help / advice.
With Chef, you have several ways of storing persistent data:
1) set node attributes
2) chef data bags
3) chef vault
4) environments
5) environment recipes
6) roles
IMHO, you should decide where this data should reside by determining which of the items I listed it belongs to.
What does it apply to? What does it describe?
You got to be more specific in where you are actually facing the issue but as far as I have understood why not
just define a ruby class and initialize all the variables you are supposed to get. In the recipe instantiate the object and keep settings its properties from the result. There should be no issue in this approach.
But more importantly what is your use-case here, because you could just define an array attribute and then keep syncing the result in that attribute . As in ruby Objects are referenced , thus any change you make to resource attributes which takes that object, changes are persistent to in that object.

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

Best place for getStoreConfig - block or model

When creating a magento module i sometimes need store config values for use in a template file. Where would be the best place for this - should I create a model or is a helper or block good enough?
I thinking in terms of best practice?
I would say a helper because it is accessible from everywhere. It wouldn't be hurtful to place in a block if it's only ever used in that block or it's template, although there is not much reason to create a block just for this when a helper will do.
A model should only be used to model things. As a rule of thumb I only use models for objects that might be used in a data structure, not as a convenience holder for functions.
Template should (whenever possible) get everything from block to keep it simple and little clogged... In the block you might call the helper for getting the config value if you think that will enhance reuse ability.

Validate a Collection Has at Least One Item using Validation Application Block

Using the Enterprise Library 4.1 Validation Application Block, how can I validate that a collection property contains at least one item?
I'm assuming you mean out of the box. If so, then I don't think there is way to validate directly the number of items in a collection.
These are some other ways that you could try:
Decree that you only deal with null collections and not empty collections and use a Not Null Validator. Not practical, though.
Use self validation and have the object validate in code that the collection(s) have the correct number of items. Will work but it's nice to have the validation in the configuration file.
Expose the collection count as a property. This could be done, assuming an employee collection for example, with an EmployeeCount property on your object that contains the collection or you could create your own custom collections that expose a count property. Then you could use a Range Validator to validate on the Count property.
Create a custom validator that can validate the number of items in a collection -- something like CollectionCountRangeValidator.
If I wanted to develop something quickly, I would probably go with option 3. However, option 4 fits in well with the Enterprise Library approach and also allows your class design to be independent of the validation requirements. Plus you could always reuse it on your next project. :) And does anyone really miss creating their own collections when a List will do nicely?
This is already implemented in the EntLib Contrib.
This is called CollectionCountValidator.

Resources