What is the best practice to disable caching in local development enviroments?
You might use \Cake\Cache\Cache::disable() in your bootstrap.php. I'm unaware of this being cited as 'best practise', however.
For CakePHP 4 you can do the following
in src/Application.php
use Cake\Cache\Cache;
...
public function bootstrap(): void
{
parent::bootstrap();
if (Configure::read('debug')) {
Cache::disable();
}
to disable cache completely
Also you can selectively disable only database metadata cache replacing Cache::disable(); to
$connection = ConnectionManager::get('default');
$connection->cacheMetadata(false);
Instead of default you can select your configured datasources
Do not forget to use Cake\Datasource\ConnectionManager;
And then you just need to enable debugging either in app_local.php using 'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN) or in .env setting DEBUG=true (or APP_DEBUG, look carefully in your config) if you are using dotenv. So you will not have uncommitted changes in your local files.
Related
I am using CakePHP and was trying to implement https://github.com/josegonzalez/cakephp-environments
Which seemed to be going fine except that I have no idea where to specify the env specific database info.
Does anyone know where to set these?
I personally haven't used the plugin, however from looking at the code and the docs, if you were using the suggested database configuration, then it seems that you would define the options as either environment variables, which can be done in various ways, for example
in your server configuration (Apache example)
in your cloud varibale settings (Heroku example)
manually using putenv(), $_ENV, $_SERVER
$name = 'MYSQL_DB_HOST';
$value = 'localhost';
putenv("$name=$value");
$_ENV[$name] = $value;
$_SERVER[$name] = $value;
...
or as CakePHP configuration values via the Environment::configure() calls, something like:
Environment::configure('development',
true,
array(
'MYSQL_DB_HOST' => 'localhost',
'MYSQL_USERNAME' => 'user',
// ...
),
// ...
);
I'm still getting to grips with puppet (feels like I'm drinking from a hose pipe at times) so I've attempted to keep my configuration and environment simple initially. I've started by having puppet deploy files to my clients. However, I get the feeling that the way I'm deploying the files isn't the most efficient way of doing so. For every file, I'm specifying like this:
file { "/etc/ntp.conf":
owner => 'root',
group => 'root',
mode => '0444',
source => 'puppet://basxtststinfl01/files/etc/ntp.conf',
}
file { "/etc/snmp/snmpd.conf":
owner => 'root',
group => 'root',
mode => '0644',
source => 'puppet://basxtststinfl01/files/etc/snmpd.conf',
}
I have up 15 files I'd like to deploy. Is this the correct approach?
Thanks.
File in modules is a good keyword.
Generally, to solve the problem of repetitive resource, you can wrap them in a defined type.
define deployed_file($ensure = 'present',
$owner = 'root',
$group = 'root',
$mode = '644',
$recurse = '') {
if $recurse != '' { File { recurse => $recurse } }
file {
$name:
ensure => $ensure,
owner => $owner,
group => $group,
source => "puppet://basxtststinfl01/files${name}",
}
}
Your resources from above can then be written as:
deployed_file {
'/etc/ntp.conf':
mode => '444';
'/etc/snmp/snmpd.conf':
}
You can add more parameters to make the URL customizable.
Note that I added the recurse parameter for posterity. file has lots of attributes, and if you need for the deployed_file to support them, you should add them in this manner, so that they get passed to the wrapped file if specified, but ignored otherwise.
I suppose the question of whether this is the ‘correct approach’ comes down to what you’re doing exactly, but since ‘it depends’ is sometimes an annoying thing to hear, theres a few general points that can be made ...
This is an approach that will work - it would deploy the 15 or so files that you have declared exactly as you specify them.
It does however come at the expense of requiring the exact maintenance of your files as they are written in basxtststinfl01
Since these are static files, you might find it restrictive if you come to running puppet code to provision many different servers.
So to options! The examples you have given there can be considered from the context of puppet modules - reusable code to configure a particular service or logical unit of your system
In your ntp case, there is an ntp puppet labs module which contains logic within it to create an ntp.conf file and takes variables as parameters to configure it. This shortens the puppet declaration and allows you to reuse it for provisioning more servers. An example of how to configure this is given in the documentation of the puppetlabs-ntp module.
class { '::ntp':
servers => [ 'ntp1.corp.com', 'ntp2.corp.com' ],
}
More often that not, someone has written a module that will provision a part of the system that you want, see the Puppet Forge
Decomposing your system requirements into units and using modules means you can specify your config files dynamically according to variables that might vary from system to system.
Best thing to do is work through the excellent documentation on the puppetlabs website:
Some resources:
Learning Puppet (you may already have seen)
Basics of modules
I'm on a shared host and ini_set function is disabled for security reasons. I'm trying to deploy CakePHP 2.4.1 on this host. Fresh cake installation results in a blank page, with no errors shown, instead if I comment these lines:
\lib\Cake\Model\Datasource\CakeSession.php
if (empty($_SESSION)) {
if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) {
foreach ($sessionConfig['ini'] as $setting => $value) {
if (ini_set($setting, $value) === false) {
throw new CakeSessionException(__d('cake_dev', 'Unable to configure the session, setting %s failed.', $setting));
}
}
}
}
Everything seems to works fine. Now, I'm asking what is the downside of keeping that snippets commented (in other word, what is that code responsible for)?
As the exception message, the method name and the rest of the code indicates, it configures the session settings, session name, cookie lifetime, save handler, etc...
Your code may run fine, and you should be able to use the PHP session_*() functions instead to configure the settings (the best place for that would probably your bootstrap.php). Also writing a dummy value into $_SESSION seems to prevent the CakeSession::_configureSession() to use ini_set(), so you don't have to modify it.
So this might work, but it shouldn't be necessary to jump through such hoops. There's no need to disable ini_set() in a properly set up shared hosting environment, and personally I'd change the hoster in case they are unable to change this behaviour.
I have a site running in localhost as a development environment and in a server for production.
There are some differences in some configuration files between both and I every time I have to update the changes in the server I have to be careful not to overwrite some files which are different.
I would like to be able to simplify this process by creating just one single file with the correct configuration for each environment.
I need to read that file currently in this Config files:
app/Config/email.php
app/Config/routes.php
And ideally, if possible in:
app/Vendor/Vendor_name/vendor_file.php
Is it possible somehow?
I have tried to use Configure::read and Configure::write but it seems it can not be done inside email settings such as public $smtp or in the routes file.
Thaks.
The routes file is simply a php file with calls to the router. You could very simply split it up into multiple files and load them yourself:
app/Config/
routes.php
routes_dev.php
routes_production.php
routes.php would then load the proper routes file.
<?php
if ($env == 'dev') {
include 'routes_dev.php';
} else {
include 'routes_production.php';
}
The email config is also just a php file. You could write a function to set the proper default config based on the environment.
class EmailConfig {
public function __construct() {
if ($env == 'dev') {
$this->default = $this->dev;
}
}
public $default = array(
'host' => 'mail.example.com',
'transport' => 'Smtp'
);
public $dev = array(
'host' => 'mail2.example.com',
'transport' => 'Smtp'
);
}
As for vendor files, that's a case by case basis.
If you have a deployment system, it might be better to actually have separate files for each environment (maybe even a full config directory) and rename them after the deployment build is complete, making Cake and your code none the wiser.
The way I used to handle this situation was to add environment variables to the apache virtualhost configuration.
SetEnv cake_apps_path /var/www/apps/
SetEnv cake_libs_path /var/www/libs/
This allowed me to then pull $_SERVER['cake_apps_path'] and $_SERVER['cake_libs_path']. Then each developer can set his own variables in his own virtualhost config, and you add that to the server's virtualhost config, and you're done. Each developer can have their own pathing.
I have problem with cakephp's Session->write method.
If I set a value like $_SESSION['..'] i'm able to read it back. But if I use the write method it's not working.
My problem is same as here: http://www.nabble.com/Session-problem-td16684956.html
The same code was working in windows but it's not working after I moved to linux.
Any permission problem would be the reason? (but i have given rw permission fully for the cake app directory).
code sample: in the link: http://www.nabble.com/Session-problem-td16684956.html
Configure::write('Session.save', 'php');
Configure::write('Session.cookie', 'CAKEPHP');
Configure::write('Session.start', true);
Configure::write('Session.checkAgent', false);
Configure::write('Security.level', 'medium');
cake version: 1.2.3.8166
Some steps to ensure it's not you:
clear the cache in your /app/tmp
check and recheck that your /app/tmp is world-writable recursively (that means drwxrwxrwx for all folders inside)
use Firebug to check your session cookie, maybe something has gone wrong with it
Last but not least, try to move your session persistence to your database (see: Session.save), just to test things out that way, you never know what you'll find.
Hopefully you'll find something if you try all these.
You should also try to use Cache::read and Cache::write
if (($session = Cache::read('session')) === false)
{
$session = 'some values';
Cache::write('session', $session);
}
Firstly, it will try to initialize Cache::read. If it returns false, Cache::write
will take part to store the values in sessions.
Prabu,
While I suspect the Configure::write() call will sometimes correctly set the session information (at least it looks like it might work), the Cake convention (aka the CakeWay) is to use the Session helper. I believe it is included by default in all Cake controllers; if not, you can always declare your controller as such:
class UsersController extends AppController {
...
var $helpers = array( 'Session', ... )
...
}
Then, when you want to write info to the session, just call:
$this->Session->write( 'checkAgent', false );
To read back values, use:
$this->Session->read( 'checkAgent');
For more information on the Session helper, check out the CakeBook # http://book.cakephp.org/view/484/Session