How to creating ACOs? - cakephp

I think I have undestood the bases of almost everything in CakePHP until the Access Control Lists, now I'm on 11.2.5 Creating ACOs (Access Control Objects) and I don't understand where I have to put the AclComponent methods:
$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'controllers'));
$this->Acl->Aco->save();
In which file I should insert this code?
Have I to inserti in some specific statement?
I don't undestand what this line does exactly, so I can't locate where and when it should run, what this code does, and when It should work?

The idea with the ACO records creation is that if your project is over (meaning no new actions are created), you don't need to insert anything anymore in the acos datatable. These methods are intended to be called once, or only a few times.
It is then up to you to decide where you want to place these lines of code, as anyway you will probably remove them afterwards.
Alternatively, to fill the acos datatable, you could also use this plugin http://www.alaxos.net/blaxos/pages/view/plugin_acl that automatically detects new actions and propose to complete the acos datatable accordingly.

you can insert that wherever you need to create Aco-s. in app_controller, or in any controller.

This page in the Cookbook gives you a very nice automated tool for creating ACOs:
http://book.cakephp.org/view/647/An-Automated-tool-for-creating-ACOs
If you add the build_acl function to the AppController, you can run it from any controller and it generates your ACOs for you. It's always worked very nicely in my ACL-using applications.

Related

How to force two instance of the same app (DNN/2sxc) to read from the same stream?

Sorry if my question is silly but I'm new to DNN/2sxc, I've spent the whole day trying to figure this with no success..
I have two instances of the same app, one in the home page and the other on its own page, each one must have its own view template (I use Razor).
My problem is I cannot figure a way to make the two apps read the same data, so every add/edit/remove/re-sort in one of them will be reflected to the other, currently each app has its own data and therefore they are unusable in my case.
I've tried to use a 'EntityTypeFilter' inside a 'Data Query' and use it in both views (as in the News-Simple demo video), it worked and gave me all the items in the two views, but another two problems come with this solution:
1- now I'm unable to use the toolbar to (add/remove/reorder,.. etc) any of the items , as you can see in this image, which is a show-stopper for me,
note: this is the toolbar I use:
#foreach(var item in AsDynamic(Data["Default"]))
{
...
#Edit.Toolbar(target: item, actions: "new,edit,replace,remove,moveup,movedown,instance-list")
2- the 'Content Demo Item' is also visible in the list, but it is not that important since I can delete it and use one of the real data items as a demo item.
I appreciate any kind of help.
Thank you.
So the first thing you should know is the difference when using content-items as data (to query, etc.) and when using it as assigned-items (where each module-instance has a subset of items). Here's the blog that should help you understand the difference: http://2sxc.org/en/blog/post/12-differences-when-templating-data-instead-of-content
So when you want the "manually and easily control the exact items displayed, their ordering etc." you want to use the "content-assigned-to-instance" which also gives you the simple add, delete buttons, as these don't really delete anything, but just remove the assignment from the module-instance.
Now your case is a bit special, in that you want to re-use the exact same set in another module-instance. There are a few ways you can do this:
Same View
if it's exactly the same view etc. just duplicate the module using DNN-features (the add-existing-module-to-another page)
different view
if it's a different view (maybe more compact, etc.) you again have multiple options. The first is to mirror / duplicate using the dnn-feature, and just put an if-im-on-this-page-then-show-differently or inject another CSS. That's probably the easiest without any dev-know-how.
The harder, but possibly nicer way, is to actually to use a new template, and tell it to retrieve the items in the way they are configured in the other module - let's say module 1 is the original, module 2 has a different template wanting to access the items of module 1 in exactly the same order as given in 1. They way to do this is simple, but requires a few lines of C# code in Module 2.
You need to create a new ModuleDataSource (https://2sxc.org/en/Docs/Feature/feature/4542) object and tell it that it's from Module 1. If you've never done this, it's basically that your code can create a query just like the visual designer, but you have more control - see the wiki https://github.com/2sic/2sxc/wiki/DotNet-DataSources-All. The Module-Data-Source in the visual-query-designer doesn't allow you to "switch" modules (a advanced setting we may add in the future) but the object has a ModuleId property which you can set before accessing the data, making it "switch" to that Module. here's the Pseudo code in your Module#2 razor...
var otherModData = CreateSource<ModuleDataSource>();
otherModData.ModuleId = 1;
foreach(var itm in AsDynamic(otherModData["Default"])) {
...
}
That should do it :)

How to pass var from controller into a different view with Cakephp

I am new to Cakephp and indeed OOP, so forgive me if i haven't fully grasped the MVC concept yet. I have search a lot but cannot find an answer - perhaps my way of working below is not correct. I hope you can help.
I am building a site which will have many elements relating to their tables and data. I intend to use a view to pick and choose the relevant elements and any parameters needed.
For example, the homepage of my site will have two elements - a latestusers element and a latestscores element. I am trying to use a view not related to either the users or scores models/controllers, stored in 'other/index.ctp'.
I have tried using set() to pass a variable from the users controller (latestusers action) into the other/index.ctp view, but the viewVars remain empty. Could this be due to scope of the variable (i think it is fine for a view in the users folder, i.e. a view specific to the users controller).
I could achieve what i want to do by using global variables, but i think this is missing the point of MVC/OOP. Would be grateful for any suggestions.
I can include code if need be - it is fairly basic at this stage - but i feel my problem lies with how i am going about things, not the code itself.
Cheers,
James
Yes, the issue is with the scope. If you're going to use variables in the element you'll need to pass them in from your view. So the flow would look something like this
Controller $this->set()s the variable into your current view/layout
Your view/layout calls $this->element with the current element path.
Your element uses those variables.
In number 2 you need to pass your variables as an array of data. This section on the cookbook gives more information : http://book.cakephp.org/view/1081/Elements
<?php echo$this->element('helpbox',
array("helptext" => "Oh, this text is very helpful."));?>
Note - I didn't understand part of the question. Just want to make sure you are passing data to the correct view. You should not be calling the view of another controller in your active controller.
Your other/index.ctp should be an element and that element should be called from your layout.

Count number of posts in cakephp

I'm trying to create a menu in cake php where I can also know how many articles are inside the section, should I use a manual query, or does exist some existing method to do it?
My site menu:
- Works (12)
- Photos (35)
- Stuff (7)
- Contacts
My problem is also I didn't get how I can access to data like this for every view, this should be a main menu, so I should use this in every view but If i put it in default.ctp, every model deosn't exist, because I cannot access it from a view.
Does exist some page which talks about this?
Since those are separate models that are not related to each other, you'll need to do a manual count.
$this->Model->find('count');
EDIT
Ok, so looks like you are talking about different models.
If this is used in a menu, that means it will be shown in all pages.
You have two ways of doing this.
You can do it by having an AppController for you application. Basically, you can put this code in the beforeRender method so it runs everytime your a request is rendered
function beforeRender() {
App::import('Model', array('Work', 'Photo', 'Stuff'));
$work = new Work();
$workCount = $work->find('count');
//do the same for the other
$this->set('workCount', $workCount);
}
Have a look at this for more details on callbacks : http://book.cakephp.org/view/977/Controller-Methods#Callbacks-984
Secondly, you can do this via a helper. You can put the same code (that is inside the bforeRender) into a helper, and you can call the helper method.
You can look here for more info on creating a helper : http://book.cakephp.org/view/1097/Creating-Helpers
The CounterCache behavior will help you out:
http://book.cakephp.org/view/1033/counterCache-Cache-your-count

Can not Bake table model, controller and view

I developed small CakePHP application, and now I want to add one more table (in fact, model/controller/view) into system, named notes. I had already created a table of course.
But when I run command cake bake model, I do not get table Notes on the list. I can add it manually, but after that I get some errors when running cake bake controller and cake bake view.
Can you give me some clue why I have those problems, and how to add that new model?
I would also check your app/config/database.php to ensure that you are using the correct database configuration. You may well have added the table to a different database perhaps and the bake is picking up the other database. Also, and this may be obvious, but check you are in the right project, it's easy to be in a different folder and not realise, especially if you have lots of projects.
I'm not aware of a limit on the bake listing. I would check your database to make sure the table exists and has some columns. You can always open up the console bake script and check for a limit and increase it if needs be.
I found solution!
I had to delete all from cache directory, /app/tmp/cache/models
Now it works!
:-)
When you say added it manually, do you mean added the note.php model? If not, you may want to try that. Verify that the model name is correct for the following:
file name: note.php
class name: class Note extends AppModel
table name: notes
Also, be sure the notes table has the id column and it is set to primary key.
If this does not push you in the right direction, please post your notes table schema here. Also, have you had success in baking other things in your app? Have you upgraded anything?
Please change the following farameters to bake:
For Controller:
/cake/console/libs/tasks/controller.php
function listAll($useDbConfig = 'default') {
change to :
function listAll($useDbConfig = 'YOUR DB CONFIG NAME') {
NOW DO CAKE BAKE for CONTROLLER! ENJOY!

CakePHP: Passing $this->data to the View from Controller

I'm using CakePHP 1.2 and I'm just wondering if there is any side affect on passing the $this->data to the View from the Controller.
Ex:
// inside PostsController, I have this code:
$this->data['Posts'] = $this->Post->find('all');
instead of :
$posts = $this->Post->find('all');
$this->set(compact('posts'));
// inside the /posts/view, I access it like this:
<?php foreach ($this->data['Posts'] as $post) {....};?>
By doing this, I skipped the $this->set() from the controller all together. Does this violate any MVC pattern or any security issue that I might have overlook? I saw that using the Auth Component, $this->data contains the [_Token] array.
Thanks
You need to be aware of the different places that Cake Helpers automagically look for data, since that is were it makes a real difference. The Form Helper will fill in fields automatically based on the contents of $this->data. That's how form data persists when validation fails. OTOH, a <select> elements options array is automatically taken from the pluralized field name,
e.g. $form->select('Model.foo_id') will take its options from $foos if set.
As such, $this->data has its special place and shouldn't be used lightly, just as named variables have their use and shouldn't be ignored. Use both as appropriate. If you don't want to auto-set Form Helper content, set() your variables. IMHO it's also more readable to assign a variable name that hints at the data it contains. All your views operating on $this->data is less clear than one view operating on $foo and another on $bar.
In CakePHP 2.x you should use $this->request->data instead if plain $this->data, otherwise you might end up getting this error:
Indirect modification of overloaded property View::$data has no effect
$controller->data is meant for data posted to the control from view file.
$view->data is for general data.
I would avoid doing it to keep myself sane. besides you are typing more in view.
There is no good reason for setting $this->data directly except when working with forms.
Why break convention - Controller:set is there for a reason. If you want to pass data to the view for display or display logic purposes you should use the function provided instead of trying to co-opt Controller:data for unintended purposes.
Everything is easier from within CakePHP if you follow the rules and do things the expected, correct way.
In cakephp version 2.*, error occurs when you try to set data on $this->data

Resources