Bonjour,
J'aimerais pouvoir faire une API pour communiquer avec mon application cake. L'application elle même ne gérera qu'une partie du back office du site, le reste étant géré par des CMS classique, wordpress, drupal ou consort.
Je voudrais donc faire un fichier de librairie accessible aux intégrateurs, pour interagir avec mon application (lecture de donnée principalement).
Il faudrait donc que depuis un fichier externe à l'application je puisse charger des modèles de l'application, et forcément si je ne fais qu'un include de mon modèle, il ne trouve pas AppModel, puis App. Existe t il un fichier dans cake à charger pour que ça initialise le tout, et donc que je puisse inclure mes modèles tranquillement par la suite.
Pas sur d'être bien clair donc un exemple sera peut être plus clair, mon application va gérer des médias, l'intégrateur veut la liste de tout les médias, je ne veux qu'il n'est à saisir que :
include('***/lib.php');
$medias = getMedias();
A moi de faire en sorte que le fichier lib.php puisse charger le modele Media puis lance une de ces fonctions.
Je voyais un code de ce genre :
include ('***/app/Model/Photo.php');
function getMedias() {
$model = new Media();
return $model->someFunction();
}
Comment faire en sorte d'avoir ce fonctionnement?
Je suis reparti de ce qu'il y avait dans l'index du webroot, j'ai donc ajouté le code suivant à mon fichier lib.php :
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
if (!defined('ROOT')) {
define('ROOT', ' ***** /app');
}
if (!defined('APP_DIR')) {
define('APP_DIR','');
}
if (!defined('WEBROOT_DIR')) {
define('WEBROOT_DIR', basename(dirname( __FILE__ )));
}
if (!defined('WWW_ROOT')) {
define('WWW_ROOT', dirname( __FILE__ ) . DS);
}
define('CAKE_CORE_INCLUDE_PATH', ' **** /cake/lib');
include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php';
include_once(' **** /Model/Photo.php');
il y a des ***** parce qu'il s'agit de lien perso sur mon serveur.., mais les liens sont bien OK
Le souci c'est que même en faisant appel à un model, je me prends la fenetre de connexion (redirection vers /users/login)
des idées pour avancer??
J'ai également essayer de remplacer le include par
App::uses('Photo', 'Model');
mais sans succès...
Ce serait stupide d'aller directement chercher les infos dans la base de donnée quand même...
Je ne sais pas si tu as deja regardé de ce coté la, ou si ca a un rapport avec ta demande, mais voici un lien qui pourrait peut etre t'aider
En effet REST semble correspondre à ma demande.
Pour redéfinir les actions, ça n'a pas l'air de fonctionner :(
Router::mapResources('photos');
Router::parseExtensions();
Router::resourceMap(array(
array('action' => 'rlist', 'method' => 'GET', 'id' => false),
array('action' => 'rview', 'method' => 'GET', 'id' => true)
));
et la réponse à "***/photos/1.xml" me retourne
<response>
<code>404</code>
<url>/admin_photo/photos/1.xml</url>
<name>Action PhotosController::view() could not be found.</name>
</response>
Alors que d'après ma config la fonction appelée devrait être rview et non view. où ai je loupés quelque chose?
La je ne pourrias pas vraiment t aider, j ai jamais utilisé REST.
Par contre a la fin de la page, il y a Routing REST Personnalisé. Peut etre que cela pourra t aider
Je me suis inspiré de la partie juste avant "Modifier les routes REST par défaut".
En tout cas merci mikachu.
Si quelqu'un d'autre à une idée de pourquoi il ne veut pas me prendre la bonne fonction.
De rien, mais a tout a hasard, as tu tenté de renommer rview en view pour faire un test,afin de voir si ca fonctionne ?
si je la renomme ça fonctionne, puisque "view" est la fonction par défaut, donc c'est sûr ce serait une solution pour que ça marche, mais j'aimerais comprendre pourquoi ça ne fonctionne pas en changeant le nom de la fonction, et dans mon cas le "view" est déja utilisé pour le fonctionnement classique hors REST.
Si vraiment ça ne voulait pas je ferais un controleur exclusivement pour le REST ce qui me permettrait d'utiliser les noms des fonctions par défaut :/
Si quelqu'un d'autre à une idée de pourquoi il ne veut pas me prendre la bonne fonction.
A mon avis c'est le problème du principe de Conventions over Configuration de CakePHP. Ils ont définis les actions de base comme étant index(), view(), ... . Du coup ça bloque car tu la nommes différemment.
Il faut utiliser Router::connect dans ton cas.
EDIT : fonctionnement classique hors REST. Faux, lorsque tu fais une requête HTTP via un navigateur ou via une application, il s'agit d'une requête REST.
pourtant d'après la page d'aide sur REST la fonction resourceMap permet de modifier les valeurs par défaut.
Dans ce cas on a par défaut :
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
array('action' => 'update', 'method' => 'POST', 'id' => true)
Si l'on veut par exemple ajouter une fonction en DELETE sans "id", ce n'est pas possible, ce serait bizzare..
le fonctionnement magique de cake est bien car rapide, mais dès que l'on veut sortir un peu des clous on est mort.. :(
Oui je n'ai pas tout saisi en lisant la doc. Il faut essayer de voir où le fonctionnement magique de Cake (comme tu dis :) ) est vraiment utile et nous fait gagner du temps et où il vaut mieux le faire manuellement afin d'avoir une marge de manoeuvre plus importante. J'ai remarqué que pas mal de gens sur le forum se bloquent à cause de ça, ils veulent à tout prix utiliser les briques de Cake pour éviter de coder.
Disons que dans un framework la logique est d'utiliser ce qui existe, sans réinventer la roue... Il est aussi intéressant de savoir comment fonctionne la magie pour mieux connaître ces limites.
La dans mon cas j'ai refais un contrôleur spécifique pour REST donc je peut réutiliser les noms de fonctions par défaut, mais bon je serais tout de même intéressé, pour savoir comment modifier ou ajouter de nouvelle fonction.
Sinon je finirais par le faire à l'ancienne, utilisé une seule fonction "index" et jouer avec des paramètres envoyés dans le $_POST.
@prbaron
J'ai remarqué que pas mal de gens sur le forum se bloquent à cause de ça, ils veulent à tout prix utiliser les briques de Cake pour éviter de coder.
C'est étrange ce que tu dis.
Si nous utilisons un Framework, c'est pour s'en servir que je sache.
Les librairies, les utilitaires et autres ensembles de fonctions sont fait pour être utilisés, sinon autant ne pas se servir du Framework, sinon autant coder toutes nos propres fonctions sans se servir du Framework.
Les librairies et compagnies de CakePHP, ce n'est pas présent juste pour faire joli.
C'est comme si tu disais que les librairies javascript telles que jQuery par exemple, que ça ne sert à rien, qu'il ne faut pas les utiliser et uniquement coder en javascript basique.
Utiliser quelque chose qui est à notre disposition, ne veut pas dire éviter de coder, surtout concernant CakePHP.
Il semblerait que je me soit mal exprimé.
CakePHP est un bon framework, mais il s'agit d'un framework Conventions over Configuration. Si on suit les conventions de CakePHP, cela permet de gagner un temps précieux car tout est fait par le framework. La contrepartie c'est que lorsque l'on s'éloigne des conventions, on se retrouve "emprisonné", c'est tout de suite plus compliqué.
Je ne dis pas que les frameworks ne servent à rien, au contraire, je suis un fervent défenseur des frameworks. Il faut juste faire attention à jusqu'où il faut les utiliser. Il est parfois plus intéressant d'utiliser des fonctions plus bas niveau du framework. Comme ici. Je suppose que resourceMap() est du sucre pour les fonctions Router::connect(). Comme @blibsnake ne suit pas les conventions de CakePHP, je pense qu'il vaut mieux utiliser directement Router::connect() qui est plus bas niveau, et qui certes, ne réaliseront pas tout automatiquement comme resourceMap() mais qui lui autorisera une plus grande marge de manoeuvre.
HS : c'est la même chose pour jQuery, il est très utile car il permet d'ajouter une couche d'abstraction à JS, mais il faut quand même faire attention aux performances et ne pas perdre de vue que jQuery est du sucre pour JS, et que tout ce qui est réalisable par jQuery peut être fait par JS (ex : http://www.sitepoint.com/jquery-vs-raw-javascript-1-dom-forms/).
Je reviens vers vous... j'étais passé sur un autre projet entre temps :)
J'utilise du json, donc mes appels auront l'extension ".json", je ne sais pas si ça a une incidence ou pas.. comment puis je envoyé des données à l'appel.
J'ai essayé avant l'appel, d'ajouté des données dans le tableau $_POST mais celui ci est vide dans le contrôleur. ça fonctionne très bien en ajoutant des paramètres à l'url donc via le GET.
J'ai l'impression que ce que je veut c'est la base, qu'est ce que j'ai loupé?
comment puis je envoyé des données à l'appel.
Des données à l'appel de quoi ?
J'ai essayé avant l'appel, d'ajouté des données dans le tableau $_POST mais celui ci est vide dans le contrôleur. ça fonctionne très bien en ajoutant des paramètres à l'url donc via le GET.
Ce qu'il te faut bien comprendre c'est comment sont écrites les trames HTTP pour voir comment récupérer tes informations.