CakePHP multi-site file system organization with shared functions - cakephp

I have a CakePHP 1.3 mutli-site installation in the server. Each site has its own folder, and they all load the CakePHP core libraries from one same place. This is how it looks like:
[cake] (cake's core libraries)
[sites]
[site 1]
[app]
[plugins]
[vendors]
.htaccess
index.php
[site 2] (also with its own app, plugins and vendors folders)
[site 3] (also with its own app, plugins and vendors folders)
etc
I find myself many times in the situation where I want to implement some functions that I would like to use in all of the apps, but so far I just replicate the code inside each site. I would like to be able to declare those functions in one place and be able to call them from any site. I believe vendors could have something to do with this, but I've been looking in the cookbook and I can't figure out how to use that in my case.
Any help would be much appreciated!
UPATE
So by looking at the vendors, it seems to me (maybe I'm wrong) that it would work in my case if the functions in those vendors files don't need to directly interact with other CakePHP classes (for example Session, Auth, etc). I'll give an example of one of the things I'm trying to do, maybe that helps to understand better what I'm trying.
Each of the sites has its own login system (using cake's Auth). One of the things I want to do is, when a user logs in (the login() function in UsersController is called), have there a function that does some processing with the username of the user, and then calls the Session->flash() function to insert there a message (the message changes depending on that processing the function makes). So this function needs to use the User model and the Session model.
Can I do this using vendors, so I declare this one function (i.e. processLogin()) in a vendor, and all the sites can use that function? If so, how? If not, is there any other way to do this?

Stick them in the vendor folder at the same level of cake and sites, name-spaced under a name of your choice (usually the agency name or other unique identifier).
Examples on loading vendor files in CakePHP 1.3 is explained in the Cookbook here: http://book.cakephp.org/1.3/en/view/943/Loading-Vendor-Files
However, I’d advise upgrading to CakePHP 2, and placing your code in a sub-folder under lib.

Related

2SXC/DNN - Delete ADAM Files in Entity

We're designing a system for a client where they are allowing authenticated users to upload images. We've created an API to upload the files but the client only wants the latest file and delete all previous ones so that there would only ever be one.
We've looked through the docs and can't come across a way for ADAM to handle this in both 2SXC and DNN's file system.
Internally when deleting images we see API calls like the following to the internal 2SXC API, but we're wondering if this is exposed somewhere within the public API?
https://somedomain.com/api/2sxc/app/auto/data/61393528-b401-411f-a001-f423ea46700a/b7d04e2c-c565-496c-8efb-aa133cf90d33/Photo/delete?subfolder=&isFolder=false&id=189&usePortalRoot=false&appId=3
We could probably use the same endpoint above, but we'd likely run into permission issues or changes to the APIs that could be problematic.
Thank you for any advice you can give! Perhaps #iJungleBoy can provide some thoughts on this.
As a solution from a completely different direction, if you are on the later release of 2sxc (v12.8+, v13+), and comfortable programming in C#, you might consider doing this as a "cleanup" from a Dnn Scheduled Task. This can be done with a relatively easy setup. We have a Gist in place that we use as a starter. You simply put the code in the /App_Code folder then setup a normal Dnn Scheduled Task. NOTE that you can scroll down to the first comment on the Gist to see a screenshot of a complete working setup.
Accuraty's AccuTasks template on GitHub Gists
There are two more key things to note:
You need to install Dnn's CodeDom 3.6 because the example uses the later versions C#'s string interpolation - OR remove the few $"ASL2021 - {this.GetType().Name}, Task Scheduled Email", bits or convert to string.Format() or something.
Since your task's code is NOT running in a (2sxc) module, if needed, you'll do stuff like this: 2sxc Docs - Use 2sxc Instance or App Data from External C# Code
So, if you are comfortable writing code that "finds and deletes stuff older than NN days" - this might be the way to go.

Folder structure for multiple models

In my CakePHP 3 application I used different controllers for different parts - like so:
app/src/Controller/Admin/...
app/src/Controller/Backend/...
app/src/Controller/Frontend/...
app/src/Controller/Api/...
All templates follow the same hierarchic structure.
Now, since my application is getting more complex, I would also like to split up all model classes putting them in a similar folder structure.
So how could this be done? How can I tell the controller which table class to use by default?
As Cakephp prefers conventions over configurations ,so if you will just follow the conventions of table,model and controllers then you do not need to worry about these things.here is link to study conventions and here is the cakephp inflector buid by Cakphp team for convention check.I will help you if find some solution for this issue

Share controllers, models and views in multisite CakePHP 2.3 installation

I'm creating a CakePHP 2.3 advanced installation (several apps -websites- that share one same lib folder where all of cake's core files are located). This works without any problems, I just edit the core.php file in the Config folder for each app so it knows where to find cake's files. The file system looks something like:
[root]
[cake-core-files]
[websites]
[website-1]
[app]
[plugins]
[vendors]
[website-2]
...
[website-N]
These different apps are in fact different in some things (they are different websites) but at the same time there's many things that are common to all of them (for example some models, controllers, functions...). What I would like to do, if possible, is to have those apps also share a bunch of controllers, models, etc so I can put them in one place, instead of replicating them now for each app.
I've seen the concept of vendors and plugins in CakePHP (I actually use plugins in those websites, but from the /app/plugins folder), but I'm not sure if that would work in my case, or how I would set that up. I guess the idea would be to have another folder (for example [shared_objects]) at the same level of [cake-core-files] and [websites], but I don't know how I would have to configure cake to do that or how to call those objects from each app.
Any ideas?
EDIT
Based on the comments/responses below I'm trying to do this using the App:build() function in the bootstrap.php, but I can't get it to work. This is what I've done:
Added a new folder where I want to put the stuff to share between all apps:
[root]
[cake-core-files]
[shared-stuff] --> NEW FOLDER
[Model]
[Config]
[websites]
[website-1]
etc...
Placed the model User.php inside the new folder [shared-stuff/Model]
Added this line in the bootstrap:
App::build(array('Model' => array('/path/to/shared-stuff/Model')));
Deleted the model User.php from its original location [website-1/app/Model]
After this steps, it seems to work, the model User.php is loaded correctly from the [shared-stuff] folder (I've tested that printing App::objects('Model');, the User model is listed). However, it actually doesn't work, when I call that model from the UsersController in the login() function, the login doesn't work (although I don't receive any kind of error, even with debug set to 2).
This model uses a database configuration different from the default one (the users table is located in a different database than the default one). I don't know if this matters.
One thing is for sure, if I leave the same exact User.php model in its original location ( [website-1/app/Model]) it all works fine, including the login, so it's a problem with how I try to configure all this sharing stuff, not the model itself.
Any ideas what am I doing wrong?
I think it could be useful to share some controller/model between multiple websites, and do it without a plugin: Using shared controller/model lets you to overwrite it if needed. It should happen simply copying the controller/model in the website's correct folder and the system should use it instead of the shared one!
EDIT: Wonderful, it works, but i think there is a little error in cake's official documentation: All paths should be terminated with a Directory separator! In the cakephp book there aren't trailing slash. Add it to your App::build path and everything will work perfectly!
You can have plugins in the core Plugins/ dir
[root]
[lib]
[Cake]
[Plugins]
[Available]
[To]
[All]
[website-1] // the 'app' dir -> https://github.com/cakephp/cakephp/tree/master/app
[plugins]
[vendors]
[website-2] // you can have many of them named anything, 'app' is just one.
...
[website-N]
This folder specifically will make the plugins available to any app using the cake lib
EG:
Look at this. Copy app to website-1, repeat till website-n.

Using Skue or similar frameworks to build REST API on google-app-engine

Searching for ways to build REST APIs, I found skue (https://code.google.com/p/skue/). However there is not much information on the site. My plan is to build a rest api as follows strictly:
Models << Business logics << Restful Resources.
What this means is: the models are access exclusively by the business logic; the restful resources interface is the only layer a client has direct access to. I am specifying all this to avoid people suggesting using the appengine-rest-server.
My question is: has anyone ever successfully used Skue? If so do you have any examples you would not mind sharing? GET and POST would be sufficient, but more is welcomed. If not Skue, are there any frameworks out there that allow building such rest-apis on top of the google-app-engine?
I'm the author of Skuë. Skuë means "mouse" in Bribrí which is the language of an indigenous group of people of Costa Rica, my Country.
I know there isn't enough information on the site: (https://code.google.com/p/skue/)
For developers that want to use it on their own projects. I'm sorry for that I just haven't had the time to do a proper documentation since this is just a side project and not my daily work.
However, I'm willing to help you out with ramping up so you will be able to use it. The first thing to notice is the small example that it's part of the source code. Go to the site then click on Source -> Browse and then expand the "app" branch.
The code inside of the "app" folder represents your own API implementation. The package "skue" contains the actual implementation of the library so basically you just create your Python project for Google App Engine and includes the skuë package directly into it.
Now overwrite your main.py file with the content of the downloaded main.py: main.py on Skuë project.
The most important part of that file is where you put your own routes to your resources implementations: Notice here the use of the "ContactResource".
TASK_HANDLERS = [
]
API_HANDLERS = [
('/contacts/(.*)', ContactResource)
]
API_DOC = [ ('/', ApiDocumentationResource) ]
Browse to the contact resource implementation.
There are a lot of things going on under the hood there.. but the idea is for you to not worry about those.
You need to inherit from the proper Resource parent class depending on the kind of resource you want to create, there are four basic types:
DocumentResource: A document resource is a singular concept that is akin to an object instance or database record.
CollectionResource: A collection resource is a server-managed directory of resources. Clients may propose new resources to be added to a collection. However, it is up to the collection to choose to create a new resource, or not.
StoreResource: A store is a client-managed resource repository. A store resource lets an API client put resources in, get them back out, and decide when to delete them.
ControllerResource: A controller resource models a procedural concept. Controller resources are like exe- cutable functions, with parameters and return values; inputs and outputs.
Like a traditional web application’s use of HTML forms, a REST API relies on controller resources to perform application-specific actions that cannot be logically mapped to one of the standard methods (create, retrieve, update, and delete, also known as CRUD).
Now take a look at the "describe_resource" implementation on ContactResource example. When you inherit from the basic resource types described above the next step is to programmatically describe your resource to the outside world using that method. The underlying Skuë implementation uses that method to validate require parameters and also to self describe the endpoints when you perform an OPTIONS request on them.
And the final step is for you to implement the methods (CRUD) that you want to handle for your resource.
Again with the ContactResource example, that resource handles the creation, update and read of Contact items.
I hope this helps you at least to understand how to start using the library. I will create better tutorials in the future, though.
In the meantime you can contact me via email: greivin.lopez#gmail.com and I will send you a more elaborated example or even something that matches your requirements.
Important Note: Currently the Skuë project only supports responses in JSON format. If you plan to use another format you will need to create the proper classes to handle it.
Greetings from Costa Rica.
I haven't used skue, but what you're looking for sounds like a good fit for Google Cloud Endpoints. See my previous answers on the subject for more details.

Using App::uses (instead of App::import) in a CakePHP 2.1 Plugin

I'm writing a small application in CakePHP 2.1, and I want to use Nick Baker's file upload plugin. I downloaded the cakephp2.0 branch (I know that isn't done yet), and placed it in my apps Plugin folder. I made some necessary modifications on it, but I'm curious what the right way is to replace those App::import function calls (at start of FileUploadComponent, FileUploadBehavior and FileUploadHelper classes) with the App:uses function.
It needs to import the FileUploadSettings class from Config/file_upload_settings.php and the Uploader class from Vendor/upload.php. It can be done with the require_once function, but I'm sure there is a CakePHP way to do it.
From what I've gathered:
use import() for external libraries
and uses() for framework files
For example:
App::import('Vendor', 'ExternalLibrary');
App::uses('Inflector', 'Cake.Utility');
According to the Cake manual App::import() is comparable to the way require_once() works. From what I understand you would load classes using App:uses() and Vendor files using App:import().
The API documentation says the following on the subject:
All classes that were loaded in the past using App::import(‘Core’, $class) will need to be loaded using App::uses() referring to the correct package. This change has provided large performance gains to the framework.
The method no longer looks for classes recursively, it strictly uses
the values for the paths defined in App::build()
It will not be able to load App::import('Component', 'Component') use App::uses('Component', 'Controller');.
Using App::import('Lib', 'CoreClass'); to load core classes is no longer possible. Importing a non-existent file, supplying a wrong type or package name, or null values for $name and $file parameters will result in a false return value.
App::import('Core', 'CoreClass') is no longer supported, use App::uses() instead and let the class autoloading do the rest.
Loading Vendor files does not look recursively in the vendors folder, it will also not convert the file to underscored anymore as it did in the past.
The migration guide also has some things to say about App:uses() and is a good starting point in general to compare best practices for 2.0 with the older methods from 1.3 and lower.
This related question deals with loading Vendor files in Cake 2.0, I can't verify the claim by José Lorenzo that App:import() is a "silly wrapper" for require_once(), nor the statement that it's the preferred way of including files. The only reference I could find for the latter is in the Coding Standards for Cake contributors, viz. developers contributing to the Cake core, not applications built on the framework.
EDIT
Let's say you want to import the Twitter OAuth library, residing in Vendor/twitter, the main class file is twitteroauth.php in Vendor/twitter/twitteroauth/twitteroauth.php:
App::import('Vendor', 'twitteroauth', array('file' => 'twitter'.DS.'twitteroauth'.DS.'twitteroauth.php'));

Resources