colinmollenhour / magento-mongo

MongoDb abstraction layer and atomic job queue for Magento
Other
124 stars 50 forks source link

Call to a member function selectCollection() on a non-object #12

Closed planet001 closed 10 years ago

planet001 commented 10 years ago

Dear colin, I have a error like that when I click enumerators on menu, please give me some suggests? Fatal error: Call to a member function selectCollection() on a non-object in C:\xampp\htdocs\magento\app\code\community\Cm\Mongo\Model\Resource\Collection\Abstract.php on line 49 Thanks

colinmollenhour commented 10 years ago

Does lib/Mongo exist? The mongodb-php-odm repo is included as a git submodule.

planet001 commented 10 years ago

Yes, In Mongo lib folder, it has already two files Collection.php and Database.php, but it's still not working

colinmollenhour commented 10 years ago

Indexer issue fixed in c6ac4e7.

planet001 commented 10 years ago

Thanks Colin! how about Fatal error: Call to a member function selectCollection() . Do you have any ideas?? Its quite uncomfortable for me :(

colinmollenhour commented 10 years ago

No ideas. Please try using a a debugger and post more info if there is a bug.

planet001 commented 10 years ago

Can you give me config.xml sample to connect to mongodb, I don't know what's the reason why my config can't get collection name in my mongodb when I called selectCollection. I trying to execute with your enumerations example. I've created a collection name "enums" and three documents: name (string), defaults(array), stores(array). I'm sorrry I just begin with mongodb and disturbing you.

colinmollenhour commented 10 years ago

You should not modify and files in the Cm_Mongo extension, only add your own extension. The collection name comes from mongo.xml. E.g. the collection name for the 'mongo/enum' resource is found in mongo.xml under /mongo/enum/collection.

The connection config should go in local.xml, but unless you want to change the defaults it is actually not necessary to even modify local.xml at all. The defaults are here: https://github.com/colinmollenhour/magento-mongo/blob/master/code/etc/config.xml#L18

planet001 commented 10 years ago

Hi Colin I try this many ways, many time but not working for me, I don't know what the reason why. Can you review my code?? I very grateful if you help me. This links below which is simple demo for integrate mongodb, please review what happened in my code. Many thanks for your enthusiasm. http://www.mediafire.com/download/bggg9gifjfstef3/Test.rar

colinmollenhour commented 10 years ago

Please do a fresh Magento install to a new directory. After verifying hte new installation works please clone this module using modman and flush the cache. With no configuration changes (assuming your db is listening on the default port on localhost with no password required) it should just work. If this doesn't work then please report back.

kamilw-ed commented 10 years ago

Hi! I am getting the same error as @planet001. When I try to open Enumerations grid in Magento admin I also get this error:

Call to a member function selectCollection() on a non-object in /home/kamil/Work/Projects/dev/magento-mongo/code/Model/Resource/Collection/Abstract.php on line 49

I have done some debugging and here is the result of it. Cm_Mongo_Model_Resource_Collection_Abstract::__construct()

$this->_conn = $this->getResource()->getReadConnection();
$this->_query = $this->_conn->selectCollection($this->getCollectionName()); //This is faulty line 

The $this->getResource()->getReadConnection(); is returning false. It seems that Magento cannot initialize the mongo_setup connection properly. Class Mage_Core_Model_Resource is used by Magento to initialize every connection for each module. There is a method _newConnection() that is responsible for this initialization. Inside this method Magento wants to load the database adapter:

$className  = $this->_getConnectionAdapterClassName($type);

So, lets looks at the body this method:

protected function _getConnectionAdapterClassName($type)
{
    $config = Mage::getConfig()->getResourceTypeConfig($type);
    if (!empty($config->adapter)) {
        return (string)$config->adapter;
    }
    return false;
}

As you can see it will load the config for a particular connection type. Default Magento connection type is pdo_mysql, whereas for this extensions it is mongo. Magento will load the config from module config.xml and general local.xml

Here's the relevant part of config.xml of Cm_Mongo:

<resource>
    <connection>
        <types>
            <mongo>
                <class>Cm_Mongo_Model_Resource_Type_Mongo</class>
            </mongo>
        </types>
    </connection>
</resource>

It is clear that the database adapter is missing! If you look at app/etc/config.xml you will see this:

<resource>
    <connection>
        <types>
            <pdo_mysql>
                <adapter>Magento_Db_Adapter_Pdo_Mysql</adapter>
                <class>Mage_Core_Model_Resource_Type_Db_Pdo_Mysql</class>
                <compatibleMode>1</compatibleMode>
            </pdo_mysql>
        </types>
    </connection>
</resource>

So, is the adapter really missing or is config not fully implemented? Magento expects the adapter to be an instance of Varien_Db_Adapter_Interface but I can't it being used anywhere in your extension.

Could you please tell me what am I missing? Otherwise you did a really great job and I'd really like to use this extension. Tested on Magento EE 1.13, though I have checked the body of Mage_Core_Model_Resource class and it is the same for all CE and EE versions since 1.6 and 1.8 respectively.

Kind regards

PS.I have all dependencies downloaded and present in lib

colinmollenhour commented 10 years ago

Ahh yes, these lines were added at some point in Magento core:

        if (!$connection instanceof Varien_Db_Adapter_Interface) {
            $connection = false;
        }

I see in my old project we had overridden Mage_Core_Model_Resource to remove these lines and that change was never added to this repo.. So if you remove those lines it will work..

I have added a patch for this (branch:fix-getconnection) that relies on an updated mongodb-php-odm that uses Late Static Binding (PHP 5.3+). I think this should work but don't have a test envronment setup right now so please test it and let me know before I merge it into master.

Remember, after you checkout the test branch you must use git submodule update to get the test branch in the submodule as well or this patch will not fix the issue.

kamilw-ed commented 10 years ago

I can confirm that when I patched Mage_Core_Model_Resource and checked out that fix-getconnection branch it started to work properly. However, class Cm_Mongo_Model_Resource_Type_Shim is not implementing all of the interface methods, so I had to add them. As I mentioned it earlier, I am using Magento EE 1.13.

Missing methods are:

Thanks!

P.S. Actually, because Shim class implements Varien_Db_Adapter_Interface we don't need to remove that if condition from Mage_Core_Model_Resource

colinmollenhour commented 10 years ago

Yes, the shim was intended as an alternative to avoid patching Mage_Core_Model_Resource.

colinmollenhour commented 10 years ago

Merged getConnection fix. Thanks for testing.