I'd like to use Cakephp classes (models) from regular php code unrelated to cakephp.
I tried this but it didn't work:
include('/lib/Cake/Core/App.php');
App::uses('Business', 'Model');
$b = new Business();
The last line gives me an error, and I've also tried several workarounds with no success...
I'll be ever grateful for a good answer :)
EDIT: Here's the solution I found! (Thanks, #Burzum!):
I copied webroot/index.php to webroot/cake_setup.php and removed the last few lines so it will only include stuff and not actually execute anything:
App::uses('Dispatcher', 'Routing');
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(
new CakeRequest(),
new CakeResponse()
);
Then, this worked from external php code:
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
include_once(__DIR__ . DS . '..' . DS . 'v2' . DS . 'app' . DS . 'webroot' . DS . 'cake_setup.php');
App::uses('AppModel', 'Model');
App::uses('Business', 'Model');
$b = new Business();
Thanks a lot guys!
CakePHP is not made to be used piece by piece. If you're looking for a standalone ORM go for doctrine or propel.
You can keep trying it but you'll have to run the bootstrapping process of the framework (see what it does inside webroot/index.php) and register it's class loader and point it the the core include path.
Edit:
While looking at this again today, I think the proper solution here would be to expose the stuff your need from your CakePHP app through an API that the other non-Cake app can consume. REST is pretty easy with CakePHP you might want to look at that solution. You don't tight couple your other app on the CakePHP app then. You can even upgrade to 3.0 without having to touch the other non-Cake app then.
Related
I've taken over an old CakePHP 2.X website and have no prior experience with CakePHP so please forgive me if this is a stupid question.
I was looking at making some changes to some vendor files and noticed that we appear to have multiple copies of various files (which are, for the most part, identical) in 2 different places:
app/webroot/api/vendor/API/lib/
vendors/API/lib/
Additionally I noticed there are several other vendor directories in various other places.
I am using App::import('Vendor', 'example', array('file' => 'API/lib/example.php')); to load the scripts in question.
Could someone please explain to me what the best practices are regarding file structure relating to vendor files? Additionally, am I safe to delete the duplicate copy of all the files? How does CakePHP know which copy to load?
Edit:
I have come to the conclusion that the files are being loaded from vendors/API/lib/ rather than app/webroot/api/vendor/API/lib/, is it possible that the files in the latter location are redundant? I cannot seem to find any references to them.
Well as Sudhir has commented you, there is a folder in your app project which is called Vendor. I would recommend you to put it there.
app > Vendor
For example, I have created a folder called Csv for generating my own csv files through a Shell which is launching them. It is located inside app > Vendor > Csv
For importing this to my projects, I did the next for being able to use it:
<?php
include('GenericShell.php');
require_once(ROOT . DS . 'app' . DS . 'Vendor' . DS . 'Csv' . DS .
'CsvGenerator.php');
class CsvPatientsShell extends GenericShell {
That's one only example with PHP.
One other one would be, if in this case you have a Component which is called component.php and you want to import it to a Controller which you use frequently inside your project :
Component would be located into
Controller > Component > Namecomponent.php
The next thing you would have to do would be to do the import likewise inside your controller:
Let's say your controller's name is NameController.php and is located inside the Controller folder.
Controller > NameController.php
public function main_function() {
App::import('Component', 'Namecomponent');
$NameComponent = new NameComponent();
$this->layout = null;
$this->autoLayout = false;
die();
}
That would be a more correct way to do it with CakePhp but both mentioned are legit I'd say.
I hope that will help you somehow.
I am trying to accomplish something which I think is getting beyond my current PHP skills!
I have working code in a Magento .phtml template file that calls an external PHP class e.g.
$ExternalLibPath=Mage::getModuleDir('', 'My_Module') . DS . 'lib' . DS .'class.authentication.php';
require_once ($ExternalLibPath);
$myauth = new Authentication();
$credentials = $myauth->get("account_credentials");
echo "Connecting as " . $credentials->user_name ;
(In the .phtml file the classes are called from an include). I'm trying to move the code from the frontend template files to a Magento module/extension with a class triggered on an event. My module works fine up until the external classes are accessed where trying to access *$credentials->user_name* causes an Undefined property: stdClass: error.
I don't understand why the code works in a .phtml template and not in the module, or what I am doing wrong!
Any help would be appreciated.
Pete.
You should call the class directly from the phtml:
$credentials = Mage::getModel('namespace/custom_class')->getAccountCredentials();
and return whatever you need to.
Ok I think I am pushing my self to far here, I'm createing a project in my own MVC even I don't know what MVS is itself,
<?php
class init
{
function __construct()
{
$this->enviroment();
$this->start();
}
function enviroment()
{
/* Required Classes */
require_once( ROOTPATH . BOOTSTRAP . REDENGINE . '/class.debug.php');
require_once( ROOTPATH . BOOTSTRAP . REDENGINE . '/class.theme.php');
require_once( ROOTPATH . BOOTSTRAP . REDENGINE . '/class.url.php');
require_once( ROOTPATH . BOOTSTRAP . REDENGINE . '/language/class.lang.php');
require_once( ROOTPATH . BOOTSTRAP . REDENGINE . '/class.sessions.php');
}
function start()
{
/* Start Classes */
$uSys = new Urlsystem;
$fragments = $uSys->getFragments();
$tSys = new ThemeSystem;
$lSys = new LanguageSystem;
$sSys = new Sessions;
/* defineing APPVIEWS & APPCONTROLLER */
define( 'APPVIEWS', '/appviews' );
define( 'APPCONTROLLER', '/appcontroller' );
if ( empty($fragments) )
{
require_once( ROOTPATH . APPCONTROLLER . '/app.home.php'); /* default app controller page */
require_once( ROOTPATH . APPVIEWS . '/view.home.php'); /* default app views page */
}
if ( !empty($fragments) )
{
// Start ENGINE
if ( !file_exists(ROOTPATH . APPCONTROLLER . '/app' . $fragments . '.php') &&
!file_exists(ROOTPATH . APPVIEWS . '/view' . $fragments. '.php')
) {
if ( file_exists(ROOTPATH . APPCONTROLLER . '/app.404.php') &&
file_exists(ROOTPATH . APPVIEWS . '/view.404.php')
) {
require ROOTPATH . APPCONTROLLER . '/app.404.php';
require ROOTPATH . APPVIEWS . '/view.404.php';
}
else {
echo "NO 404 APP || VIEW";
}
}
if ( file_exists(ROOTPATH . APPCONTROLLER . '/app' . $fragments . '.php') )
{
require ROOTPATH . APPCONTROLLER . '/app' . $fragments . '.php'; // load application
if ( file_exists(ROOTPATH . APPVIEWS . '/view' . $fragments . '.php') ) {
require ROOTPATH . APPVIEWS . '/view' . $fragments . '.php';// load view
}
}
// End ENGINE
}
}
} ?>
Ok, as you see my front controller, so I know it's failing, I just notice my fail after I nearly finish my project, especialy when I need to do www.someurl.com/?$getuser or www.someurl.com/myname or a user.
Anyway my question is when do we really need MVC for PHP?
I'm looking at facebook, etc
They still use the ?this=blabla get so they are not MVC , is that right? Anyway I'm still confused how facebook does www.facebook.com/myname without it. ( htaccess ? )
If they don't use MVC then when do we really need it?
Note :
I've read many thread about when use MVC, but I haven't found one in my problem, if there is please leave a comment so I can read :)
Thanks a lot.
I believe you are confused between MVC and having RESTful URL scheme (http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services).
MVC is just a coding pattern that separates entities and modules. Like Application Logic from GUI Templates while The URL pattern is a different thing altogether. URLs are just to access a Web Resource. MVC frameworks like CodeIgnitor can still give you 'ugly' URLs if you do not work it out with .htaccess
MVC is an architectural pattern focused on separation of concerns; the URL's have nothing to do with it.
URL's are handled by the server. If it's Apache you are using, set up mod_rewrite.
That being said, you might want not to reinvent the wheel, but look at options available out there, there are plenty of MVC-oriented PHP frameworks. Find one that you like and can be productive in and use it.
I think you're confusing MVC with query params. The two are not necessarily linked, though it is true that the more popular PHP MVC frameworks do mask the params by using mod_rewrite or an equivalent method.
MVC is simply a way to keep your presentation logic separate from your business logic. Think of it this way: if you have a site using MVC, you can easily create a mobile phone version by simply changing the views based on the browser, your site's logic doesn't need to change, just the HTML that is sent to the client.
It seems that your question is confusing two different topics together. Model View Controller(MVC) and pretty URLs.
Model View Controller is a design paradigm which allows you to separate your logic(model), your templates(views), and your directing input/output(controller).
Pretty URLs on the other hand, allow for redirecting urls based on format rules(typically .htaccess rules).
Model-View-Controller - design paradigm information.
Pretty URLs tutorial - implementation of using Apache's mod_rewrite.
mod_rewrite - information on what a rewrite engine is.
Saving your code, HTML, and data in different folders is the most basic way of structuring your application - and that's the primary reason for implementing MVC: organization.
The other design patterns present in most frameworks supplement MVC, and they promote code reuse, rapid development, etc. But you can do the latter even without MVC - all it takes is a code library! Most frameworks utilize the MVC design pattern, but MVC != frameworks.
Some frameworks require you to tweak Apache (Lighty, Nginx, etc) to make it a framework extension. Pretty URLs are just a way of presenting input data (view) that are consumed by the controller so the latter can route to the appropriate handler. Seen in this light, .htaccess is an integral part of MVC for such frameworks.
Before you plunge deeper into your project, it helps to do a little more research. Most frameworks have taken the convoluted approach to MVC, which have led many to confusion. Fat-Free Framework uses a more direct and easier-to-follow path.
you might consider starting by using one of the many different MVC frameworks out there, such as CodeIgniter or cakePHP. These frameworks have bene developed by many pople and refined over a period of time. MVC is not necessary, but once the boilerplate is established, creating web applications is very fast.
When to use... All the time, is a good practice.
Personally, my choice: Symphone and Doctrine can easier to write big applications by team. But began with CodeIgniter.
You are really making it hard on yourself by attempting to writing your own mvc. (You are not doing it by manipulating the URL scheme). While it is a good educational experience to write one yourself, you will not get the level of quality and the benefits of the MVC pattern by reinventing the wheel.
Write your app in symfony, zend, codeigniter cake or any of the good open source MVC frameworks out there. When you get a feel for how it should work, then you should create your own for fun.
These frameworks exist to make your projects faster to code and more maintainable.
Searched stackoverflow for this and found no answer
Coming from Ruby On Rails and Rspec, I need a tool like rspec (easier transition). Installed it through PEAR and tried to run it but it's not working (yet)
Just wanna ask around if anyone's using it have the same problem, since it's not running at all
tried running it with an example from the manual - http://dev.phpspec.org/manual/en/before.writing.code.specify.its.required.behaviour.html
phpspec NewFileSystemLoggerSpec
returns nothing
even running
phpspec some_dummy_value
returns nothing
Development on PHPSpec has restarted since August 2010, after a 2 years break. The code base looks more stable now. I would give another try.
The website is now located at www.phpspec.net
You can find the documentation at http://www.phpspec.net/documentation. It is basically an update of the first version.
Should you require any further assistance you can also reach the developers through their mailing list:
http://groups.google.com/group/phpspec-dev
I also couldn't get it to run, but you can also use BDD with PHPUnit. Check the documentation:
Was really looking forward to using PHPSpec, oh I guess will check into PHPUnit
I tried using phpspec but found it too buggy/immature. I can highly recommend SimpleTest for writing unittests.
You can write RSpec-ish types of tests in PHPUnit, but it's hindered by a couple of things.
PHPUnit mocks don't let you
re-declare them so it's hard to set
up a bunch of stubs in a before
method and then override them as
needed. You can work around this by
arranging for the stubs to be setup
after the expectations, but it's odd.
PHP isn't as dynamic as Ruby so you
can't easily mock or stub out class
methods unless you specifically
design the class for this and even
then it's pretty ugly. (This may
change with PHP 5.3's late static
binding features).
I have used PHPSpec succesfully but it's not actively developed now is it? It's great but don't think I would go with a stalled project. Anyway to the point I used the following setup to run the tests from the webbrowser, maybe you'll find something to help you to set it up for CLI.
PHPSpecConfiguration.php
$projectDir = realpath( dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' ) . DIRECTORY_SEPARATOR;
$simdal_root = $projectDir . 'library';
$phpspec_root = $projectDir . '..' . DIRECTORY_SEPARATOR . 'PHPSpec';
$mockery_root = $projectDir . '..' . DIRECTORY_SEPARATOR . 'Mockery';
$paths = array(
'SimDAL'=>$simdal_root,
'PHPSpec'=>$phpspec_root,
'Mockery'=>$mockery_root
);
set_include_path( implode( PATH_SEPARATOR, $paths ) . PATH_SEPARATOR . get_include_path() );
require_once 'PHPSpec.php';
require_once 'Mockery/Framework.php';
class Custom_Autoload
{
public static function autoload($class)
{
//$path = dirname(dirname(__FILE__));
//include $path . '/' . str_replace('_', '/', $class) . '.php';
if (preg_match('/^([^ _]*)?(_[^ _]*)*$/', $class, $matches)) {
include str_replace('_', '/', $class) . '.php';
return true;
}
return false;
}
}
spl_autoload_register(array('Custom_Autoload', 'autoload'));
and then the file that runs it all: AllSpecs.php;
require_once 'PHPSpecTestConfiguration.php';
$options = new stdClass();
$options->recursive = true;
$options->specdocs = true;
$options->reporter = 'html';
PHPSpec_Runner::run($options);
I don't like CLI testing...But this might help someone.
Hello its pretty old Q. in deed, but i think http://behat.org/ should be here. Everyone has this problem should check it out.
Note that PHPSpec is discontinued:
http://blog.astrumfutura.com/2010/05/the-mockery-php-mock-objects-made-simple/#comment-88628508
the directory structure I'm trying to achieve would be this:
application/default/views/layouts/layout.phtml
application/default/views/scripts/index/index.phtml
application/admin/views/layouts/layout.phtml
application/admin/views/scripts/index/index.phtml
library/Zend
config/config.ini
public/index.php (bootstrap)
but I can't figure out how to let Zend find my layout.phtml in each of my modules.
in my bootstrap I have:
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application/'));
define('APPLICATION_ENVIRONMENT', 'testing');
//setup path to our library files
set_include_path( APPLICATION_PATH . '/../library' . PATH_SEPARATOR .
get_include_path() );
//register the autoloader
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
//set config in the registry
$config = new Zend_Config_Ini( APPLICATION_PATH . '/../config/config.ini', APPLICATION_ENVIRONMENT );
Zend_Registry::set('config', $config);
//setup logging
$writer = new Zend_Log_Writer_Stream(APPLICATION_PATH . '/../log/debug.log');
$logger = new Zend_Log($writer);
Zend_Registry::set('logger', $logger);
//run!
$frontController = Zend_Controller_Front::getInstance();
$frontController->addModuleDirectory(APPLICATION_PATH);
//initialize Zend_Layout's MVC helpers
Zend_Layout::startMvc();
$frontController->throwExceptions(true);
try {
Zend_Controller_Front::getInstance()->dispatch();
} catch (Exception $exception) {
echo '<html><body><center>' . 'An exception occured while dispatching the front controller.';
if (defined('APPLICATION_ENVIRONMENT') && APPLICATION_ENVIRONMENT != 'production' ) {
echo '<br /><br />' . $exception->getMessage() . '<br />' . '<div align="left">Stack Trace:' . '<pre>' . $exception->getTraceAsString() . '</pre></div>';
}
echo '</center></body></html>';
exit(1);
}
Where am I going wrong?
Update:
I haven't looked at this in a long time, so the accepted solution may not be up-to-date. If anyone wants to post a more up-to-date solution to this question (i.e. ZF 1.8+), please do so! It would be helpful to others who are looking for a solution to this.
You should check out Per Module Zend_Layout, in this article, the author covers exactly what you are trying to achieve. His methodology is to write a plugin for the front controller that handles layout registration.
Using Zend Framework 1.12 (Haven't tested it on previous versions): works out of the box!
I usually use application.ini to setup things so, in orther to enable layouts:
resources.layout.layout = "layout"
...or whatever the default layout should be called. As "layoutPath" has not been defined Zend_Layout will look into "Application/modules//views/scripts" for a file called "layout.phtml"
If you use zend tool it will start layouts with the following line:
resources.layout.layoutPath = APPLICATION_PATH "layouts/scripts"
This is also fine, just delete the directory or avoid creating the default "layout.phtml". If the default layout is not found in that directory it will look into de modules as before for the "layout.phtml" inside "Application/modules//views/scripts".
If the layout is not found inside a module it will load the layout of the default module.
As simple as that!
If you need some extra work with your template you can add a plugin to it for example:
resources.layout.pluginClass = "YourLibrary_Controller_Plugin_Layout"
and do some extra stuff inside it.