Standalone PHP script using Expression Engine - expressionengine

Is there a way to make a script where I can do stuff like $this->EE->db (i.e. using Expression Engine's classes, for example to access the database), but that can be run in the command line?
I tried searching for it, but the docs don't seem to contain this information (please correct me if I'm wrong). I'm using EE 2.4 (the link above should point to 2.4 docs).

The following article seems to have a possible approach: Bootstrapping EE for CLI Access
Duplicate your index.php file and name it cli.php.
Move the index.php file outside your DOCUMENT_ROOT. Now, technically, this isn’t required, but there’s no reason for prying
eyes to see your hard work so why not protect it.
Inside cli.php update the $system_path on line 26 to point to your system folder.
Inside cli.php update the $routing['controller'] on line 96 to be cli.
Inside cli.php update the APPPATH on line 96 to be $system_path.'cli/'.
Duplicate the system/expressionengine directory and name it system/cli.
Duplicate the cli/controllers/ee.php file and name it cli/controllers/cli.php.
Finally, update the class name in cli/controllers/cli.php to be Cli and remove the methods.
By default EE calls the index method, so add in an index method to do what you need.

#Zenbuman This was useful as a starting point although I would add I had issues with all of my requests going to cli -> index, whereas I wanted some that went to cli->task1, cli->task2 etc
I had to update *system\codeigniter\system\core\URI.php*so that it knew how to extract the parameters I was passing via the command line, I got the code below from a more recent version of Codeigniter which supports the CLI
// Is the request coming from the command line?
if (php_sapi_name() == 'cli' or defined('STDIN'))
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
and also created the function in the same file
private function _parse_cli_args()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? '/' . implode('/', $args) : '';
}
Also had to comment out the following in my cli.php file as all routing was going to the index method in my cli controller and ignoring my parameters
/*
* ~ line 109 - 111 /cli.php
* ---------------------------------------------------------------
* Disable all routing, send everything to the frontend
* ---------------------------------------------------------------
*/
$routing['directory'] = '';
$routing['controller'] = 'cli';
//$routing['function'] = '';
Even leaving
$routing['function'] = '';
Will force requests to go to index controller
In the end I felt this was a bit hacky but I really need to use the EE API library in my case. Otherwise I would have just created a separate application with Codeigniter to handle my CLI needs, hope the above helps others.

I found #Zenbuman's answer after solving my own variation of this problem. My example allows you to keep the cron script inside a module, so if you need your module to have a cron feature it all stays neatly packaged together. Here's a detailed guide on my blog.

Related

Dropbox API - search in files and content

I'm trying to build Java app that search for files including a "word" in a content of files inside dropbox folder.
As we can see in Dropbox docs:
https://www.dropbox.com/developers/documentation/http#documentation-files-search
we can do that using "filename_and_content".
I suppose that the fragment of Java code allowing to set "filename_and_content" should look like this:
SearchBuilder searchBuilder = client.files.searchBuilder("/duke/duke/Daily_Activity_Reports", "plik");
searchBuilder.mode(Files.SearchMode.filenameAndContent);
But how should I use this SearchBuilder in searching?
Once you have the SearchBuilder object configured the way you want, you can then call the start method on it to begin searching. The documentation for the start method can be found here.
It returns a SearchResults object with the results, as well as more, which tells you if there are more results available, and start, which you should pass back to the start method in order to get the rest of the results.

symfony2 get firewall name on login page

I'd want to use a login page to access different firewalls, so I need to get information about the firewall I'm logging in.
In my controller I'd use
$this->container->get('security.context')->getToken()->getProviderKey()
but as an anonymous user I don't have access to getProviderKey method.
I could also parse
_security.xxx.target_path
to get xxx firewall but I'm looking for a more general solution if it exists at all.
Any idea?
As of symfony 3.2, you can now get the current firewall configuration using the following:
public function indexAction(Request $request)
{
$firewall = $this->container
->get('security.firewall.map')
->getFirewallConfig($request)
->getName();
}
Ref: http://symfony.com/blog/new-in-symfony-3-2-firewall-config-class-and-profiler
For Symfony 3.4 I wrote this to avoid referencing the non-public "security.firewall.map" service:
$firewallName = null;
if (($firewallContext = trim($request->attributes->get("_firewall_context", null))) && (false !== ($firewallContextNameSplit = strrpos($firewallContext, ".")))) {
$firewallName = substr($firewallContext, $firewallContextNameSplit + 1);
}
(Referencing "security.firewall.map" on 3.4 will throw an exception.)
Edit: This will not work in a custom exception controller function.
I was doing a little research on this myself recently so that I could send this information in an XACML request as part of the environment.
As far as I can tell from GitHub issues like this one:
https://github.com/symfony/symfony/issues/14435
There is currently no way to reliably get the information out of Symfony except the dirty compiler pass hack suggested on the linked issue. It does appear from the conversation on these issues, they are working on making this available, however, the status is still open, so we will have to be patient and wait for it to be provided.
#Adambean's answer is pretty elegant, but I'd write it as a one-liner:
$firewallName = array_slice(explode('.', trim($request->attributes->get('_firewall_context'))), -1)[0];
The difference is that $firewallName will always be a string (which may be empty).
Also, please note that this answer (like #Adambean's) doesn't work for a firewall with a dot in its name.

Avoiding repetition with Flask - but is it too DRY?

Let us assume I serve data to colleagues in-office with a small Flask app, and let us also assume that it is a project I am not explicitly 'paid to do' so I don't have all the time in the world to write code.
It has occurred to me in my experimentation with pet projects at home that instead of decorating every last route with #app.route('/some/local/page') that I can do the following:
from flask import Flask, render_template, url_for, redirect, abort
from collections import OrderedDict
goodURLS = OrderedDict([('/index','Home'), ##can be passed to the template
('/about', 'About'), ##to create the navigation bar
('/foo', 'Foo'),
('/bar', 'Bar'), ##hence the use of OrderedDict
('/eggs', 'Eggs'), ##to have a set order for that navibar
('/spam', 'Spam')])
app = Flask(__name__)
#app.route('/<destination>')
def goThere(destination):
availableRoutes = goodURLS.keys():
if "/" + destination in availableRoutes:
return render_template('/%s.html' % destination, goodURLS=goodURLS)
else:
abort(404)
#app.errorhandler(404)
def notFound(e):
return render_template('/notFound.html'), 404
Now all I need to do is update my one list, and both my navigation bar and route handling function are lock-step.
Alternatively, I've written a method to determine the viable file locations by using os.walk in conjunction with file.endswith('.aGivenFileExtension') to locate every file which I mean to make accessible. The user's request can then be compared against the list this function returns (which obviously changes the serveTheUser() function.
from os import path, walk
def fileFinder(directory, extension=".html"):
"""Returns a list of files with a given file extension at a given path.
By default .html files are returned.
"""
foundFilesList = []
if path.exists(directory):
for p, d, files in walk(directory):
for file in files:
if file.endswith(extension):
foundFilesList.append(file)
return foundFilesList
goodRoutes = fileFinder('./templates/someFolderWithGoodRoutes/')
The question is, Is This Bad?
There are many aspects of Flask I'm just not using (mainly because I haven't needed to know about them yet) - so maybe this is actually limiting, or redundant when compared against a built-in feature of Flask. Does my lack of explicitly decorating each route rob me of a great feature of Flask?
Additionally, is either of these methods more or less safe than the other? I really don't know much about web security - and like I said, right now this is all in-office stuff, the security of my data is assured by our IT professional and there are no incoming requests from outside the office - but in a real-world setting, would either of these be detrimental? In particular, if I am using the backend to os.walk a location on the server's local disk, I'm not asking to have it abused by some ne'er-do-well am I?
EDIT: I've offered this as a bounty, because if it is not a safe or constructive practice I'd like to avoid using it for things that I'd want to like push to Heroku or just in general publicly serve for family, etc. It just seems like decorating every viable route with app.route is a waste of time.
There isn't anything really wrong with your solution, in my opinion. The problem is that with this kind of setup the things you can do are pretty limited.
I'm not sure if you simplified your code to show here, but if all you are doing in your view function is to gather some data and then select one of a few templates to render it then you might as well render the whole thing in a single page and maybe use a Javascript tab control to divide it up in sections on the client.
If each template requires different data, then the logic that obtains and processes the data for each template will have to be in your view function, and that is going to look pretty messy because you'll have a long chain of if statements to handle each template. Between that and separate view functions per template I think the latter will be quicker, even more so if you also consider the maintenance effort.
Update: based on the conversion in the comments I stand by my answer, with some minor reservations.
I think your solution works and has no major problems. I don't see a security risk because you are validating the input that comes from the client before you use it.
You are just using Flask to serve files that can be considered static if you ignore the navigation bar at the top. You should consider compiling the Flask app into a set of static files using an extension like Frozen-Flask, then you just host the compiled files with a regular web server. And when you need to add/remove routes you can modify the Flask app and compile it again.
Another thought is that your Flask app structure will not scale well if you need to add server-side logic. Right now you don't have any logic in the server, everything is handled by jQuery in the browser, so having a single view function works just fine. If at some point you need to add server logic for these pages then you will find that this structure isn't convenient.
I hope this helps.
I assume based on your code that all the routes have a corresponding template file of the same name (destination to destination.html) and that the goodURL menu bar is changed manually. An easier method would be to try to render the template at request and return your 404 page if it doesn't exist.
from jinja2 import TemplateNotFound
from werkzeug import secure_filename
....
#app.route('/<destination>')
def goThere(destination):
destTemplate = secure_filename("%s.html" % destination)
try:
return render_template(destTemplate, goodURLS=goodURLS)
except TemplateNotFound:
abort(404)
#app.errorhandler(404)
def notFound(e):
return render_template('/notFound.html'), 404
This is adapted from the answer to Stackoverflow: How do I create a 404 page?.
Edit: Updated to make use of Werkzeug's secure_filename to clean user input.

How to do navigation durandal.js?

i am trying to use durandal.js for single page architecture,
i already have application where i am loading all pages in div = old approach for single page architecture,
what i want to do is when i click on page i need to open hotspa pages,
for now i write something like this . www.xyz.com#/details,
where # details is my durandal view page!
when i put <a> herf ....#/details, i got error like this :
http://postimg.org/image/hoeu1wiz5/
but when i refresh with same url, it is working fine, i am able to see view!
i do not know why i got this error
If you are using anything before version 2.0 of Durandal, you are getting this because in your Shell.js you are not defining router, or you have a bad definition of where the router module is, or possibly you are defining scripts in your index instead of 'requiring them' via require.js
1st - Check shell.js, at the top you should have a define function and it should say / do something like this, and should be exposing that to the view like so -
define(['durandal/plugins/router'], function (router) {
var shell = {
router: router
};
return shell;
};
2nd - Check and make sure the 'durandal/plugins/router' is point to the correct location in the solution explorer, in this case it is app > durandal > plugins > router. If it is not or if there is no router you can add it using nuget.
3rd - Make sure you aren't loading scripts up in your index or shell html pages. When using require.js you need to move any scripts you are loading into a require statement for everything to function properly. The 'Mismatched anonymous define() module' error usually occurs when you are loading them elsewhere - http://requirejs.org/docs/errors.html#mismatch

Drupal - Security check all site paths by role

I'm writing this in the forlorn hope that someone has already done something similar. I would have posted on drupal.org - but that site is about as user-friendly as a kick in the tomatoes.
I don't know about you, but when I develop I leave all my Drupal paths with open access, and then think about locking them down with access permissions at the end.
What would be be really useful is a module which parses all the paths available (by basically deconstructing the contents of the menu_router table) and then trying them (curl?) in turn whilst logged-in as a given user with a given set of roles.
The output would be a simple html page saying which paths are accessible and which are not.
I'm almost resigned to doing this myself, but if anyone knows of anything vaguely similar I'd be more than grateful to hear about it.
Cheers
UPDATE
Following a great idea from Yorirou, I knocked together a simple module to provide the output I was looking for.
You can get the code here: http://github.com/hymanroth/Path-Lockdown
My first attempt would be a function like this:
function check_paths($uid) {
global $user;
$origuser = $user;
$user = user_load($uid);
$paths = array();
foreach(array_keys(module_invoke_all('menu')) as $path) {
$result = menu_execute_active_handler($path);
if($result != MENU_ACCESS_DENIED && $result != MENU_NOT_FOUND) {
$paths[$path] = TRUE;
}
else {
$paths[$path] = FALSE;
}
}
$user = $origuser;
return $paths;
}
This is good for a first time, but it can't handle wildcard paths (% in the menu path). Loading all possible values can be an option, but it doesn't work in all cases. For instance, if you have %node for example, then you can use node_load, but if you have just %, then you have no idea what to load. Also, it is a common practice to omit the last argument, which is a variable, in order to correctly handle if no argument is given (eg. display all elements).
Also, it might be a good idea to integrate this solution with the Drupal's testing system.
I did a bit of research and wasn't able to find anything. Though I'm inclined to think there is a way to check path access through Drupal API as opposed to CURL - but please keep me updated on your progress / let me know if you would like help developing. This would a great addition to the Drupal modules.

Resources