Hosting piwik on a server with a read-only filesystem - php

I use CloudControl for hosting and I would like to set up a server (possibly with load balancing support) to host piwik for all of my websites. The only problem is that the only writable directory CloudControlled allows you to access is defined by $_SERVER['TMPDIR'].
Is it possible to modify piwik to use this directory for all of its file-writing needs?
And also will I run into any issues with using load balancing? Something like automatically generated reports being generated by each node behind my load balancer since they're not aware of each other?

The idea is to keep this change for your system even when you update.
This is easy to do: create a bootstrap.php inside the piwik main folder.
This is the content of said file:
<?php
define('PIWIK_USER_PATH', $_SERVER['TMPDIR']);
You can double-check this: in index.php, you should see that it checks for a bootstrap.php file in the same folder. It's included when available, and this allows you to do little customizations and keep them even when you update. E.g. I've run piwik from svn for the past three years or so and have some custom changes in there.

There's far too much code for me to be able to confirm this works, but the constant PIWIK_USER_PATH seems to be used as the base root for file io. With that in mind, editing index.php, around line 23, which is originally:
if(!defined('PIWIK_USER_PATH'))
{
define('PIWIK_USER_PATH', PIWIK_DOCUMENT_ROOT);
}
To something like:
if(!defined('PIWIK_USER_PATH'))
{
define('PIWIK_USER_PATH', $_SERVER['TMPDIR']);
}
Might work - but then what happens when it's trying to read a file in its original location? Since this is a temporary directory, however, it may not be viable, in which case an approach using override_function or a similar method, paired with a persistent storage (your database), might also work - by overriding file functions with a database load/save routine; obviously this opens up another can of worms of biblical proportions, thus, my final recommendation is for you to get another less restrictive host.

Related

How to move Joomla's configuration.php file above the root folder in a web host?

I have installed a security solution in my Joomla website,and it's suggest that to put the configuration.php file above the Public_html Folder,how could it be possible?
how to tell the CMS to recognize the new location?
is the solution would be valid in all versions of the Joomla CMS? ,if it's not,so please
write:
1st:Joomla 2.5 Solution.
2nd:Joomla 3 Solution.
you would need to modify the defines.php file located in the includes folder.
Specifically this line:
define('JPATH_CONFIGURATION', JPATH_ROOT);
And change JPATH_ROOT to the correct path.
But the problem with this is that you are modifying a core file so if an update changes the defines.php file it will overwrite your changes and will break your setup. You will need to reedit the file.
Also the JPATH_CONFIGURATION constant may be used for other things within the CMS that are not specifically trying to get the configuration.php file so make sure to check that it will not adversely affect other parts of the cms before doing this in production.
Alternatively you can change the frameworks.php file (also in the includes folder) directly to change from where the configuration is loaded from
ob_start();
require_once JPATH_CONFIGURATION . '/configuration.php';
ob_end_clean();
Just change the require_once line to the correct path.
Again since this is a core file it could be changed by an update. But this may also affect other parts if the config file is loaded manually in components or other parts of the cms.
Simply answer is don't do it. This would mean you would have to do what #Patrick has suggest which is correct and will work, however it means editing a core Joomla file. This is not a good idea as in your case, if you ever update Joomla, you will have to perform this change every time and it you forget (which is likely), your site will stop working completely.
I would strongly suggest you find a different "security solution" which does not involve having to modify any core Joomla files.
If you could define what you mean by "security solution", then maybe an alternative could be provided for you
I didn't dig for 'since when this has been implemented', But it can be done without changing the core.
Joomla looks for a defines.php in the root and if its present, imports it. And then if it finds a constant named _JDEFINES defined, it doesn't load the original file, effectively overriding it completely.
So, If you wish to override the defines its pretty easy and all you have to do is copy the contents of the defines.php file from under the webroot/includes/ path and paste it inside the one we created in the webroot. And you can change the following constant as per your taste.
define('JPATH_CONFIGURATION', JPATH_ROOT."/my/supersecret/directory");
Now there is one more thing left to be done and then we are good to go :)
You have to prepend the following lines to the top of our override file (the defines.php in the webroot).
define('JPATH_BASE', __DIR__);
define('_JDEFINES', 1);
This constant conveys to the framework that the defines have been overridden and to use the new file accordingly (Last time I checked, this flag/constant is checked at around 10 different places all over the framework eg. here, so its important)
Also I have seen this feature available with Joomla v2.5.0 and v3.8.8 as per your requirements in the question.
Edit: Remember you have to repeat the same procedure for administrator folder too if you want admin panel to work, and remember that administrator has its own /includes/defines.php

Does symlinking a file change how the file is parsed in php?

I have a php application that relies on several classes to function properly. If I take one of the application's class files
/my/folder/class.php
then move it somewhere else
mv /my/folder/class.php /my/other/folder/class.php
then in its place inside of
/my/folder/
I create a symlink to it called class.php via
ln -s /my/other/folder/class.php /my/folder/class.php
I would expect my application to be unaffected, but instead this is breaking it. I know the symlink is valid since at the command line I can do
nano /my/folder/class.php
and everything looks as I would expect it to. Am I missing something fundamental about the behavior of symlinks, and/or how apache or php processes them? Is it changing the working directory or $_SERVER['DOCUMENT_ROOT']? I can not figure out why this would have any affect on my application.
I am using Apache server in CentOs.
Thanks!
The only difference would be if you are using require_once or include_once and you are mixing the symlink path with the real file path. In this instance, the X_once is going to think those files are different and load it twice (which will of course cause problems if you define any classes or functions).
Would probably need an actual error message to guess any further.

php show holding page using ip address

A common problem that I face is placing a holding page on a website, while a new deployment is performed or some other maintenance is done (like testing the new deployment). I know this can be accomplished easily if you are using Apache (htaccess), but this is not always the web server in use (IIS, Nginx, etc). All my current websites redirect every request to an index.php file in the root of the public directory (e.g. Zend Framework, Wordpress, Symfony2), and so my current solution is the following:
To add the following code into the root index.php file:
$maintenanceFile = 'maintenance.flag';
if (file_exists($maintenanceFile)) {
$ips = explode("\n",file_get_contents($maintenanceFile));
foreach($ips as $key=>$value) {
$ips[$key] = trim($value);
}
if(!isset($_COOKIE['BYPASS_MAINTENANCE']) && !in_array($_SERVER['REMOTE_ADDR'], $ips)) {
include_once dirname(__FILE__) . '/holding.html';
exit;
}
}
With this I can simply add a maintenance.flag file also in the root, which contains a list of allowed ip addresses like so:
127.0.0.1
123.456.789.101
Then if the your ip address exists within the list, you can see the current website and test it etc before going public again, otherwise you are shown a holding.html page (which also resides in the root) instead. Once finished I can simply delete the maintenance.flag file.
So my question is, is there a better way of doing this?
I split up my website in 3 parts (copies) and have 3 subdomains.
1) dev.website.com is for developers. You can access if your ip is found, like your way.
2) test.website.com is for tester before I launch the website we need to test for buggs.
3) live.website.com equal to website.com for all the others.
This way I can easy develop without causing problems on the live domains.
You can easy switch from dev to test to live. You can copy environments easy.
Hopefully helped you!
The development and production versions of a website should always be in different directories and accessed using different domain names or ports or paths. And both should never use the same DB or other resources like uploaded files, etc.
If you're using Subversion, or git or any code repository (which I hope you are) then its easy to have a separate "dev" environment setup where you can do all your testing, etc. All my sites are setup this way. Once I implement or fix features and have tested them in my "dev" side I commit my changes to SVN and then on my "prod" side I simply do an svn update to push everything into production.
The problem with your $maintenanceFile technique is every single page request to your site will result in a file_exists check on your hard drive. This may not matter for smaller sites but for larger sites with a lot of hits this could result in slower performance overall.

Doctrine 2. Auto generating proxies

I have a strange problem. I want to turn off the auto generating of my proxies in Doctrine 2. I found this line of code that should do (and does) the trick:
$config->setProxyDir(APPPATHSYSTEM."/proxies");
$config->setProxyNamespace('Proxies');
// Auto generate proxies for development
$config->setAutoGenerateProxyClasses(DEVELOPMENT);
On my test environment the proxies are located at application/proxies. i.e.:
application/proxies/BaseUserProxy.php
When I'm on the live environment my code suddenly searches for the proxies at application/proxies/Proxies which is not the actual location.
I do understand it has something to do with the namespace, but I don't understand why it behaves differently when using the setAutoGenerateProxy method.
Any ideas?
edit
I did generate the new proxies using the:
orm:generate-proxies
option.
Which gave me this output:
php doctrine.php orm:generate-proxies
Processing entity "Base\Element"
Processing entity "Base\Page"
...
Processing entity "Base\Site"
Proxy classes generated to "/var/www/application/proxies"
Looking at the last line, the proxies are generated in /var/www/application/proxies. The directory listing looks like this:
BaseElementProxy.php
BasePageProxy.php
...
BaseSiteProxy.php
So there is no extra Proxies directory. But when I refresh my webpage it thinks there is, it gives me the following error:
Warning: require(/var/www/application//proxies/Proxies/BaseUserProxy.php)
[function.require]: failed to open stream:
No such file or directory in /var/www/library/Doctrine/Common/ClassLoader.php on line 148
Why is the extra Proxies directory added? If I do generate the proxies on each request it does not look in the extra Proxies directory. Anybody?
#Bryan M.: That is not a solution, but a workaround. Besides, it does not work. When generating the proxies they will, if applying your suggestion, be generated in APPPATHSYSTEM and my webapp will try to load them from APPPATHSYSTEM."Proxies". The problem is that the system looks for the proxies on different locations if I use:
$config->setAutoGenerateProxyClasses(DEVELOPMENT);
If DEVELOPMENT is true, it will look at APPPATHSYSTEM. If DEVELOPMENT set to false, it will look at APPPATHSYSTEM."Proxies". Just switching the DEVELOPMENT constance breaks my application, what theoretically should not be possible.
I don't think AutoGenerated proxies care.
Instead of pushing autogenerated proxies to production, you should probably doctrine orm:generate-proxies, which I suspect will put them in the place your production code is configured to look for them.
Are you developing on OS X and deploying to Linux? OS X's filesystem is case insensitive. So I'll often run into a problem where I mistype the case of a class, and it runs and passes just fine in the local environment, but chokes on our server.
So in this case, in OS X, the namespace "Proxies" is able to resolve to "/proxies", but in production, it can't find the class folder, and creates it under "/proxies/Proxies".
If you rename the folder to something called "/temp" you will realize the difference between path and namespace.
The path is the absolute path to the directory the proxies are getting generated into. The namespace is necessary to allow you to configure how an autoloader picks up these entities.
The path in your case has to be something like "proxies/Proxies" and the namespace is then "Proxies". Your autoloader has to be configured to listen to namespace prefix "Proxies" at directory "proxies/".
This is all mood with Doctrine 2 RC1 though, we found a way to explicitly load a proxy path without help of an autoloader at no additional cost. The Proxy Namespace configuratino is therefore only necessary to make sure no other classes are in the same namespace as the proxies.

Robust Directory Manager in PHP

This is a general question. What are some techniques you employ to prevent the links in your PHP code from breaking every time you move a file or move a file into a different directory?
For front end stuff, always use absolute URLs (start with '/' so you can move from domain to domain as needed).
For internal include() / require() type stuff, do as Gaurav suggests and use a config file that creates a constant to represent your path (so you can change it easily as needed from one location in your code).
For library type stuff (i.e. classes, functions, etc) that you want to reuse, I would add that to the include_path either via php.ini (global or local), .htaccess (if you are using apache) or via the ini_set() function. That way you can include these files by just the filename (i.e. <?php include_once('library.php'); ?>)
If you go the ini_set route, take a look at the auto_append directive (which in turn can be set via php.ini, .htaccess or ini_set)... that way you can have a 'bootstrap' file added to every page request that sets up your include_path for just that application without having to add the ini_set statement every where you turn.
With all that said, I recommend that you:
think your application layout ahead in advance, develop a common convention, and stick to it.
consider learning about design patterns (MVC, et al), which will get you thinking in new ways about how you design your applications
adopt the use of an application framework (CakePHP, Zend Framework, etc) which will come with a suggested (or mandated) file/directory layout and keep you from having to manage file locations and stuff.
Good luck!
If you move/rename a file that is linked throughout your web page and would like to ensure that links still work, I would write a 303 redirect (where and how depends on your web server and it's configuration).
I use a configuration file wherein I define all the paths (using define()) to various directories like 'webroot', 'application', or 'css'
This way I need to change only one line in one file and the changes are affected in all files wherein this variable is used.

Categories