CakePHP cannot find database configuration from shell in plugin - php

Background: Basically, my application has a plugin which has a Shell within it. This Shell is located in the plugin's Console > Command folder. Functions from this shell are intended to be ran from the command line.
My database configuration file (database.php) is located in the application's root Config folder. I access the database in several other instances so I know there's nothing wrong with the database configuration.
When I try to use any Model data retrieval methods (such as find(...)), I get the error:
The datasource configuration "default" was not found in database.php
This is occurring because it's looking for the database.php file inside the Plugin's Config folder, rather than the root Config folder. This only occurs when using a Shell, rather than in a Controller.
My Question: How can I tell my Plugin to use the root's database.php file instead of trying to find it in it's own Config folder, when using a Shell?
To reiterate: The Plugin uses the root Config/database.php file when retrieving data from a model in a Controller, but tries to use its own Config/database.php file when retrieving data from a model in a Shell.
Two things that I've tried that will work: 1) Moving database.php into the Plugin's Config folder and 2) Creating a symbolic link.
Both solutions seem unacceptable as I don't want to have two copies of my database.php file around, and creating a symbolic link isn't a great solution since this application will likely have to be distributing among different systems.
Thanks. I should mention that this is Cakephp 2.3.6
Answer (thanks user221931): Your working path needs to be the application path, not the plugin path. You can run the plugin shell using the plugin dot notation. Like this:
cake -app /path/to/app Plugin.shellName shellFunction
as opposed to how I was incorrectly doing it before:
cake -app /path/to/app/Plugin/pluginName shellName shellFunction

How about running the plugin shell using -app?
Changing Paths:
Your working path should be the same as your application path. To change your path use the '-app' param.
Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp

Related

How do I set the working directory for phpunit using the XML file?

I'm looking through the documentation, but I'm not seeing any option to change the working directory used when running tests.
I'm using PhpUnit as it's included in Laravel. I want to be able to run vendor/bin/phpunit from my project's root directory, and have it run using the /public directory as the working directory.
I tried running ../vendor/bin/phpunit from the /public, but since the phpunit.xml file isn't in the public directory and I don't want to specify my config file path every time, that won't work.
Is there something I can add to my phpunit.xml file to tell it to run tests using the /public directory as the "cwd" (current working directory)?
Based on the feedback I received in the comments and the documentation, I determined the following:
It's probably not possible to change the cwd that phpunit uses by default (well, it's possible in PhpStorm, but not the command line without writing some kind of wrapper script)
Code that depends on being run from a specific directory is not a good idea.
What I had was some code in one of my classes like this:
$var = file_get_contents("../some_file.json");
This works fine -- until you try to add unit tests. The web server runs using the /public directory as the cwd, while phpunit will run using the root directory.
Rather than trying to force phpunit to always use a particular cwd (/public), I decided it's probably best to remove relative paths from the code that rely on a consistent cwd. So the line above becomes:
$var = file_get_contents(base_path("some_file.json"));
I didn't want to change production code that was already working just to get some tests in place, but this change seemed insignificant enough. (and it's an improvement anyway)
Well, you'd have to do the actual chdir in PHP, but you can define a bootstrap script in the XML (<phpunit bootstrap="./bootstrap.php">) and have that change the working directory.
Alternatively, you can put a setUpBeforeClass function into your test class that changes the working directory.

Is there a better alternative to relocate cakephp3 config folder

I am using Cakephp3 and would like to know if there is a better alternative to relocating the config folder.
The issue rises from the fact that everytime I have to refresh the production app, i copy over the entire app from development to production and reconfigure the required settings in the config folder.
After some iterations of this process, I started to make a backup of the config folder and after copying the app, restore the config folder.
After some time even this started to get tedious, so I ended up hacking the cake files and folders.
I relocated the config folder outside the root directory
Created a symbolic link in the root directory poiting to the config directory outside the root directory.
Updated the ROOT constant in config/paths.php to the real root folder
In webroot/index.php redefined the bootstrap.php require location
So as long as long as I dont update the cakephp core, I can copy over the dev app to the prod app and all the config stays the same.
I would like to know if some one has a simpler approach.
Thanks
After some research and reading carefully the comments in related bootstrap file, I found a solution for, well at least, my problem.
The problem basically was that I had to refresh the database, email, debug settings define in the app.php file, everytime I uploaded the app from my dev server to my prod server.
Reading the comments in the bootstrap file I found the comment which stated:
Load an environment local configuration file.
You can use a file like app_local.php to provide local overrides to your
shared configuration.
So this allows me to redefine the configurations defined in the app.php file. However I wanted this to me more dynamic, so I ended up creating an APP_INSTANCE_NAME constant in the bootstrap.php file of the webroot directory as follows
// /config/bootstrap.php
define('APP_INSTANCE_NAME', strtolower(gethostname()));
and later in the bootstrap file, i did the following:
Configure::load('app_' . APP_INSTANCE_NAME, 'default');
with this change, the configuration that gets loaded is based on the server hostname and I dont have to relocate the config folder. Hope this helps someone with cakephp3
Thanks to jason and greg's comments which motivated me to read the comments more carefully.

Routes file not properly loaded

I have just installed a new installation of Laravel using composer as per the laravel docs. The documentation refers to the app/routes.php file which is used to map routes to controllers or closed functions. First, there was no app/routes.php file so I created one. Now the routes I've copied from the laravel documentation aren't being found when accessing via the browser. In fact the app/routes.php file isn't even being found by the application as I have put a die statement in there and nothing. It has nothing to do with .htaccess. I am using the default .htaccess and redirects are working. I thought maybe it has something to do with the composer.json autoload array so I have tested that and nothing. Not a jot. Either I'm being thick or there is something fundamental which isn't being explained in the docs. I'm running the latest version of laravel. Any ideas?
Laravel changed the folder structure with its latest release (which is version 5):
In 4.2: app/routes.php
In 5.0: app/Http/routes.php
There's also a few things you need to do in order for a Laravel Project to work. First (and this is the method I use) create a symbolic link to your project's public folder:
ln -s /path/to/webroot/example_app/public /path/to/webroot/example
Next, change the permissions on your storage folder:
chmod 777 -R storage
You should now be able to access localhost/example and the Laravel 5 welcome page should show up. Usually I call my project example_app and create a link to a folder called example, so I can easily access it via localhost/example
In Laravel 5, the routes file is located elsewhere: app/Http/routes.php.
Basically I did chmod 777 on the storage and vendor files and it started working

How to add project to Netbeans when all source files are not in webroot?

The directory structure of my project is like this:-
/var/www/includes/
/var/www/classes/
/var/www/public/css/
/var/www/public/js/
/var/www/public/index.php
The webroot is /var/www/public, so accessing the test domain localhost.dev would serve the files inside the public directory and hence would run /var/www/public/index.php. No need to access like localhost.dev/public/index.php
The problem is when I create the project in Netbeans, I have to set the index file so that the project can be debugged using xdebug and Netbeans.
So when adding the project I provided /var/www as Project source folder (Sources Folder) as the includes and classes are in this folder. In the next project configuration screen (Choose Project > Name and Location > file path is taken as Run Configuration), I'm asked for the Project URL and the index file. Since the index.php file is actually under the /var/www/public/, when I browse the file and select it, the url to index page is taken as localhost.dev/public/index.php instead of just localhost.dev/index.php. This is preventing me from debugging the project.
Can anyone please point out how to add projects to Netbeans when all the source files are not in web root and the project is to be debugged using xdebug.
I think its a bad practice to put all the project files directly in /var/www.
I think you will never see that in real deployed projects. So my first recommendation will be to change the way you are structuring your project. If that's not possible, in Netbeans select /var/www/public as the Project folder.
If Netbeans need references to the folders in /var/www, create symbolic folders inside public pointing to those in /var/www.
The last resource you have is to create a rewrite rule in Apache to make localhost.dev/public be the same as localhost.dev. You can look for this in Apache documentation.
I have a similar set up with one minor difference: my setup uses a remote site on my local development server. On the "Run Configuration" window of the project properties, I set "Run As" to "Remote Web Site (FTP, SFTP)". I don't think this affects the information in my answer, but I'm mentioning it just in case.
Go to the "Sources" window of your project properties, find the entry for "Web Root", click "Browse" and select the /var/www/public directory. That should cause xDebug to use localhost.dev/index.php. You'll notice when you go to the "Run Configuration" window and browse for the Index File that the browse window will start in "public" rather than "www".
An important note about this type of configuration that caused me a great deal of frustration.
When using xDebug, you'll want to be able to set breakpoints in and work with the files outside of the web root (public) directory. Because you've set the web root to /var/www/public, you won't be able to work with the files in /var/www/includes or /var/www/classes.
The thing you need to do is to add the files outside of your web root to the Global Include Path.
There are two methods for adding directories to your Global Include Path, which one you use depends on how you've configured your project.
In your case, the external directories are included in your project, so you need to add them via the "Options" interface. Go to Tools->Options and select the "PHP" tab, then add the /var/www/includes and /var/www/classes folders to the Global Include Path.
The other method for adding files to the Global Include Path is for files that are located outside of your project source folder. For directories like /var/folder_outside_www/, you use the "PHP Include Path" window in the project properties.
I haven't found a better way but I use this steps:
Menu:Project Properties -> Link:Run Configuration -> Button:Advanced
Debug URL, choose: Ask Every Time
Path Mapping, Server Path: http://localhost.dev/ ,Project Path: /var/www/public/
Now, when you start Debugging process, Netbeans will display Specify URL pop-up which you can change from http://localhost.dev/public/index.php into http://localhost.dev/index.php
Set /var/www/public as project folder (contain netbeans project folder) and include in project properties /var/www/includes/ and /var/www/classes/ as global include directories. Or best way use PHPStorm.

CakePHP Shared core for multiple apps

On my local setup I have a load of different CakePHP websites. I'm using a Mac so the folder structure is something like ~/Users/cameron/Sites/sample-website and then within each of these websites I will have the typical Cake folder and App folder.
What I would like to do is have just a core cake folder and then have ALL the sites pull from that one cake core so I don't have the same stuff several times over. I have been reading some tutorials on the web: http://rickguyer.com/cakephp-one-core-many-apps/
So I have my cake folder here: ~/Users/cameron/Sites/cake-1.3/ and then my site here: ~/Users/cameron/Sites/sample-site/ and in this folder I have the usual app folder and htaccess to tell it where to find webroot etc.
Now I have edited the index.php file inside webroot like the tutorial BUT have only changed one line because I haven't moved my files OUTSIDE of the App folder like he does. So the only like I have changed is as follows:
if (!defined('CAKE_CORE_INCLUDE_PATH'))
{
define('CAKE_CORE_INCLUDE_PATH', '..'.DS.'..'.DS.'cake-1.3');
}
As far as I can tell that is correctly looking two directories up and finding a folder called cake-1.3 however it just gives a error 500?
Any ideas what the problem is? Thanks
EDIT:
Even doing this doesn't work???
Which If I echo: echo CAKE_CORE_INCLUDE_PATH; gives /Users/cameron/Sites/cake-1.3 and if I paste that in the address bar it loads up the cake folder so it's definitely the correct folder structure JUST it doesn't like looking at cake outside of the main url?
if (!defined('CAKE_CORE_INCLUDE_PATH'))
{
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3'); echo CAKE_CORE_INCLUDE_PATH;
}
You are right on the money with:
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3');
Just make sure that Users sits in root. In other words, when you go to terminal you can get to this directory by typing: cd /Users/cameron/Sites/cake-1.3
It looks like you may be on a MAC. If so, your linking is correct. Most of the time what I find is you have done a copy paste of the app directory and it does not get the .htaccess files. I would check those first. But here is a comprehensive list of what you should verify:
Make sure the host is pointing to
the correct directory
(/Users/cameron/Sites/sample-site/)
Verify mod_rewrite is in fact on.
Verify you have copied the .htaccess
file in both the
/Users/cameron/Sites/sample-site/
and the
/Users/cameron/Sites/sample-site/webroot
directories.
Confirm that the
/Users/cameron/Sites/cake-1.3/
directory has a directory called
cake in it that contains the core.
Once all of this is confirmed, you will be good as gold!
Happy Coding!
UPDATE:
When the index.php file looks for the cake core, it will look for a directory inside the location you are pointing to for another directory called cake. So in your case:
define('CAKE_CORE_INCLUDE_PATH', DS.'Users'.DS.'cameron'.DS.'Sites'.DS.'cake-1.3');
You must have the cake directory inside /Users/cameron/Sites/cake-1.3. Your directory structure will look like:
/Users/cameron/Sites/cake-1.3/cake
/Users/cameron/Sites/cake-1.3/cake/libs
/Users/cameron/Sites/cake-1.3/cake/config
/Users/cameron/Sites/cake-1.3/cake/console
etc.
CakePHP 3.0+
In CakePHP 3.0+ this configuration is moved out of webroot/index.php to App/Config/paths.php
If you have access to your php.ini, you can add the path to Cake core there. Doing it this way means you don't have to change webroot/index.php at all. Example in php.ini:
include_path = ".:/usr/local/lib/php:/home/something/phpinc/cakephp2/lib"
According to the CakePHP 2.x docs, this is the recommended way to share the Cake core (assuming you have access to your php.ini).
You can have only one cake core but you must have one app folder (containing MVC) by site.
Is this a misunderstanding of the folder structure of CakePHP?
From the docs (CakePHP folder structure):
The app folder will be where you work your magic: it’s where your application’s files will be placed.
The cake folder is where we’ve worked our magic. Make a personal commitment not to edit files in this folder. We can’t help you if you’ve modified the core.
So the cake folder shouldn't change between all of your uses, therefore you have 1 copy. You can always change some of the functionality of the core by making your own changes in the app folder i.e. extending.
There is no need to edit index.php.
Just put an alias (or link in UNIX) to your cake folder in each of your sites folder. Works perfectly. Same goes for plugins and vendors folder.

Categories