Laravel- displaying partial using different scopes on the same page - laravel

I'm building my first project in laravel and I have an index page where I want to show 4 different lists (they're different categories of the same data, and users will have permissions to see one or more of the lists)
The format for the lists (name, link, image, etc) is identical so I made a partial for it, with the idea that on this index page I'd check the authenticated user and if they have permission for list A then show it, if they have permission for list B then show it, etc.
To try it out, I made a scope for the first category (in my controller), and it shows the right data when I pass it to a totally separate view. But I'm unclear on how/whether I can display the partial multiple times on the index view with a different scope each time. What's the right way to go about this?
I imagined I would do something like check the permissions one at a time, make a variable with just that scope of data, and show the partial for just that data, like:
#include ('partials._items_list') , $category_A)
But the comment here suggests that a view has only one scope of data at a time (so maybe my idea isn't a valid thing):
Laravel - Modify and return variable from #include

You can pass different values with the same partial using something like the following:
#include ('partials._items_list') , ['categoey_A' => $category_A]);
#include ('partials._items_list') , ['categoey_A' => $category_B]); // <-- Different Value
Use only {{ $categoey_A }} in your partials._items_list view but output will be different.

Related

Builder Plugin set identifier value through partial

I am trying to use output data that I have set up using the builder plugin through the Record Details component and running into some issues.
In my created plugin, Schools, I have Instructors (set up as a relation to an instructors plugin I created separately). It is possible to have more than one instructor, so they are store in the database as an array. Like so:
[{"instructor":"69"},{"instructor":"79"},{"instructor":"80"},{"instructor":"96"}]
The numbers represent the row ID of the instructor table
In my CMS I can pull all of the School info just fine into a partial (Builder Details), and can pull the array of instructors, but I am struggling to pass this array over to look up the ID and get the instructors information. My thought right now is to send it to another partial like so:
{% "school/instructor" insProfile = instructorID %}
The partial school/instructor is getting the ID just fine. I have included the Builder Details component and set it up with the following:
Alias: builderDetails
ModelClass: Instructors Plugin
Identifier value: insProfile
Key Column: id
Display Column: member_name
I am getting record not found results. I am confused as to how to set the Identifier Value to match the value I passed through my partial. I tried {% set identifierValue = insProfile %} before the {% set record = ... %} is run, but that did not work either.
I cannot use the :slug because that is already generating the content needed for the School page. In a TLDR, it seems I ultimately want to duplicate this function through another partial and a different tag.
Still learning October, so any help is appreciated.
I think the original post was a bit lengthy and ultimately what I wanted to do was pass a variable into a component. Such as:
{% component 'builderDetails' identifierValue=dynamicVar %}
This does not appear to work as the builder details component generates too far into page load to pick up the variable change.
Per the OctoberCMS docs, the best solution for me was to create my own component that would accept the variable before the page processed using onRender() function.
public function onRender()
{
// This code will be executed before the default component
// markup is rendered on the page or layout.
$this->profileID = $this->property('insProfile');
$this->ins = $this->getUserInfo($this->profileID);
}
This allows me to put my component in a partial, and request the partial with the variable 'insProfile'. The component will pick up the property insProfile before page/plugin generates and use that variable instead of the default.
I then set up another function to query the correct user info needed (getUserInfo)
It would be nice if the builder plugin components could be updated in such a way that I did not have to do this as the builder plugin is rather extensive out of the box.
Posting this in case anyone else comes along this problem and isn't sure where/how to pass a partial variable into a component.

One route for multiple controllers

I'am new to Laravel 5 and have one small problem with routing.
I would like to be able to set one route for multiple controllers.
Lets say I have controlers: one, two, three.
I want to create something like (that is not working of course):
Route::get('{controller}', $controller.'#index')->where('controller', '(one| two|three)+');
So when I will type:
examlpe.com/two
It will call controller two and index method, and it will work in same way for one and three controllers, but not for others (this is why I used 'where' here).
What I am trying to do:
I have to create an app divided to 20 or even more profiles.
Each profile will be used by different users working on different datasets (dataset for group 'one' will be never available for group 'two', etc.).
Each profile will use similiar main functions (about 4-5), but there will be many differences between them (mostly some rules that will have an influence to the function results and dataset presentation).
I can 'extract' core of those functions to the single controller that will be extended by controlers dedicated to each group so then I will be able to adjust functions results to each profile (according to those users needs).
My idea was to have it all separated per profile so then I will have profiles like in example: one, two, three, ...
Then each profile will have slighlty different url so it will be easily recognized, and will contain also dataset id, for ex. (process, view, closed are methods from controller, available for all group, but have some differences as I wrote before):
examlpe.com/two/process/12
examlpe.com/two/view/34
examlpe.com/one/process/66
examlpe.com/three/closed/54
Hope that is clear...

codeigniter extra url segments

I am making a site for a client and decided i would use code igniter.
The site essentially has two backends, one for designers, and one for a sales team. So after logging in, the user will be redirected to either
mysite.com/sales/
mysite.com/design/
The sales team for example can view orders, containers, products, therefore i need a controller for each of these.
mysite.com/sales/orders/
The sales need to be able to view, edit, delete certain orders...
mysite.com/sales/orders/vieworder/235433
Basically my problem is i dont have enough url segments to play with.
My thoughts on solving my problem
removing the orders, containers, products classes and making ALL of their methods as methods of the sales class, although this would mean a large number of methods and loading all models so it seemed kind of pointless.
removing the sales/designer classes and controlling what each kind of user has access to based on a user type stored in session data.
a way of having an extra url segment?
I appreciate any advice, I just dont want to get 3 weeks into the project and realise i started wrong from the beginning!
Use folders.
If you make a subfolder in /application/ called sales you can put different controllers in there:
/application/
/sales/
orders.php /* Controller */
/design/
Then in orders.php you will put your vieworders($id) method and so on, and you will be able to acces it with domain.com/sales/orders/vieworders/id.
You can also make subfolders in the /models/ and /views/ to organize your files.
Now, Access Control is something apart and it depends more in the auth system you are using.
Give the user/designer a privilege, a column in the user table for example, check the permission of the user at the beginning of the function, then prevent or execute it.
This would be the exact way i would do it.
Seems like you should have a look into the routing class. Might be a dirty solution but rerouting the sales/(:any) to something like sales_$1 would mean you'd make controllers with names like sales_orders.
Same for the design part.
(FYI: $routing['sales/(:any)'] = 'sales_$1'; should do the trick; see application/config/routing.php).

CakePHP, organize site structure around groups

So, I'm not quite sure how I should structure this in CakePHP to work correctly in the proper MVC form.
Let's, for argument sake, say I have the following data structure which are related in various ways:
Team
Task
Equipment
This is generally how sites are and is quite easy to structure and make in Cake. For example, I would have the a model, controller and view for each item set.
My problem (and I'm sure countless others have had it and already solved it) is that I have a level above the item sets. So, for example:
Department
Team
Task
Equipment
Department
Team
Task
Equipment
Department
Team
Task
Equipment
In my site, I need the ability for someone to view the site at an individual group level as well as move to view it all together (ie, ignore the groups).
So, I have models, views and controls for Depart, Team, Task and Equipment.
How do I structure my site so that from the Department view, someone can select a Department then move around the site to the different views for Team/Task/Equipment showing only those that belong to that particular Department.
In this same format, is there a way to also move around ignoring the department associations?
Hopefully the following example URLs clarifies anything that was unclear:
// View items while disregarding which group-set record they belong to
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
http://www.example.com/Departments
// View items as if only those associated with the selected group-set record exist
http://www.example.com/Department/HR/Team/action/id
http://www.example.com/Department/HR/Task/action/id
http://www.example.com/Department/HR/Equipment/action/id
Can I get the controllers to function in this manner? Is there someone to read so I can figure this out?
Thanks to those that read all this :)
I think I know what you're trying to do. Correct me if I'm wrong:
I built a project manager for myself in which I wanted the URLs to be more logical, so instead of using something like
http://domain.com/project/milestones/add/MyProjectName I could use
http://domain.com/project/MyProjectName/milestones/add
I added a custom route to the end (!important) of my routes so that it catches anything that's not already a route and treats it as a "variable route".
Router::connect('/project/:project/:controller/:action/*', array(), array('project' => '[a-zA-Z0-9\-]+'));
Whatever route you put means that you can't already (or ever) have a controller by that name, for that reason I consider it a good practice to use a singular word instead of a plural. (I have a Projects Controller, so I use "project" to avoid conflicting with it.)
Now, to access the :project parameter anywhere in my app, I use this function in my AppController:
function __currentProject(){
// Finding the current Project's Info
if(isset($this->params['project'])){
App::import('Model', 'Project');
$projectNames = new Project;
$projectNames->contain();
$projectInfo = $projectNames->find('first', array('conditions' => array('Project.slug' => $this->params['project'])));
$project_id = $projectInfo['Project']['id'];
$this->set('project_name_for_layout', $projectInfo['Project']['name']);
return $project_id;
}
}
And I utilize it in my other controllers:
function overview(){
$this->layout = 'project';
// Getting currentProject id from App Controller
$project_id = parent::__currentProject();
// Finding out what time it is and performing queries based on time.
$nowStamp = time();
$nowDate = date('Y-m-d H:i:s' , $nowStamp);
$twoWeeksFromNow = $nowDate + 1209600;
$lateMilestones = $this->Project->Milestone->find('all', array('conditions'=>array('Milestone.project_id' => $project_id, 'Milestone.complete'=> 0, 'Milestone.duedate <'=> $nowDate)));
$this->set(compact('lateMilestones'));
$currentProject = $this->Project->find('all', array('conditions'=>array('Project.slug' => $this->params['project'])));
$this->set(compact('currentProject'));
}
For your project you can try using a route like this at the end of your routes.php file:
Router::connect('/:groupname/:controller/:action/*', array(), array('groupname' => '[a-zA-Z0-9\-]+'));
// Notice I removed "/project" from the beginning. If you put the :groupname first, as I've done in the last example, then you only have one option for these custom url routes.
Then modify the other code to your needs.
If this is a public site, you may want to consider using named variables. This will allow you to define the group on the URL still, but without additional functionality requirements.
http://example.com/team/group:hr
http://example.com/team/action/group:hr/other:var
It may require custom routes too... but it should do the job.
http://book.cakephp.org/view/541/Named-parameters
http://book.cakephp.org/view/542/Defining-Routes
SESSIONS
Since web is stateless, you will need to use sessions (or cookies). The question you will need to ask yourself is how to reflect the selection (or not) of a specific department. It could be as simple as putting a drop down selection in the upper right that reflects ALL, HR, Sales, etc. When the drop down changes, it will set (or clear) the Group session variable.
As for the functionality in the controllers, you just check for the Session. If it is there, you limit the data by the select group. So you would use the same URLs, but the controller or model would manage how the data gets displayed.
// for all functionality use:
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
You don't change the URL to accommodate for the functionality. That would be like using a different URL for every USER wanting to see their ADDRESS, PHONE NUMBER, or BILLING INFO. Where USER would be the group and ADDRESS, PHONE NUMBER< and BILLING INFO would be the item sets.
WITHOUT SESSIONS
The other option would be to put the Group filter on each page. So for example on Team/index view you would have a group drop down to filter the data. It would accomplish the same thing without having to set and clear session variables.
The conclusion is and the key thing to remember is that the functionality does not change nor does the URLs. The only thing that changes is that you will be working with filtered data sets.
Does that make sense?

Duplicated Zend_Form Element ID in a page with various forms

How do I tell the Zend_Form that I want an element (and it's ID-label, etc) to use another ID value instead of the element's name?
I have several forms in a page. Some of them have repeated names. So as Zend_Form creates elements' IDs using names I end up with multiple elements with the same ID, which makes my (X)HTML document invalid.
What is the best solution to fix this, given that I really have to stick with using the same element names (they are a hash common to all forms and using the Zend_Form Hash Element is really out of question)?
Zend_Form_Element has a method called setAttribs that takes an array. You may be able to do something like $element->setAttribs(array('id' => "some_id"));
or you can do $element->setAttrib('id', 'some_id');
Thanks, Chris Gutierrez.
However, as I said, I needed to get ride of the default decorator generated IDs like -label. Wiht the $element->setAttribs() it is not possible, however.
So based on http://framework.zend.com/issues/browse/ZF-7125 I just did the following:
$element->clearDecorators();
$element->setAttrib('id', 'some_id');
$element->addDecorator("ViewHelper");
Whoever sees this: please note this was enough for what I needed. But may not be for you (the default settings has more than the viewHelper decorator).

Resources