I'm working on the Doctrine tutorial at http://www.Doctrine-project.org/ and I receive a fatal error when I try to run my generate.php script which makes my models and makes tables in the database:
Fatal error: Class 'BaseCharity' not found in ...\models\Charity.php on line 14
generate.php:
require_once('bootstrap.php');
Doctrine_Core::dropDatabases();
Doctrine_Core::createDatabases();
Doctrine_Core::generateModelsFromYaml('schema.yml', 'models');
Doctrine_Core::createTablesFromModels('models');
and schema.yml
Charity:
actAs: [Timestampable]
columns:
active:
type: boolean
default: '1'
owed: decimal(32,2)
totalPayed: decimal(32,2)
name: string(255)
website: string(255)
description: text
icon: string(255)
I am quite stumped by this, I can get it to correctly create other tables that are very similar or much more complicated then this one. I've tried rewriting it as well. I really have no clue where this error is coming from.
You need to register the models with the autoloader provided by Doctrine. No need to use any Iterators or what so ever
Doctrine::loadModels('path/to/your/models');
You can of course use it sevaral times:
Doctrine::loadModels('path/to/your/models/generated');
Doctrine::loadModels('path/to/your/models/custom');
Doctrine::loadModels('path/to/your/models');
Found this:
http://www.doctrine-project.org/jira/browse/DC-344
Hi, I've stumbled upon the same
problem and I think I know where the
issue is.
So
Doctrine_Core::createTablesFromModels()
calls Doctrine_Export::exportSchema()
which in turn calls
Doctrine_Core::loadModels().
Doctrine_Core::loadModels() uses
RecursiveIteratorIterator and iterates
over all found files.
Now I think the order of files
returned by RecursiveIteratorIterator
is not always the same (depends on OS,
filenames and cosmic radiation ), but
the most important thing here is that
class files from 'modules/generated'
directory (as in examples) ARE NOT
included before subclasses derived
from generated classes. This means
that Doctrine_Core::autoload() fails
to load classes from
'modules/generated' directory, exactly
this check fails:
if (0 !== stripos($className,
'Doctrine_') ||
class_exists($className, false) ||
interface_exists($className, false))
as base class is not starting with
'Doctrine_' and is not yet loaded.
To fix it properly the algorithm for
loading modules must be changed to
first include 'modules/generated'
classes and then rest of classes. I am
not sure but maybe Core::autoload()
might be changed to include base
classes properly.
QUICK WORKAROUND: As a quick
workaround I've changed parameters in
call to createTablesFromModels() to:
Doctrine_Core::createTablesFromModels(array('models/generated','models'));
as createTablesFromModels() can accept
array of directories.
Hope this helps you, please let me
know if you need any more information.
Thanks!
Related
I'm in the process of trying to make a laravel compatible composer/packagist package. I'm using Laravel 5.5.
I've created a package : floor9design/machine-identifier. Composer downloads this to vendors/floor9design fine, but despite reading/googling how to do this, I'm unsure of how to include this in my laravel projects.
PHP Storm is correctly picking up the class, auto-completing as expecting.
I have not modified any files so far. If I add the following to a controller:
use Floor9design\MachineIdentifier\MachineIdentifier;
(alongside some class usage on the page).
PHP storm autocompletes this (as it does with other classes validly called).
When I try to load this, the following error comes:
Class 'Floor9design\MachineIdentifier\MachineIdentifier' not found
I've had a look round plenty of tutorials, and this final step seems to be missing from a lot of information.
I realise there are three approaches:
Firstly:
Direct include_once, which while working, is not the normal approach
Secondly:
Pre-laravel 5.5 approach (add something to app.php)
Thirdly
Laravel 5.5 approach and up, autodetection of something.
I've deliberately said something as the documentation seems to speak about ServiceProviders, and I simply don't get how they work.
Let me rephrase this into a question and a follow up question:
Question: apart from include_once, how do I load the MachineIdentifer class from floor9design/machine-identifier in Laravel.
Question 2: If the answer is via a service provider, can you simply explain how they relate to one another.
Thanks
Answer (as accepted below)
On the composer repo I was incorrectly specifying the PSR4 namespace, which is now corrected to:
"autoload": {
"psr-4": {
"Floor9design\\MachineIdentifier\\": "src"
}
}
The previous namespace had a -, which is an illegal character. Many thanks to lawrence-cherone.
Your PSR4 is wrong in the package
floor9design\\machine-identifier\\": "src"
Will cause the composer/autoload_psr4.php to map to:
'floor9design\\machine-identifier\\' => array($vendorDir . '/floor9design/machine-identifier/src'),
Which is not a valid class namespace.
You should change the PSR4 to match your class namespace:
Floor9design\\MachineIdentifier\\": "src"
Once you fix that you will be able to use it like normal from anywhere in your project.
I get the following error when running:
class page_generator extends Page_SchemaGenerator {
}
Application Error: requires jQuery or jUI support
BaseException, code: 0
C:\projects\wamp\atk4\atk4\lib\Form\Submit.php:33
Where did you get such class? What version of ATK4 are you using?
Anyway, you have to add jUI class iun your Frontend class.
Sorry, but I couldn't remain silent and will say that - schema generators are evil !!! :)
There are only very rare case when they are OK. One of such cases is if you actually require dynamically changeable DB structure. If that's the case, then better use this add-on: https://github.com/atk4/atk4-addons/tree/master/dynamic_model
Add the following to your lib/Frontend.php
$this->add('jUI');
And as #DarkSide said - schema generators are evil.
There is also on-the-fly generator controller for model:
https://github.com/atk4/atk4-addons/tree/master/dynamic_model
We have used Zend_Log, which is configured in application.ini differently for different circumstances. We initialize it/get it in the bootstrap and store it in the registry:
$r = $this->getPluginResource('log');
$logger = $r->getLog();
But we've subclassed Zend_Log (say, Our_Log) to add customized features, and want to get it the same way. So then we have to make a new Resource Plugin. That seems quite easy - just copy Application/Resource/Log.php, rename the file to Ourlog.php, rename the class to class Zend_Application_Resource_Ourlog. For now, let's not worry about "Our_Log", the class -- just use the new Resource Plugin to get a Zend_Log, to reduce the variables.
So then, our new code in the bootstrap is:
$r = $this->getPluginResource('ourlog');
$logger = $r->getLog();
but of course this doesn't work, error applying method to non-object "r". According to the documentation,
"As long as you register the prefix path for this resource plugin, you
can then use it in your application."
but how do you register a prefix path? That would have been helpful. But that shouldn't matter, I used the same prefix path as the default, and I know the file is being read because I "require" it.
Anyway, any guidance on what simple step I'm missing would be greatly appreciated.
Thanks for the pointers -- so close, so close (I think). I thought I was getting it...
Okay, so I renamed the class Xyz_Resource_Xyzlog, I put it in library/Xyz/Resource/Xyzlog.php
Then, because I don't love ini files, in the bootstrap I put:
$loader=$this->getPluginLoader();
$loader->addPrefixPath('Xyz_Resource','Xyz/Resource/');
$r = $this->getPluginResource('xyzlog');
if (!is_object($r)) die ('Not an object!!');
Sudden Death. So, okay, do the ini:
pluginPaths.Xyz_Resource='Xyz/Resource/'
The same. No help. I believed that the basepaths of the plugin paths would include the PHP "include" paths. Am I mistaken in that? Any other ideas? I'll happily write up what finally works for me to help some other poor soul in this circumstance. Something to do with Name Spaces, maybe?
Plugin classes are resolved using the plugin loader, which works slightly differently to the autoloader; so just requiring the class in doesn't help you here. Instead, add this to your application.ini:
pluginPaths.Application_Resource = "Application/Resource"
you should then be able to use the class as normal. Since your path above will be checked before the default Zend one, you can also name your class 'Log' and still extend the Logger resource to override the standard functionality.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Call to a member function on a non-object
I'm doing this tutorial here:
http://tv.cakephp.org/video/webtechnick/2011/01/12/nick_baker_--_facebook_integration_with_cakephp
I baked a new project with cake bake facebook_app and set the configuration database file to the correct settings and the default cakePHP screen showed that tmp directory was writable, DB setup was good, etc.
I downloaded the CakePHP plugin by WebTechNick here: https://github.com/webtechnick/CakePHP-Facebook-Plugin, and filled out app information (app_secret, app_id, etc), adding it to facebook_app/config/facebook.php
Changed facebook_app/app_controller.php:
class AppController extends Controller {
var $name = 'Facebook';
var $helpers = array('Session', 'Facebook.Facebook');
}
Then just exactly as in the tutorial `facebook_app/views/pages/home.ctp':
<h1>Facebook_App</h1>
<?php $this->Facebook->share(); ?>
returning the error message:
Undefined property: View::$Facebook
I realize that means PHP didn't recognize Facebook as an object. But I installed the plugin!
Also, it seems not MVCish to have something like $this->Facebook->share(); in a view (home.ctp). However, this is exactly how WebTechNick does it in his tutorial (I followed it exactly 3x) and it does not work for me. I'm a complete noob at cakePHP (although I've read the entire documentation) and I'm just trying to learn and understand through examples.
:) To be fair, it's PHP - you didn't install anything. Or if you prefer, "install" != "invoke." PHP is really amazingly easy to debug. I mean, it tells you exactly what's wrong:
Like turning to a channel that's not on the air, the error your getting means that the object you're calling doesn't actually exist, at least not in the scope you're trying to invoke it.
Is that your IDE? Is it set up for your Cake app? Are you sure the instructions were to set your AppController's $name to 'Facebook' instead of $name = Facebook_App in your AppController? It looks like you either replaced your actual app's AppController with the plugin files instead of putting them in the proper directory, or the plugin is not deferring / calling / extending / returning to the application the way it's supposed to. Knee jerk -> typo, naming conflict, path problem, permissions.
Cake's not even rendering. I can tell because your screenshot would show that error with the styled Cake errors. That tells you it's erroring before AppController class makes it to View class.
Create an instance of the Facebook object statically in the view and see what happens. Then, what does
function beforeFilter() {
parent::__construct() ?
}
get you? Anything? What about debug(), var_dump, the object functions will also shed light on what's happening. So will your logfiles.
Btw, if you don't use them already: Firefox + FirePHP + Xdebug = made of win.
I was having this problem and I found that the plugin I was using was for CakePHP 1.3 and I was using Cake 2.0. I found the BETA branch for the upgraded Cake 2.0 and it worked perfect.
Here is the Cake 2.0 BETA Branch
So I recently discovered that the log4* package was available for PHP and upon seeing this eagerly downloaded the latest from the log4php website and followed the installation instructions. The instructions indicate that one is to download the tar package, untar, and place the following directory in a place of one's choosing: log4php/src/main/php
Therefore I copied the contents of log4php/src/main/php into my lib dir under lib/log4php.
In my script, as required, I required the 'Logger.php' class and indicated a properties file to manage my appenders. The properties file, log4php.properties, is located on my filesystem at "/home1/ioforgec/www/devlab/pnotes/config/log4php.properties".
Here is the logfile content:
#
# Example Logger
#
log4php.appender.EA1 = LoggerAppenderConsole
log4php.appender.EA1.target = STDOUT
log4php.appender.EA1.layout = LoggerLayoutPattern
log4php.appender.EA1.ConversionPattern = "%m"
log4php.appender.EA1.threshold = FATAL
log4php.exampleLogger = FATAL, EA1
So here is a copy of my script that implements (more or less 'wraps' the log4php functionality):
<?php
require_once('/home1/ioforgec/www/devlab/pnotes/lib/log4php/Logger.php');
class LogUtil
{
public $logger;
public $properties_file = "/home1/ioforgec/www/devlab/pnotes/config/log4php.properties";
public static function logExample($msg)
{
Logger::configure($properties_file);
$logger = Logger::getLogger("example");
$logger->debug("Shouldnt see this print because of config max level FATAL");
$logger->fatal($msg);
}
}
?>
In order to test that this is working properly, the following script calls the LogUtil.php shown above:
#!/usr/bin/php
<?php
require_once("lib/utils/LogUtil.php");
LogUtil::logExample("example message");
?>
So, despite configuring the example logger to format the messages as the plain message, despite setting the level of the logger to a max of FATAL, not only in the logger declaration but also in the threshold command, the print to the console looks to me like the default root logger:
Mon Oct 18 20:30:05 2010,705 [827] DEBUG example - Shouldnt see this print because of config max level FATAL
Mon Oct 18 20:30:05 2010,711 [827] FATAL example - example message
I see the print statement without the plain formatting as specified, and I see two print statements, the debug print (which should never have printed due to the setting of FATAL on the logger config - FATAL is MUCH higher than DEBUG)
What on earth am I doing wrong? Ive tried every combination of setup I can possibly think of. Does anyone have any suggestions?
Edit - Update - This is still an issue. No progress.
Edit2 - Really? Has no one on this forum tried to use this very popular logging package and its incarnation as a PHP module?
I have tried every conceivable avenue to try and get my question answered, including the log4php user's mailing list.
After many many more hours of manipulating the configuration file I have discovered a small, yet critically important factoid. In order to specify a 'logger' you must name it under the 'logger' hierarchy and its appenders under the 'appender' hierarchy, etc etc. For example:
# for the 'console' logger named 'example' we first define the appender:
log4php.appender.consoleAppender = LoggerAppenderConsole
log4php.appender.consoleAppender.target = STDOUT
log4php.appender.consoleAppender.layout = LoggerLayoutSimple
# we then assign the appender and the minimum log level to the logger:
log4php.logger.example = WARN, consoleAppender
My mistake was in seeing the root logger hierarchy name 'log4php.rootLogger' and assuming that in order to assign a logger one need only name a value for 'log4php.lognameLogger'. Sadly this is no excuse as there was an example, buried, in the documentation. I suppose finding it at 9+ hours is better than not at all :)
Thanks to those who reminded me that there was more debugging work to be done, I appreciated the reminder to keep trying