Slim 3 double output using own view file - slim-3

In spite that I am very new to the Slim 3 framework I'm using it for a small project (API) and it works fine except for the double output that I'm getting back and it's making me crazy! I'm suspecting that htaccess is calling the index.php file twice, leading the app to run more than once, or an incorrect integration of the viewer code (Formater.php)....but I can't seem to find it.
My second question is: Where exactly do Slim 3 apps end ( the exit point ) ?
Here is a short description of my app flow:
input-request ---> Slim route handlers ---> my code (middleware and controllers ) ---> my output formater ( I use a small class to handle the output depending on the format switch [text, json, xml] *** the Formater class)

OK, I have taken some more time to read the source code of the Slim Response files and found that I had to use the response->getBody()->rewind() method to start with a fresh response body in case you are using your own viewer..... Indeed that did solve the problem.

Related

Encoded slash (%2F) in query parameter causes redirection to fail in Angular Application

In my angular application, I need to make GET call to a Tomcat server. This GET call requires query parameters which could contain special characters too like "+", "/", "/+"
GET call is being made from angular controller using $window.open with target as "_blank"
Currently the redirection is getting failed without any encoding.
So, I added encoding in .js file before the GET call is being made by using encodeURIComponent.
Then I added decoding logic using URLDecode.decode in backend java code to decode query parameters.
But still it doesn't work.
It works only if I encode query parameters twice within the .js file using encodeURIComponent twice.
I am trying to find the root cause for double encoding but no luck yet. I would greatly appreciate if anyone could share any inputs.
Made it work by adding a * in path parameter in app.js. Adding a star means that the request will include multiple path parameters separated by /, and so angular will not try to encode / in the request.
Double encoding could also work but then the server side logic has to be modified to decode the request parameters twice and replace %2B2F by %2F

Writing custom php script in joomla

I am good in php and javascript. I need a guidance where to place my custom php script if i make a ajax call from joomla.
I need to fetch the file names from a specific folder. I could make an ajax that will communicate with my php code and in return, my php code will give me the files of the specific folder.
Where is that php script to be place and how it should be routed.
For example
$.ajax({
url:'....../fetchfiles.php',
success:function(data){
}
})
Hope i was clear.
If I understood correctly your question my answer would be that you can place your fetchfiles.php wherever you want providing that you put right path to the file in your $.ajax call.
Then in the fetches.php you should call Joomla framework before you start your code, something like this:
// no direct access
define( '_JEXEC', 1 );
// get joomla root
$jpath_root = $_POST['jpath_root'];
//load Joomla
define( 'JPATH_BASE', $jpath_root );
require_once ( JPATH_BASE .'/includes/defines.php' );
require_once ( JPATH_BASE .'/includes/framework.php' );
jimport( 'joomla.application.application' );
jimport( 'joomla.filter.filteroutput' );
$japp = JFactory::getApplication('site');
/* now you are good to go with your code */
Just a few words about
// get joomla root
$jpath_root = $_POST['jpath_root'];
part.
My experience is that it is the best if you pass JPATH_ROOT variable via $.ajax( one way would be to have hidden input with value set to 'JPATH_ROOT' in your joomla file from where you call ajax and then in your ajax.js just pick that value up and pass to the ajax.php or fetches.php in your case)
You can define JPATH_BASE another way too, eg
define( 'JPATH_BASE', realpath(dirname(__FILE__)));
or
define( 'JPATH_BASE', realpath(dirname(__FILE__).'/../../..' ));
depending on your actual files structure but be aware that this way you practically redefined original JPATH_BASE constant and that it may cause conflicts in case you call, later within your code, some third party component functions/classes which may depend on original Joomla defined constants ...
I've learned it hard way with ZOO Component and my ajax calls ... :)
Hope this makes some sense.
Based on where you want to show the results you can create a component or a module (you can also easily include the module in an article to print the result in component position).
In the case of module:
https://docs.joomla.org/J3.x:Creating_a_simple_module/Developing_a_Basic_Module
Obviously your ajax call will be in tmpl/default.php and your php script in the module folder, simply you have to include it in the file list in mod_helloworld.xml. Then zip your folder and install it using Module Manager.
In case of problem with your jquery code, you have to use the noConflict() mode.

Nginx fallback for file not found to different directory with same path

Short Version: Is there any easy way to automatically redirect a path like /templates/my_child_theme/main/sidebar/user_nav.html to /templates/default/main/sidebar/user_nav.html whenever a 404 is encountered?
Question: Is there an easy way to use something like try_files within nginx to change a filepath when not found to a different folder with the same file path at the end? I'm currently using a client-side framework (AngularJS) and dealing with checking for the existence of files can get fairly expensive as I am literally performing an AJAX call for each file and looking for a 404 before performing the logic to swap out the path in Javascript. I've seen similar solutions for fallback images but haven't gotten a good solution yet. Here's the gist of what I'm looking to do:
Look for file at /templates/$1/$2.
On HTTP 404 instead return /templates/default/$2.
This only really needs to happen in the /templates/ location for now.
It's possible that these files could be nested several layers deep so I need something like /templates/my_child_theme/main/sidebar/user_nav.html to redirect to /templates/default/main/sidebar/user_nav.html
Backstory:
I've been building a site in AngularJS that has a fairly complex templating setup. I am utilizing the awesome ui-router module from Angular UI for deeply nested views and have written a few custom functions to implement child themes similar to Magento's fallback system. Here's what currently happens:
AngularJS requests a template path using a getTemplate() function I wrote which first looks for the file at /templates/child_theme_name_here/filepath by performing an XMLHttpRequest, checking for a status code of 404 (file not found), and then either returning that path or (in the case of a 404) returning /templates/default/filepath instead.
This way I can overload modify specific templates without needing to copy the entire theme each time, making development easier (we have 3 major corporate clients which will each have their own branded child theme) by not making me keep up with each change across multiple themes.
If there is a better way to do this within AngularJS I am open to that as well, it just seemed to me that Nginx would be the most logical place to perform such an action due to to it's low-level integration with the filesystem.
Solved.
Had to teach myself a bit on regular expressions, but finally got it working.
Here's what worked:
location ~* ^\/templates\/([^\/\\\]+)(.*)$ {
try_files /templates/$1$2 /templates/default$2 =404;
}
Regex Explanation
~* means case-insensitive matching (not really regex, just nginx syntax)
^ means start of a string
\/ means match a backslash
templates means literally match the word templates
\/ means match a backslash again
( means start capturing the following match as a group for later use
[^\\\/] means match anything that's not a backslash or forward slash means the previous set of characters can be matched multiple times (i.e. keep matching anything that isn't a slash.
) means stop capturing characters for this group. We have now defined the string that represents the first folder after /templates/
(.*) means match any other character as many times as needed (match everything that isn't a line feed in other words)
$ means match the end of the string
try_files then tries each URL in order
/templates/$1$2 means try /templates/(everything in capture group 1 above, which holds the folder we captured)(then add everything from capture group which holds the backslash and anything after it until the end of the url)
/templates/default$2 is very similar, except instead of using the text from capture group 1 ($1, the folder name we matched) we use the text "default" and then add everything from the second capture group to the end like before
=404 means that if neither of those worked return a 404 error
I'm seeing a significant speed improvement by moving this fallback mechanism into the server versus all of the extraneous calls I was forced to do before on the client.

Composite C1 - MVC Player conflicting with Blog module

I have a composite C1 site - working fine. Some pages use the MVC Player - which works fine - along with all pages on the site - except the Blog which causes a routing conflict.
Error: The incoming request does not match any route.
C1 Function: Composite.AspNet.MvcPlayer.Render
Error details:
Exception has been thrown by the target of an invocation.
The incoming request does not match any route.
This error appears at the top of the page - the blog works fine under the error - I just need to get rid of the cause of this error. I guess the MVC controller is trying to route the blog pages because it thinks they don't exist & can't find the controller.
How can I get the controller to ignore the blog - or fix this some other way?
Short answer is that both items (blog and mvc player) are fighting over the path portion of your URL. They both expect they own the path into bit to do routing.
Example: /en/Blog /2011/11/29/Chamonix-To-Courmayeur-Skiing-Day-Trips
The /en/Blog portion is routing you to the page hosting your blog, while the rest is path info that is passed along to any functions you may have hosted on the page. Since the path is "one thing" there is no distinction whether this string is intended for the blog function or the MVC Player function. This is what is creating the confusion.
Provided you wish to leave the blog as is you can work around this issue in two ways:
Move the feature you have in MVC Player to another function provider, like Razor Functions
Change the MVC Player so it does not pass the path info along to you MVC controller.
The second workaround can be done quick and dirty by editing ~/App_Code/Composite/AspNet/MvcPlayer/Player.cs and commenting out this line (line 57)
Path = PathInfo;
Before you do this note that this would impact all your running instances of MvcPlayer.
To create a new alternative MvcPlayer which does not rely on routing (leaving the original one intact) do this:
Copy Player.cs to NoRoutePlayer.cs (and rename the class accordingly) and make the above mentioned change there (comment out line 57).
Then register this new function in Composite C1 by going to Functions | C# Functions | Composite | AspNet | MvcPlayer and add a node here, using the existing Render element as inspiration. Just set the 'Type' name to NoRoutePlayer.
With that change you will have a Player function and a NonRoutingPlayer function and you can then use the latter to run your MVC controller, and everyone should get along just fine :)

CakePHP 1.3: Measuring Page Execution Time

Looking to figure out how to measure the total PHP execution time of a CakePHP site. It looks like in 1.2 this was included in the rendered HTML as a HTML comment when in debug mode, but this is not happening on my 1.3 site, and in any case I want it as an element I can output to the user, not a comment.
I can do this easily in regular PHP using microtime() but I'm not sure where to add the code in CakePHP, and I suspect it might have a more robust execution timer anyway. Ideas?
Just in case anyone else is curious, I solved this by adding the following code to my layout.ctp. You could also do this in the controller and pass it in as a variable, which might be a little more classic MVC-friendly, but I wanted this on every page of the site without duplicating code in each controller.
Page rendered in <?php echo round((getMicroTime() - $_SERVER['REQUEST_TIME']) * 1000) ?>ms.
Use Debug Kit. Among other functionality, you can grab the total execution time via
DebugKitDebugger::requestTime()
This may not be the "right" way to do it, but you can add the following PHP code back into app/webroot/index.php (at the very end). Then if you have debug on > 0, you'll get the old 1.2 functionality back.
if (Configure::read() > 0) {
echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
}

Resources