Anyone can enighten me, i am new to Yii. I have 3 tables
projects (id,name,status,created_by)
users (id,name)
project_users (id,project_id,user_id)
The condition is: Show all projects if created by current user or current user is a project member. I have already a working code for this.
$criteria=new CDbCriteria;
$criteria->join = ' LEFT JOIN project_users pu ON pu.project_id=t.id';
$criteria->addCondition('created_by='.Yii::app()->user->id.' OR pu.user_id='.Yii::app()->user->id);
$criteria->distinct = true;
$dataProvider=new CActiveDataProvider('Project',
array(
'pagination'=>array('pageSize'=>15),
'criteria'=> $criteria
)
);
But, id like to learn how can i get same result using "WITH" (relational AR query in Yii). I already tried but all failed. Please help thanks.
the relation on Project model file
projectUsers' => array(self::HAS_MANY, 'ProjectUsers', array('id'=>'project_id')),
$dataprovider should be
$dataProvider=new CActiveDataProvider('Project',
array(
'pagination'=>array('pageSize'=>15),
'criteria'=>array(
'with'=>array(
'projectUsers' => array('alias' => 'pu')
),
'condition' => 't.created_by='.Yii::app()->user->id.' OR pu.user_id='.Yii::app()->user->id,
'distinct'=>true,
'together'=>true,
),
)
);
Check out my picture. The criteria is more powerful than that, but you can understand the basically how to use
Small tip: If everything is new with you, just enable Yii log to see what the query is produced eventually, then you can troubleshoot the problem by yourself.
Related
here is the code that runs and that results in two sentmessage objects getting added to the table:
$sentmessage = null;
//add entry into sent message table Tx_BpsMessagecentre_Domain_Model_Sentmessage
$sentmessage = $this->objectManager->create('Tx_BpsMessagecentre_Domain_Model_Sentmessage');
//now just fill in the object
$sentmessage->setBpsmessageid($bPSMessage->getUid());
$sentmessage->setBody($bPSMessage->getBody());
$sentmessage->setSubject($bPSMessage->getSubject());
$sentmessage->setCouponlist($bPSMessage->getCouponlist());
$sentmessage->setHallname($bPSMessage->getHall()->getHall());
$sentmessage->setHalladdress($bPSMessage->getHall()->getAddress());
$sentmessage->setHallurl($bPSMessage->getHall()->getUrl());
$sentmessage->setBanner($bPSMessage->getBanner());
$this->sentmessageRepository->add($sentmessage);
$this->objectManager->get('Tx_Extbase_Persistence_Manager')->persistAll();
die; //if I take out this die and the persist call above I still get two records added
I am using typo3 v 4.5.32 with extbase 1.3.
The sentmessage object is one I had to create manually - ie without extension builder, so there might be some misconfiguration in the TCA somewhere but I have no idea what would cause this.
Thanks
PS: a piece of my ext_localconf.php showing some of my plugins
Tx_Extbase_Utility_Extension::configurePlugin(
$_EXTKEY,
'Bpsmonthly',
array(
'BPSMessage' => 'cronMonthlys'
),
// non-cacheable actions
array(
'BPSMessage' => 'create, update, delete',
)
);
Tx_Extbase_Utility_Extension::configurePlugin(
$_EXTKEY,
'Bpsbirthdays',
array(
'BPSMessage' => 'cronBirthdays'
),
// non-cacheable actions
array(
'BPSMessage' => 'create, update, delete',
)
);
Tx_Extbase_Utility_Extension::configurePlugin(
$_EXTKEY,
'BpsAnnuals',
array(
'BPSMessage' => 'cronAnnuals'
),
// non-cacheable actions
array(
'BPSMessage' => 'create, update, delete',
)
);
Ok, found the bug, it was actually caused by my debug code that spit some url out to the page, the url got resolved by the browser to hit the action again (probably a url in an img tag) and boom. so the bug only exists while debugging. I love programming.
Is there a way to delete my dumbest questions from stackoverflow?
most probably you have the two plugins from the same extension in your website - therefore everything is processed twice.
Maybe persisting your changes takes a loooooong time (e.g., >30 sec). In such cases, I experienced that under some conditions the browser posts again (!) the query, resulting in what you describe.
As I experienced the same behaviour, but under other circumstances, I'm adding my case as an answer here, maybe it helps someone.
If you're working with multiple records in the same form (model having child records) and they all are not persisted, make sure to not set the parent record on the child records.
This will lead to the multiple-rows behaviour:
$foo = ObjectManager->get('Foo\\Bar\\Domain\\Model\\Foo');
$bar = ObjectManager->get('Foo\\Bar\\Domain\\Model\\Bar');
$bar->setFoo($foo); // <-- Should not be done
$foo->add($bar);
I have two data sources
1) Database
2) Memcached or Totally different database
From 1st database I am getting the group members list IDs ( has more than 10 thousand rows) and after getting the list I query second database or hit Memcached to get the actual details
$connection = Yii::app()->db;
$sql = 'select user_id,joined_date from group_data where group_id=:group_id ';
$dataProvider = new CSqlDataProvider($sql, array(
'keyField' => 'user_id',
'sort' => array(
'attributes' => array(
'user_id',
'joined_date'
),
'defaultOrder'=>array(
'user_id ASC',
)
),
'pagination' => array(
'pageSize' => 30,
),
'totalItemCount' => $count,
));
$connection_master = Yii::app()->masterdb;
In the above data provider , I am not sure how to include my second database and get the actual user name since it is in other database .No direct connection from one database to other.
Here the problem is pagination is based on the first database table ( 30 records per page) and the actual data is from second table .
Any idea on how to implement this ?
Thank You
You could build your own custom data provider class. You can extend it from CDataProvider and implement the missing abstract methods:
abstract protected function fetchData();
abstract protected function fetchKeys();
abstract protected function calculateTotalItemCount();
Notice, that your storage model already comes very close to these methods: You store the IDs in one database and the actual data in another. So you can focus on one DB at a time in each of these methods.
You'd start with fetchKeys(). There you need to query the keys (=IDs) from your second database. Have a look at CSqlDataProvider::fetchData() to see how to use the CPagination object from $this->getPagination() to find out the current limit and offset. If you need sorting you'd also inspect the CSort object from $this->getSort() for current sort settings. With all that data available you should be able to build the query for the IDs on the currently requested result page.
Then in fetchData() you can obtain those keys through $this->getKeys(). You should not call fetchKeys() directly, because with getKeys() the result from fetchKeys() is "cached", so if it's called again later in the same request, there won't be another query. With that keys you now can easily query your main database. The result will represent the rows on the current page.
Finally you have to implement calculateTotalItemCount(). This is very easy again: Just query your second DB for the total number of items.
That's all you need to do - the code in the base CDataProvider class will take care of the rest and call your methods on demand.
I've got the following problem. I built a PHP file, which reads categories from a file, to impor tthem into Magento. I am able to read the file, no problem. The connection via NuSOAP to the Magento API works aswell. I can get the SessionID and I am able to get data, like Information for a category, also its possible to delete categories.
But, whenever I try to create or update anything, it throws an error. The rights for the user are ok aswell. For example, when I create a category, I add the usual data to the call:
$proxy->call(
$sessionId,
'category.create',
$rootCategory, array(
'name' => "TEST",
'is_active' => '1',
'page_layout' => 'two_columns_right',
'description' => "TEST",
'meta_title' => "TEST",
'meta_description' => '',
'meta_keywords' => "TEST",
'include_in_menu' => '0',
'display_mode' => 'PRODUCTS',
'available_sort_by' => 'price',
'default_sort_by' => 'price',
'is_anchor' => '0'
)
);
All the time, it says:
(
[faultcode] => 102
[faultstring] => Category not exists. )
Which is not true. The $rootCategory is definatly a category, which is existing. I tried all other categories, I tried to add a 'path' to the info, I tried to use less information (only the neccesary stuff), I tried to read existing categories to get their IDs, NOTHING works. It always throws this faultcode.
Same happens, when I try to update a category, or create /update a product. Deleting is no problem at all.
Do you see the problem?
i just compared your NON working exemple and i found this while comparing it with another exemple i has ( i do not pretent to be expert ) ..
but seems like your $new_category, array(blahblha) ...
should be INSIDE an array according to the exemple i already have
like this array($new_category,array(blahblah) ...
this is the mains difference i just saw ..
here is the EXEMPLE i just pulled out of the web ... Adapt to your needs..
$proxy->call(
$sessionId,
'category.create',
array(
3,
array(
'name'=>'New openerp',
'is_active'=>1,
'include_in_menu'=>2,
'available_sort_by'=>'position',
'default_sort_by'=>'position')) );
Have you tried specifying the category_id key in your $rootCategory within the call:
$selectedCategory['category_id'],
array('name'=>'New Category Through Soap')
)
Reference: http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_category
We are currently using the Magento API for importing a bunch of products into the store.
But we now run into a problem where some product attributes should be translated into a different language.
And I was wondering if it is possible to do this using the Magento API, because I can't seem to find anything related to that problem.
We currently have 2 store views, 1 for the Dutch version of the site and one for the French version of the site.
Our current import code looks something like this:
$store_id = $soapClient->call($soapSession, 'catalog_product.currentStore', array('nl'));
echo("store_id: $store_id");
$new_product_data = array(
'name' => 'NameInDutch',
'short_description' => 'DescriptionInDutch',
'price' => $price,
'weight' => $weight,
'websites' => array('base'),
'status' => '1'
);
$new_product_id = $soapClient->call($soapSession, 'catalog_product.create', array('simple', 4, $sku, $new_product_data)); // 4 => 'Default' attribute set
$localized_product_data = array(
'name' => 'NameInFrench',
'short_description' => 'DescriptionInFrench'
);
$store_id = $soapClient->call($soapSession, 'catalog_product.currentStore', array('fr'));
echo("store_id: $store_id");
$soapClient->call($soapSession, 'catalog_product.update', array($sku, $localized_product_data ));
Now, the output of the echo statements differs, the first time it's 1 and the second time it's 2, so that doesn't seem to be problem. But apparently it doesn't matter for the API if we set that value.
The result is that on the 'catalog_product.update' call, the name 'NameInFrench' overwrites the default name 'NameInDutch'.
So my question is if something like this is possible using the Magento API, and how one would accomplish this?
Ok, I found the answer, apparently I overlooked a certain line in the Magento API docs, because the solution was right there.
So: you don't need to set the currentStore each time, you just need to append the store id or code to the update array:
$soapClient->call(
$soapSession,
'catalog_product.update',
array($sku, $localized_product_data, 'fr')
);
This works perfectly.
I get the following SQL error:
SQL Error: 1066: Not unique table/alias: 'I18n__name'
when doing a simple find query.
Any ideas on possible situations that may have caused this??
I'm using a bindModel method to retrieve the data is that related?
This is my code:
$this->Project->bindModel(array(
'hasOne' => array(
'ProjectsCategories',
'FilterCategory' => array(
'className' => 'Category',
'foreignKey' => false,
'conditions' => array('FilterCategory.id = ProjectsCategories.category_id')
))));
$prlist = $this->Project->find('all', array(
'fields' => array('DISTINCT slug','name'),
'conditions' => array('FilterCategory.slug !='=>'uncategorised')
))
You have not used or initialized the required table/model you are using in your controller. Use var $uses = array('your_table_name');
I do not have a direct answer to my problem. However after some research I came to the following conclusion.
I've decided to change my methodology and stop using the translate behavior in cakephp.
I've found another behavior called i18n which works much better when dealing with associated models. You can read about it http://www.palivoda.eu/2008/04/i18n-in-cakephp-12-database-content-translation-part-2/#comment-1380
In cakephp book it says :
"Note that only fields of the model
you are directly doing find on will
be translated. Models attached via
associations won't be translated
because triggering callbacks on
associated models is currently not
supported."
I'm not sure if I made the right choice however I have been struggling to get the translate behavior to work in cakephp and this solution at least makes the project I'm working functional.