Error when creating page from external app
Permalink
Hello everyone.
I'm currently working on a script that will allow me to create a new page in C5 from an external app, but I'm running into a bit of a snag. I've been looking at the following forum posts:
http://www.concrete5.org/community/forums/customizing_c5/page-impor...
http://www.concrete5.org/developers/bugs/5-4-2-1/c5_integration-wit...
http://stackoverflow.com/questions/15041252/bootstrapping-c5-from-a...
This has given me a good start, but I'm getting the following error
include(Concrete5_Helper_File.php): failed to open stream: No such file or directory
Here is my code:
The error is getting thrown at the include statement, and the stack trace shows it's occurring inside concrete/helpers/file.php when it extends the Concrete5_Helper_File. I'm thinking this is happening because of where the script is being called from. Since the require statements inside dispatcher.php are getting added, but the extends statement is not, I'm thinking it could be a file-path issue, but I'm not sure. My file structure is as follows:
Root
->externalApp
--->script
->c5
--->index.php
Any help that can be given would be greatly appreciated, thanks!!
I'm currently working on a script that will allow me to create a new page in C5 from an external app, but I'm running into a bit of a snag. I've been looking at the following forum posts:
http://www.concrete5.org/community/forums/customizing_c5/page-impor...
http://www.concrete5.org/developers/bugs/5-4-2-1/c5_integration-wit...
http://stackoverflow.com/questions/15041252/bootstrapping-c5-from-a...
This has given me a good start, but I'm getting the following error
include(Concrete5_Helper_File.php): failed to open stream: No such file or directory
Here is my code:
define('C5_ENVIRONMENT_ONLY', true); include (realpath(__DIR__ .'/../../c5/index.php')); Loader::model('collection_types'); return "start"; $pr = Page::getByPath('/dashboard/test_page'); $data = array(); $data['cName'] = "New page"; $data['cDescription'] = "New page"; $data['cDatePublic'] = date_create(); $ct = CollectionType::getByHandle('right_sidebar'); $id = $pr->add($ct, $data); return $id;
The error is getting thrown at the include statement, and the stack trace shows it's occurring inside concrete/helpers/file.php when it extends the Concrete5_Helper_File. I'm thinking this is happening because of where the script is being called from. Since the require statements inside dispatcher.php are getting added, but the extends statement is not, I'm thinking it could be a file-path issue, but I'm not sure. My file structure is as follows:
Root
->externalApp
--->script
->c5
--->index.php
Any help that can be given would be greatly appreciated, thanks!!
You could place the script in library and use the library from a tool file. That way you won't need any includes or such, just the Loader::library and some wrapping code in the tool. The c5 environment only stuff is then already handled for you.
Hi JohntheFish,
Thanks for the reply! I'm currently trying to load C5 from an external app to give me access to its API, so I've been putting this code in a controller in my external app (I'm using Yii to be specific). Do you mean I should write a script, and load it in the libraries folder inside of C5? Would I then load this script from my external app instead of going through dispatcher.php? Thank you for your help, and clarification, I really appreciate it.
Thanks for the reply! I'm currently trying to load C5 from an external app to give me access to its API, so I've been putting this code in a controller in my external app (I'm using Yii to be specific). Do you mean I should write a script, and load it in the libraries folder inside of C5? Would I then load this script from my external app instead of going through dispatcher.php? Thank you for your help, and clarification, I really appreciate it.
What I mean is the best context within which to run
such code is within a tool.
Putting the bulk of it in a library is just a convenient way of structuring it.
So external stuff calls a tool URL with whatever get/put parameters.
The tool code validates its caller, loads the library, and calls a method in the library class where your code really does its stuff.
The dispatcher is still involved in setting up c5 for the tool, but only in an environment only way. However, because tools take care of that, you don't need to.
such code is within a tool.
Putting the bulk of it in a library is just a convenient way of structuring it.
So external stuff calls a tool URL with whatever get/put parameters.
The tool code validates its caller, loads the library, and calls a method in the library class where your code really does its stuff.
The dispatcher is still involved in setting up c5 for the tool, but only in an environment only way. However, because tools take care of that, you don't need to.
So you mean call the library inside of C5 through a PUT/POST/GET request from my Yii app instead of trying to load everything by including Dispatcher.php, right? I'll give that a shot this week and report back with the results, thanks.
Ok, so here is the POST request I've setup to call my tool, located inside of "root/tools"
I have an echo statement inside of the tool that I should see once it receives the POST, but all I'm getting back is "Access Denied." Is there some permissions I need to setup somewhere to allow for external http requests? Thanks again for the help JohntheFish.
$url = "http://localhost/~hugmungus/Yii/concrete/tools/tool.php"; $myvars = 'myvar1=' . 'one' . '&myvar2=' . 'two'; $ch = curl_init( $url ); curl_setopt( $ch, CURLOPT_POST, 1); curl_setopt( $ch, CURLOPT_POSTFIELDS, $myvars); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt( $ch, CURLOPT_HEADER, 0); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec( $ch ); print_r($response);die();
I have an echo statement inside of the tool that I should see once it receives the POST, but all I'm getting back is "Access Denied." Is there some permissions I need to setup somewhere to allow for external http requests? Thanks again for the help JohntheFish.
Ok, finally got it working. This issue I was having was I had the standard "defined('C5_EXECUTE') or die("Access Denied.");" at the top of my tool file(duh).
Now I just need to work on my calls, and doing the second part of what Mr. theFish recommended.
"The tool code validates its caller, loads the library, and calls a method in the library class where your code really does its stuff."
Thanks again!
Now I just need to work on my calls, and doing the second part of what Mr. theFish recommended.
"The tool code validates its caller, loads the library, and calls a method in the library class where your code really does its stuff."
Thanks again!
I might have been a bit premature on accepting the answer. I can post into the tool, but I don't think it's loading Concrete5 with it (hence the Access Denied return value on the defined('C5_EXECUTE') or die statement). I'm trying to use the Loader class to load my library but I'm getting the following error:
Class 'Loader' not found.
Class 'Loader' not found.
I am not sure if pretty urls work with tools, so you had best call the tool through the usual dispatcher.
yoursite/index.php/tools/toolname.php
As a test that the tool is loading and running, just try a tool with a dump of $_REQUEST.
Another catch with tools is they need to end with an "exit;" or the script will return to the dispatcher and try to render a page.
For example:
yoursite/index.php/tools/toolname.php
As a test that the tool is loading and running, just try a tool with a dump of $_REQUEST.
Another catch with tools is they need to end with an "exit;" or the script will return to the dispatcher and try to render a page.
For example:
Hmm, I don't seem to be getting anything back data-wise, though my response is a 200. I changed the url to:
and I no longer get the Access Denied Response. Even when I simply try and echo back a hard-coded string, I still have a result of null.
http://localhost/~hugmungus/Yii/concrete/index.php/tools/tool.php
and I no longer get the Access Denied Response. Even when I simply try and echo back a hard-coded string, I still have a result of null.
After some further investigating, it looks like it's trying to access the script in the wrong tools folder. I setup a couple of echo statements inside of the class root/concrete/startup/tools.php, and here's where it's looking
/Users/Hugmungus/Sites/Yii/concrete/concrete/tools/tool.php
which is the core scripts folder. I've put my script at
/Users/joe119911/Sites/SF2/concrete/tools/tool.php
If I move my script file into the core tools file at root/concrete/tools, it works. Should I move it down into the core Tools folder? or is there a way to have it look inside of the other tool folder too?
/Users/Hugmungus/Sites/Yii/concrete/concrete/tools/tool.php
which is the core scripts folder. I've put my script at
/Users/joe119911/Sites/SF2/concrete/tools/tool.php
If I move my script file into the core tools file at root/concrete/tools, it works. Should I move it down into the core Tools folder? or is there a way to have it look inside of the other tool folder too?
Please describe your directory structure in more detail. What you have above makes no sense to me.
Sorry for the confusion.
I'm testing this on a localhost server on my Mac, so my root directory is located at:
Going there brings up the Yii index.php. Inside of that webroot is the C5 webroot, so to access C5's index.php, I go to:
I have my tool file inside of the top level tools directory in C5, so
But when I use this url:
It goes looking for tools inside the core tools folder, ie
If I move my script there, it works, but I feel like it should be checking the top-level folder too. Instead, I'm just getting a 404 when it looks inside of the core tools folder. Is it because I have two directories named concrete? should I name the top level one something else?
Let me know if you need anymore clarification. Thanks for your help and patience!
I'm testing this on a localhost server on my Mac, so my root directory is located at:
http://localhost/~hugmungus/Yii
Going there brings up the Yii index.php. Inside of that webroot is the C5 webroot, so to access C5's index.php, I go to:
http://localhost/~hugmungus/Yii/concrete
I have my tool file inside of the top level tools directory in C5, so
users/~hugmungus/Yii/concrete/tools
But when I use this url:
http://localhost/~hugmungus/Yii/concrete/index.php/tools/tool.php
It goes looking for tools inside the core tools folder, ie
users/~hugmungus/Yii/concrete/concrete/tools
If I move my script there, it works, but I feel like it should be checking the top-level folder too. Instead, I'm just getting a 404 when it looks inside of the core tools folder. Is it because I have two directories named concrete? should I name the top level one something else?
Let me know if you need anymore clarification. Thanks for your help and patience!
All clear now. For any tool name the core searches a list of locations. Where you have the tool in the siteroot tools folder should take priority over all others.
The dispatcher works by pattern matching in the path and then looking for files that match that pattern, so too many 'concrete' s in the path may be confusing it. Calling it tool.php could also be throwing it for the same sort of reasons. So trying a different path and name is a good next step.
The dispatcher works by pattern matching in the path and then looking for files that match that pattern, so too many 'concrete' s in the path may be confusing it. Calling it tool.php could also be throwing it for the same sort of reasons. So trying a different path and name is a good next step.
Ok, renamed my top-level concrete folder to c5 and my tool.php file to spam.php. Now I'm calling the url
It's still not finding the tool file unfortunately. I looked at my print statements inside of concrete/startup/tools.php, and it's still looking inside:
When it can't find it, it gives up. It builds the search path with this line(11):
When I do a print_r on $r, it's the root tools url. DIRNAME_TOOLS is "tools", so it should pull up both directories right? I also noticed that for case "CONCRETE_TOOL"(switch statement inside of concrete/startup/tools.php lines 8-26) there is no code written, and instead it just runs the "TOOL" case (which is the custom directory). Does this sound like a bug? or am I just seeing it since I don't understand the whole process?
Anyway, thank you for your help. I'd like to keep this as clean as possible, but I do have a workaround to keep me occupied in the meantime.
http://localhost/~hugmungus/yii/c5/index.php/tools/spam.php
It's still not finding the tool file unfortunately. I looked at my print statements inside of concrete/startup/tools.php, and it's still looking inside:
users/hugmungus/yii/c5/concrete/tools/spam.php
When it can't find it, it gives up. It builds the search path with this line(11):
$r = $env->getPath(DIRNAME_TOOLS . '/' . $co->getFilename());
When I do a print_r on $r, it's the root tools url. DIRNAME_TOOLS is "tools", so it should pull up both directories right? I also noticed that for case "CONCRETE_TOOL"(switch statement inside of concrete/startup/tools.php lines 8-26) there is no code written, and instead it just runs the "TOOL" case (which is the custom directory). Does this sound like a bug? or am I just seeing it since I don't understand the whole process?
Anyway, thank you for your help. I'd like to keep this as clean as possible, but I do have a workaround to keep me occupied in the meantime.
I use tools in packages a lot and the dispatcher has no trouble finding them. So if you want to keep trying, you experiment with putting the tool in a small tool-only package.
An example of a tool in a package (for ajax, but that makes no difference) can be found in the ajax lessons howto & addon example.
You could see if that works on your dev system. That will tell you if there is anything about your c5 setup preventing it from working.
An example of a tool in a package (for ajax, but that makes no difference) can be found in the ajax lessons howto & addon example.
You could see if that works on your dev system. That will tell you if there is anything about your c5 setup preventing it from working.
Hello,
There are a lot of useful replies on here addressing the OP's problem, but I think there is a lot of misunderstanding about what the OP wants.
After scratching my head for about five minutes, I've thought of an "out of the box" solution which will set you in the right direction. I haven't tested this as it's a bit involved.
OP, and to everyone else, what the OP wants is to be able to access his tools scripts from an external website without compromising on security.
Firstly, there is a script to access the right tools file. I think this part's done. The part which isn't done is getting past that dreaded C5_ENVIRONMENT_ONLY barricade which is only possible if you're logged in.
Do this. Make sure you're logged out of your C5 site and go to the base page of your website. Then go to the login page which is usually likewww.www.sitename.co.uk/index.php/login/....
Next, go to the source code of the username, password and "Sign in" button. Find the part that says "<form method="post" action="/index.php/login/do_login/" class="form-horizontal">". Use this information so you can login using Ajax from your external site and then run the PHP file straight after you've logged in remotely.
Hope this helps.
There are a lot of useful replies on here addressing the OP's problem, but I think there is a lot of misunderstanding about what the OP wants.
After scratching my head for about five minutes, I've thought of an "out of the box" solution which will set you in the right direction. I haven't tested this as it's a bit involved.
OP, and to everyone else, what the OP wants is to be able to access his tools scripts from an external website without compromising on security.
Firstly, there is a script to access the right tools file. I think this part's done. The part which isn't done is getting past that dreaded C5_ENVIRONMENT_ONLY barricade which is only possible if you're logged in.
Do this. Make sure you're logged out of your C5 site and go to the base page of your website. Then go to the login page which is usually likewww.www.sitename.co.uk/index.php/login/....
Next, go to the source code of the username, password and "Sign in" button. Find the part that says "<form method="post" action="/index.php/login/do_login/" class="form-horizontal">". Use this information so you can login using Ajax from your external site and then run the PHP file straight after you've logged in remotely.
Hope this helps.
User permission is a very good point when calling a tool externally and may also be part of the specific tool issue I was helping with.
Did anyone manage to get this working? I am also looking to work on a mobile app where I can add pages. Is this possible? Any help in this regard would be highly appreciated.
Thanks!
Thanks!
I'm not really sure on what the helper file does, or if I need it. If anyone has any ideas, I could really use the help!