getItems isn't working in magento - php

I have installed a Magento Product Parts Interactive Diagram Extension in Magento CE 1.8.1.0.
The issue is it only renders one single Part Diagram per product. I need it to render all Diagrams for each product.
The code is :
public function getPartDiagram()
{
if ($this->getId()) {
return Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->load($this->getId());
}
if (Mage::registry('product')) {
$collection = Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->getCollection()
->addFieldToFilter('sku', Mage::registry('product')->getSku());
return $collection->getFirstItem();
}
return null;
}
If I return $collection->getLastItem(); it works and the last item is rendered on the front-end as expected.
But I cannot seem to get all items rendered, getItems does not work.
The code file is as follows, not sure but it might help.
<?php
/**
* Catalog product parts list block
*
* #category PWS
* #package ProductPartsDiagram
* #author Anda Bardeanu <info#pandawebstudio.com>
*/
class PWS_ProductPartsDiagram_Block_List extends Mage_Catalog_Block_Product_Abstract
{
protected $_productsCount = null;
const DEFAULT_PRODUCTS_COUNT = 5;
protected $_columnCount = 4;
protected $_items;
protected $_itemCollection;
protected $_itemLimits = array();
/**
* Initialize block's cache
*/
protected function _construct()
{
parent::_construct();
$this->addColumnCountLayoutDepend('empty', 6)
->addColumnCountLayoutDepend('one_column', 5)
->addColumnCountLayoutDepend('two_columns_left', 4)
->addColumnCountLayoutDepend('two_columns_right', 4)
->addColumnCountLayoutDepend('three_columns', 3);
$this->addData(array(
'cache_lifetime' => 86400,
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
));
if (!$this->getData('template')) {
$this->setTemplate('pws_productpartsdiagram/list.phtml');
}
}
/**
* Get Key pieces for caching block content
*
* #return array
*/
public function getCacheKeyInfo()
{
return array(
'CATALOG_PRODUCT_PARTS_'.$this->getPartDiagram()->getId(),
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->getCustomerGroupId(),
'template' => $this->getTemplate(),
$this->getProductsCount()
);
}
/**
* Prepare collection with new products and applied page limits.
*
* return Mage_Catalog_Block_Product_New
*/
protected function _beforeToHtml()
{
$partDiagramId = -1;
$partDiagram = $this->getPartDiagram();
if ($partDiagram) {
$partDiagramId = $partDiagram->getId();
}
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
$resource = Mage::getSingleton('core/resource');
$productsTable = $resource->getTableName('pws_productpartsdiagram_products');
// no pagination
$collection = $this->_addProductAttributesAndPrices($collection)
->addStoreFilter();
//->setPageSize($this->getProductsCount())
//->setCurPage(1);
$collection->getSelect()
->joinInner(
array('_table_products' => $productsTable),
'_table_products.product_id = e.entity_id',
array()
)
->from("", array('partdidagram_product_id'))
->where('_table_products.partdiagram_id = '. (int) $partDiagramId);
$this->setProductCollection($collection);
$this->_itemCollection = $collection;
return parent::_beforeToHtml();
}
/**
* Set how much product should be displayed at once.
*
* #param $count
* #return Mage_Catalog_Block_Product_New
*/
public function setProductsCount($count)
{
$this->_productsCount = $count;
return $this;
}
public function getPartDiagram()
{
if ($this->getId()) {
return Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->load($this->getId());
}
if (Mage::registry('product')) {
$collection = Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->getCollection()
->addFieldToFilter('sku', Mage::registry('product')->getSku());
return $collection->getFirstItem();
}
return null;
}
/**
* Get how much products should be displayed at once.
*
* #return int
*/
public function getProductsCount()
{
if (null === $this->_productsCount) {
$this->_productsCount = self::DEFAULT_PRODUCTS_COUNT;
}
return $this->_productsCount;
}
public function getItemCollection()
{
return $this->_itemCollection;
}
public function getItems()
{
if (is_null($this->_items)) {
$this->_items = $this->getItemCollection()->getItems();
}
return $this->_items;
}
public function getRowCount()
{
return ceil(count($this->getItemCollection()->getItems())/$this->getColumnCount());
}
public function setColumnCount($columns)
{
if (intval($columns) > 0) {
$this->_columnCount = intval($columns);
}
return $this;
}
public function getColumnCount()
{
return $this->_columnCount;
}
public function resetItemsIterator()
{
$this->getItems();
reset($this->_items);
}
public function getIterableItem()
{
$item = current($this->_items);
next($this->_items);
return $item;
}
/**
* Set how many items we need to show in block
* Notice: this parametr will be also applied
*
* #param string $type
* #param int $limit
* #return Mage_Catalog_Block_Product_List_Upsell
*/
public function setItemLimit($type, $limit)
{
if (intval($limit) > 0) {
$this->_itemLimits[$type] = intval($limit);
}
return $this;
}
public function getItemLimit($type = '')
{
if ($type == '') {
return $this->_itemLimits;
}
if (isset($this->_itemLimits[$type])) {
return $this->_itemLimits[$type];
}
else {
return 0;
}
}
}

I think you just want access to the collection of diagrams. So it might be simplest to add this code to your product view.phtml file:
$collection = Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->getCollection()
->addFieldToFilter('sku', Mage::registry('product')->getSku());
foreach($collection as $productpartsdiagram){
//code to display each diagram
}
Alternatively extend the class which has public function getPartDiagram() in it and add your own function:
public function getPartDiagramsAll()
{
if (Mage::registry('product')) {
$collection = Mage::getModel('pws_productpartsdiagram/productpartsdiagram')->getCollection()
->addFieldToFilter('sku', Mage::registry('product')->getSku());
return $collection;
}
return null;
}
Call this function, then loop over the returned collection.

Related

Getting sub category info in parent category in laravel

I have multi level category where structure is like:
Parent
- first child
-- second child
- another child
What I want to do is, getting products in all child levels in Parent Page so that I can have all products of parent, first child, second child, another child inside Parent.
What I have so far, currently I can get products of Parent, first child & another child but I'm not able to get products of my second child.
Codes
public function totalcategoriessubs($catslug) {
$category = Category::where('slug','=',$catslug)->with('childs')->first();
//testing this
// $products = Product::whereHas('category', function($q) use ($catslug,$category)
// {
// $q->where(function($q) use ($catslug,$category) {
// $q->where('slug',$catslug)->orWhere('category_id',$category->id);
// });
// })->orderBy('created_at', 'DESC')->paginate(10);
$products = Product::whereHas('category', function($q) use ($catslug, $category) {
$q->where(function($q) use ($catslug,$category) {
$q->where('slug',$catslug) //works
->WhereHas('childs') //works
->WhereHas('childs.childs') //not working
->orWhere('category_id',$category->id); //works
});
})->orderBy('created_at', 'DESC')->paginate(10);
//end testing
return view('front.categoriessubs', compact('products', 'category'));
}
models
Product model
public function category(){
return $this->belongsTo(Category::class);
}
Category model
public function categories()
{
return $this->hasMany(Category::class);
}
public function childs() {
return $this->hasMany(Category::class,'category_id','id') ;
}
public function parent()
{
return $this->belongsTo(Category::class,'category_id');
}
public function isParent()
{
return !$this->category_id ? true : false; // if category_id is null => is a Parent Category
}
public function products(){
return $this->hasMany(Product::class);
}
any idea?
You can get the nested childs with simple trick.
only use protected $appends = ['childs', 'products']; in Model.
In Category.php Model
protected appends = ['childs'];
public function categories()
{
return $this->hasMany(Category::class);
}
public function childs() {
return $this->hasMany(Category::class,'category_id','id') ;
}
public function parent()
{
return $this->belongsTo(Category::class,'category_id');
}
public function isParent()
{
return !$this->category_id ? true : false; // if category_id is null => is a Parent Category
}
public function products(){
return $this->hasMany(Product::class);
}
Now You can get the Childs using
Category::with('childs')->get();
Hope this helps.
Controller
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* #var Category
*/
protected $category;
/**
* #var \Illuminate\Database\Eloquent\Builder
*/
protected $query;
/**
* Controller constructor.
* #param Category $category
*/
public function __construct(Category $category)
{
$this->category = $category;
$this->query = $this->category->newQuery();
}
public function home()
{
print_r($this->getAncestorCategoriesE1(2, 3)->toArray());
print_r($this->getSubCategoriesE2(null, 7)->toArray());
print_r($this->getSubCategoriesE2(1, 7)->toArray());
print_r($this->getSubCategoriesE1(null, 8)->toArray());
print_r($this->getSubCategoriesE1(1, 8)->toArray());
}
/**
* Easy method but select all
*
* #param $categoryId
* #param int $depth
* #return \Illuminate\Database\Eloquent\Collection|string|static[]
*/
public function getAncestorCategoriesE1($categoryId, $depth = 1)
{
if (!is_numeric($depth) || $depth < 1) {
return 'INvalid depth parameter';
}
$parents = [];
for ($i = 0; $i < $depth; $i++) {
$parents[] = 'parent';
}
$rel = implode('.', $parents);
return $this->category->with($rel)->find($categoryId);
}
/**
* Easy method but select all
*
* #param null $categoryId
* #param int $depth
* #return \Illuminate\Database\Eloquent\Collection|string|static[]
*/
public function getSubCategoriesE1($categoryId = null, $depth = 1) {
if (!is_numeric($depth) || $depth < 1) {
return 'INvalid depth parameter';
}
$children = [];
for ($i = 0; $i < $depth; $i++) {
$children[] = 'children';
}
$rel = implode('.', $children);
$this->addCategoryCondition($categoryId);
return $this->category->with($rel)->get();
}
/**
* #param null $categoryId
* #param int $depth
* #return \Illuminate\Database\Eloquent\Collection|static[]
*/
public function getSubCategoriesE2($categoryId = null, $depth = 4)
{
$this->addCategoryCondition($categoryId);
$this->pushSelectInQuery($this->query);
$this->pushWithInQuery($this->query, $depth);
return $this->query->get();
}
/**
* #param $query
*/
public function pushSelectInQuery($query)
{
$query->select('name', 'id', 'parent_id');
}
/**
* #param $query
* #param int $depth
*/
public function pushWithInQuery($query, $depth = 1)
{
$query->with(['children' => function($query) use ($depth) {
$this->pushSelectInQuery($query);
if (1 != $depth) {
$this->pushWithInQuery($query, --$depth);
}
}]);
}
/**
* #param $categoryId
*/
public function addCategoryCondition($categoryId)
{
if (is_null($categoryId)) {
$this->query->whereNull('parent_id');
} else {
$this->query->where('parent_id', $categoryId);
}
}
}
Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'parent_id', 'name'
];
/**
*
*/
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
/**
*
*/
public function parent()
{
return $this->belongsTo(Category::class, 'parent_id', 'id');
}
}
In controller has DRY I fix it later!!!

getPerson() return NULL, why?

I have two entities related Orders and Person where one Person can have many Orders. These are the mapping for that entities:
class Orders {
/**
* #ORM\ManyToOne(targetEntity="Person", inversedBy="orders")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
* */
protected $person;
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
public function getPerson()
{
$this->person;
}
}
class Person {
/**
* #ORM\Column(name="person_type", type="boolean", nullable=false)
*/
protected $person_type = 1;
/**
* #ORM\OneToMany(targetEntity="NaturalPerson", mappedBy="person")
* */
private $naturals;
/**
* #ORM\OneToMany(targetEntity="LegalPerson", mappedBy="person")
* */
private $legals;
/**
* #ORM\OneToMany(targetEntity="Orders", mappedBy="person")
* */
private $orders;
public function __construct()
{
$this->naturals = new ArrayCollection();
$this->legals = new ArrayCollection();
$this->orders = new ArrayCollection();
}
public function setPersonType($person_type)
{
$this->person_type = $person_type;
return $this;
}
public function getPersonType()
{
return $this->person_type;
}
public function getNaturals()
{
return $this->naturals;
}
public function getLegals()
{
return $this->legals;
}
public function getOrders()
{
return $this->orders;
}
}
In my controller I'm trying to get from Orders the related record for Person but I'm getting NULL as the JSON shows:
{
"data":[
[
"sdasdasd",
null
],
[
"werwerwer",
null
],
[
"sdfsdfsf435435",
null
]
]
}
This is how I'm getting the data in controller:
public function getOrdersAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository("FrontendBundle:Orders")->findAll();
$orders = array();
foreach ($entities as $entity)
{
$order = array();
$order[] = $entity->getNickname();
$order[] = $entity->getPerson();
$orders[] = $order;
}
$response['data'] = $orders;
return new JsonResponse($response);
}
I test values on DB tables by running this query:
SELECT ord.nickname, ord.person_id, pn.id, pn.description FROM orders ord left join person pn on pn.id = ord.person_id
And this is the result:
So records are related, then what I'm doing wrong?
Emmm... You just miss "return".
public function getPerson()
{
return $this->person;
}

OneToMany or OneToOne, I'm in the right or wrong path?

I have this DB model:
Then I made this entities (I just leave the relation part since the other isn't relevant on the topic):
Orders.php
class Orders {
/**
* #ORM\ManyToOne(targetEntity="Person", inversedBy="orders")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
* */
protected $person;
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
public function getPerson()
{
return $this->person;
}
}
Person.php
class Person {
/**
* #ORM\OneToMany(targetEntity="NaturalPerson", mappedBy="person")
* */
private $naturals;
/**
* #ORM\OneToMany(targetEntity="LegalPerson", mappedBy="person")
* */
private $legals;
/**
* #ORM\OneToMany(targetEntity="Orders", mappedBy="person")
* */
private $orders;
public function __construct()
{
$this->naturals = new ArrayCollection();
$this->legals = new ArrayCollection();
$this->orders = new ArrayCollection();
}
public function getNaturals()
{
return $this->naturals;
}
public function getLegals()
{
return $this->legals;
}
public function getOrders()
{
return $this->orders;
}
}
NaturalPerson.php
class NaturalPerson {
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Person", inversedBy="naturals")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
*/
protected $person;
/**
* #ORM\Column(name="identification_type", type="ci_type", nullable=false)
* #DoctrineAssert\Enum(entity="Tanane\FrontendBundle\DBAL\Types\CIType")
*/
protected $identification_type;
/**
* #ORM\Column(name="ci", type="integer", nullable=false)
*/
protected $ci;
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
public function getPerson()
{
return $this->person;
}
public function setIdentificationType($identification_type)
{
$this->identification_type = $identification_type;
return $this;
}
public function getIdentificationType()
{
return $this->identification_type;
}
public function setCI($ci)
{
$this->ci = $ci;
return $this;
}
public function getCI()
{
return $this->ci;
}
}
I omitted LegalPerson since it's pretty much the same as NaturalPerson so here is the problem. The mapping looks good but how I do get related records from Orders?
The idea behind this is for each Orders I need to know to which Person belongs too (the Orders) and also the extra information stored at NaturalPerson or LegalPerson depending on person.type.
See this code:
public function getOrdersAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository("FrontendBundle:Orders")->findAll();
if (!$entities)
{
$response['message'] = "No se encontraron resultados";
}
$orders = array();
foreach ($entities as $entity)
{
$personType = $entity->getPerson()->getPersonType();
$order = array();
$order[] = $entity->getNickname();
// Here I'm trying to access to `Naturals` methods from `Orders`
if ($personType == 1)
{
$order[] = $entity->getPerson()->getNaturals()[0]->getIdentificationType() . $entity->getPerson()->getNaturals()[0]->getCI();
}
elseif ($personType == 2)
{
$order[] = $entity->getPerson()->getLegals()[0]->getIdentificationType() . $entity->getPerson()->getLegals()[0]->getRIF();
}
$orders[] = $order;
}
$response['data'] = $orders;
return new JsonResponse($response);
}
But I get this error:
Error: Call to a member function getIdentificationType() on a
non-object in
/var/www/html/tanane/src/Tanane/BackendBundle/Controller/OrderController.php
line 115
Maybe my mapping is wrong since I should have OneToOne between Person and NaturalPerson (and that sounds wrong to my logic as DER shows) or maybe is not, but then I don't know how to fetch related properties for just one record, I read docs here and also in here but they didn't talk about this part or I don't see it, any advice? ideas? tips?
Trying to use Repositories and DQL to solve the problem
I'm building a function in a Repository class to fetch the data and not get to complicated as apparently my problem is, so I did this:
public function getOrders($person_type = 1)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('ord.*, ps.*')
->from("FrontendBundle:Orders", "ord")
->join('FrontendBUndle:Person', 'ps', 'WITH', 'ps.id = ord.person_id')
->orderBy('ord.created', 'DESC');
if ($person_type == 1)
{
$qb
->select('np.*')
->join('FrontendBundle:NaturalPerson', 'np', 'WITH', 'ps.id = np.person'); // Join NaturalPerson table
}
elseif ($person_type == 2)
{
$qb
->select('lp.*')
->join('FrontendBundle:LegalPerson', 'lp', 'WITH', 'ps.id = lp.person'); // Join NaturalPerson table
}
return $qb->getQuery()->getResult();
}
I'm not tested yet so maybe it won't works but, if the idea is to get the extra information for both tables, then using this DQL I made how I pass the $person_type which is inside Person table? This is getting a little complicated, at least for me
Running a raw query to see if columns are NULL
I build this simple query just for test if results are NULL:
SELECT
ord.id,
ord.person_id as ord_person_id,
ord.nickname,
ps.id,
ps.description,
np.person_id as natural_person_id,
np.identification_type,
np.ci
FROM
orders ord
LEFT JOIN person ps ON ord.person_id = ps.id
LEFT JOIN natural_person np ON np.person_id = ps.id
WHERE
ps.person_type = 1;
And this what query returns:
So there is not NULL columns in there
CRUD for create new Orders
// Set Person entity
$entityPerson = new Person();
$person_type === 1 ? $entityPerson->setDescription($orders['nat']['person']['description']) : $entityPerson->setDescription($orders['leg']['person']['description']);
$person_type === 1 ? $entityPerson->setContactPerson($orders['nat']['person']['contact_person']) : $entityPerson->setContactPerson($orders['leg']['person']['contact_person']);
$entityPerson->setPersonType($person_type);
$em->persist($entityPerson);
$em->flush();
...
if ($person_type === 1)
{
// Set NaturalPerson entity
$entityNatural = new NaturalPerson();
$entityNatural->setIdentificationType($orders['nat']['identification_type']);
$entityNatural->setCI($orders['nat']['ci']);
$em->persist($entityNatural);
$em->flush();
}
elseif ($person_type === 2)
{
// Set LegalPerson entity
$entityLegal = new LegalPerson();
$entityLegal->setIdentificationType($orders['leg']['identification_type']);
$entityLegal->setRIF($orders['leg']['rif']);
$em->persist($entityLegal);
$em->flush();
}
Since LegalPerson and NaturalPerson are specializations of Person I would recommend using what Doctrine calls Class Table Inheritance (documentation).
You would have:
Person.php
/**
* #ORM\Table(name="person")
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({
* "natural" = "NaturalPerson",
* "legal" = "LegalPerson",
* })
*/
class Person {
/**
* #ORM\OneToMany(targetEntity="Orders", mappedBy="person")
* */
private $orders;
public function __construct()
{
$this->orders = new ArrayCollection();
}
public function getOrders()
{
return $this->orders;
}
}
NaturalPerson.php
/**
* #ORM\Table(name="natural_person")
* #ORM\Entity
*/
class NaturalPerson extends Person {
/**
* #ORM\Column(name="identification_type", type="ci_type", nullable=false)
* #DoctrineAssert\Enum(entity="Tanane\FrontendBundle\DBAL\Types\CIType")
*/
protected $identification_type;
/**
* #ORM\Column(name="ci", type="integer", nullable=false)
*/
protected $ci;
public function setIdentificationType($identification_type)
{
$this->identification_type = $identification_type;
return $this;
}
public function getIdentificationType()
{
return $this->identification_type;
}
public function setCI($ci)
{
$this->ci = $ci;
return $this;
}
public function getCI()
{
return $this->ci;
}
}
Order.php stays the same.
As you can see, now both NaturalPerson and LegalPerson extend Person. Since you've changed your entities definition, you'll have to update your database schema.
Now, in your Controller you only have to do this:
foreach ($entities as $entity)
{
$person = $entity->getPerson();
$order = array();
$order[] = $entity->getNickname();
if ($person instanceof NaturalPerson)
{
$order[] = $person->getIdentificationType() . $person->getCI();
}
else // it has to be LegalPerson
{
$order[] = $person->getIdentificationType() . $person->getRIF();
}
$orders[] = $order;
}
Don't forget to add the use statement for NaturalPerson!
This way you only work with instances of either NaturalPerson or LegalPerson. I'm sure you can further improve this.
Lastly, you will have to change your CRUD for this. You don't work directly with Person anymore (in fact, it should be abstract), so now you need to handle CRUD for NaturalPerson and for LegalPerson separately. Each will have its Type, Controller, views, etc.
Your code would now look like this:
if ($person_type === 1)
{
$entityPerson = new NaturalPerson();
$entityPerson->setDescription($orders['nat']['person']['description']);
$entityPerson->setContactPerson($orders['nat']['person']['contact_person']);
$entityPerson->setIdentificationType($orders['nat']['identification_type']);
$entityPerson->setCI($orders['nat']['ci']);
$em->persist($entityPerson);
$em->flush();
}
elseif ($person_type === 2)
{
$entityPerson = new LegalPerson();
$entityPerson->setDescription($orders['leg']['person']['description']);
$entityPerson->setContactPerson($orders['leg']['person']['contact_person']);
$entityPerson->setIdentificationType($orders['leg']['identification_type']);
$entityPerson->setRIF($orders['leg']['rif']);
$em->persist($entityPerson);
$em->flush();
}
Perhaps, a problem in other. You can forget to assign NaturalPerson or LegalPerson to Person entity. So you need to check it before calling getIdentificationType():
if($personType == 1){
if(null !== $natural = $entity->getPerson()->getNaturals()[0]){
$order[] = $natural->getIdentificationType() . $natural->getCI();
}
}elseif($personType == 2){
if(null !== $legal = $entity->getPerson()->getLegals()[0]){
$order[] = $legal->getIdentificationType() . $legal->getRIF();
}
}

Update a record through model in zend framework

I am having a model and would need to update the record. every time $count ($count = $post->save()) is being NULL. how is it possible to know whether this record saved or not. if saved, i want to display the following message 'Post updated' and if not the other message 'Post cannot update'.
This is always going to the else port. how can i know model updated correctly or not?
$post = new Application_Model_Post($form->getValues());
$post->setId($id);
$count = $post->save();
//var_dump($count); exit;
if ($count > 0) {
$this->_helper->flashMessenger->addMessage('Post updated');
} else {
$this->_helper->flashMessenger->addMessage('Post cannot update');
}
Application_Model_Post code is as below,
class Application_Model_Post
{
/**
* #var int
*/
protected $_id;
/**
* #var string
*/
protected $_title;
/**
* #var string
*/
protected $_body;
/**
* #var string
*/
protected $_created;
/**
* #var string
*/
protected $_updated;
/**
* #var Application_Model_PostMapper
*/
protected $_mapper;
/**
* Class Constructor.
*
* #param array $options
* #return void
*/
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key=> $value) {
$method = 'set'.ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setId($id)
{
$this->_id = $id;
return $this;
}
public function getId()
{
return $this->_id;
}
public function setTitle($title)
{
$this->_title = (string) $title;
return $this;
}
public function getTitle()
{
return $this->_title;
}
public function setBody($body)
{
$this->_body = $body;
return $this;
}
public function getBody()
{
return $this->_body;
}
public function setCreated($ts)
{
$this->_created = $ts;
return $this;
}
public function getCreated()
{
return $this->_created;
}
/**
* Set data mapper.
*
* #param mixed $mapper
* #return Application_Model_Post
*/
public function setMapper($mapper)
{
$this->_mapper = $mapper;
return $this;
}
/**
* Get data mapper.
*
* Lazy loads Application_Model_PostMapper instance if no mapper
* registered.
*
* #return Application_Model_PostMapper
*/
public function getMapper()
{
if (null === $this->_mapper) {
$this->setMapper(new Application_Model_PostMapper());
}
return $this->_mapper;
}
/**
* Save the current post.
*
* #return void
*/
public function save()
{
$this->getMapper()->save($this);
}
public function getPost($id)
{
return $this->getMapper()->getPost($id);
}
/**
* Update the current post.
*
* #return void
*/
public function update($data, $where)
{
$this->getMapper()->update($data, $where);
}
/**
* Find a post.
*
* Resets entry state if matching id found.
*
* #param int $id
* #return Application_Model_Post
*/
public function find($id)
{
$this->getMapper()->find($id, $this);
return $this;
}
/**
* Fetch all posts.
*
* #return array
*/
public function fetchAll()
{
return $this->getMapper()->fetchAll();
}
}
getMapper refers to the class Application_Model_PostMapper.
class Application_Model_PostMapper
{
public function save(Application_Model_Post $post)
{
$data = array(
'title'=>$post->getTitle(),
'body'=>$post->getBody(),
'created'=>$post->getCreated()
);
if (null === ($id = $post->getId())) {
unset($data['id']);
$data['created'] = date('Y-m-d H:i:s');
$post->setId($this->getDbTable()->insert($data));
} else {
$this->getDbTable()->update($data, array('id = ?'=>$id));
}
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Application_Model_DbTable_Post');
}
return $this->_dbTable;
}
}
Class of Application_Model_DbTable_Post
class Application_Model_DbTable_Post extends Zend_Db_Table_Abstract
{
protected $_name = 'posts';
}
Let me know if anything is incorrect. i am a newbie to zend and did thsi while referring the zend site. http://framework.zend.com/manual/1.12/en/learning.quickstart.create-model.html
you can extend your script like this. zend dbtable triggers the Zend_Db_Exception on any error during any insert or update.
class Application_Model_PostMapper
{
public function save(Application_Model_Post $post)
{
$data = array(
'title'=>$post->getTitle(),
'body'=>$post->getBody(),
'created'=>$post->getCreated()
);
try {
if (null === ($id = $post->getId())) {
unset($data['id']);
$data['created'] = date('Y-m-d H:i:s');
$post->setId($this->getDbTable()->insert($data));
} else {
$this->getDbTable()->update($data, array('id = ?'=>$id));
}
} catch (Zend_Db_Exception $e) {
// error thrown by dbtable class
return $e->getMessage();
}
// no error
return true;
}
}
now you can check like this
$post = new Application_Model_Post($form->getValues());
$post->setId($id);
$isSaved = $post->save();
if ($isSaved === true) {
$this->_helper->flashMessenger->addMessage('Post updated');
} else {
// error
// $isSaved holds the error message
$this->_helper->flashMessenger->addMessage('Post cannot update');
}

Issues with annotations Valid/Regex/Order By, using Symfony2

I'm updating a website from Symfony 1.x to Symfony 2.1 during my internship, and i have some issues with Doctrine's Annotations. Btw i'm kinda newbie in Symfony2.
I meet this type of exception :
An exception has been thrown during the rendering of a template
("[Semantical Error] The annotation "#Doctrine\ORM\Mapping\OrderBy" in
property IHQS\NuitBlancheBundle\Entity\SC2Profile::$games does not
exist, or could not be auto-loaded.") in
"/var/www/sites/nuitblanche1/src/IHQS/NuitBlancheBundle/Resources/views/News/archives.html.twig".
And my code is:
<?php
namespace IHQS\NuitBlancheBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="IHQS\NuitBlancheBundle\Model\SC2ProfileRepository")
* #ORM\Table(name="player")
*/
class SC2Profile
{
const SC2RACE_PROTOSS = "protoss";
const SC2RACE_TERRAN = "terran";
const SC2RACE_ZERG = "zerg";
const SC2RACE_RANDOM = "random";
static public $_sc2races = array(
self::SC2RACE_PROTOSS => self::SC2RACE_PROTOSS,
self::SC2RACE_TERRAN => self::SC2RACE_TERRAN,
self::SC2RACE_ZERG => self::SC2RACE_ZERG,
self::SC2RACE_RANDOM => self::SC2RACE_RANDOM
);
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="sc2", cascade={"persist"})
* #Assert\NotBlank
*/
protected $user;
/**
* #ORM\Column(type="string", nullable=true)
*/
protected $sc2Role;
/**
* #ORM\Column(type="integer")
* #Assert\Regex("/\d+/")
*/
protected $sc2Id;
/**
* #ORM\Column(type="integer", nullable=true)
*/
protected $sc2RanksId;
/**
* #ORM\Column(type="string", nullable=true)
*/
protected $sc2Account;
/**
* #ORM\Column(type="string")
* #Assert\Choice(callback = "getSC2Races")
*/
protected $sc2Race;
/**
* #ORM\Column(type="string", nullable=true)
* #Assert\Regex("/\d+/")
*/
protected $sc2ProfileEsl;
/**
* #ORM\Column(type="string", nullable=true)
* #Assert\Regex("/\d+/")
*/
protected $sc2ProfileSc2cl;
/**
* #ORM\Column(type="string", nullable=true)
*/
protected $sc2ProfilePandaria;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $sc2Ranks;
/**
* #ORM\ManyToMany(targetEntity="Team", mappedBy="players")
*/
protected $teams;
/**
* #ORM\OneToMany(targetEntity="GamePlayer", mappedBy="player")
* #ORM\OrderBy({"id" = "DESC"})
*/
protected $games;
protected $stats;
protected $statsInit = false;
public function getId() {
return $this->id;
}
public function getUser() {
return $this->user;
}
public function setUser(User $user) {
$this->user = $user;
}
public function getUsername() {
return $this->user->getUserName();
}
public function getSc2Role() {
return $this->sc2Role;
}
public function setSc2Role($sc2Role) {
$this->sc2Role = $sc2Role;
}
public function getSc2Id() {
return $this->sc2Id;
}
public function setSc2Id($sc2Id) {
$this->sc2Id = $sc2Id;
}
public function getSc2RanksId()
{
return $this->sc2RanksId;
}
public function setSc2RanksId($sc2RanksId)
{
$this->sc2RanksId = $sc2RanksId;
}
public function getSc2Account() {
return $this->sc2Account;
}
public function setSc2Account($sc2Account) {
$this->sc2Account = $sc2Account;
}
public function getSc2Race() {
return $this->sc2Race;
}
public function setSc2Race($sc2Race) {
if(!in_array($sc2Race, SC2Profile::$_sc2races))
{
throw new \InvalidArgumentException('Invalid parameter "' . $sc2Race . '" for StarCraft 2 Race');
}
$this->sc2Race = $sc2Race;
}
public function getSc2ProfileEsl() {
return $this->sc2ProfileEsl;
}
public function setSc2ProfileEsl($sc2ProfileEsl) {
$this->sc2ProfileEsl = $sc2ProfileEsl;
}
public function getSc2ProfileSc2cl() {
return $this->sc2ProfileSc2cl;
}
public function setSc2ProfileSc2cl($sc2ProfileSc2cl) {
$this->sc2ProfileSc2cl = $sc2ProfileSc2cl;
}
public function getSc2ProfilePandaria() {
return $this->sc2ProfilePandaria;
}
public function setSc2ProfilePandaria($sc2ProfilePandaria) {
$this->sc2ProfilePandaria = $sc2ProfilePandaria;
}
public function getGames() {
$games = $this->games;
$result = array();
foreach($games as $game)
{
$result[] = $game->getGame();
}
return $result;
}
public function getWarGames()
{
$warGames = array();
foreach($this->getGames() as $game)
{
$wg = $game->getWarGame();
if($wg instanceof WarGame)
{
$warGames[$wg->getId()] = $wg;
}
}
return $warGames;
}
public function getReplays() {
$games = $this->games;
$result = array();
foreach($games as $game)
{
if(!$game->getGame()) { continue; }
if(!$game->getGame()->getReplay()) { continue; }
$result[] = $game->getGame();
}
return $result;
}
public function getStats()
{
if($this->statsInit) { return $this->stats; }
$this->initStatsVariables();
$counter = 0;
foreach($this->getWarGames() as $game)
{
$team2 = false;
foreach($game->getTeam2() as $p2)
{
if($p2->getPlayer() && $p2->getPlayer()->getId() == $this->getId()) { $team2 = true; break; }
}
if($team2) { continue; }
$type = "_" . $game->getType();
if($game->getTeam1Result() == Game::RESULT_WIN) { $this->stats[$type]["wins"]++; }
if($game->getTeam1Result() == Game::RESULT_LOSS) { $this->stats[$type]["losses"]++; }
if($game->getType() == Game::TYPE_1v1)
{
$type = $type.$game->getTeam2Race();
if($game->getTeam1Result() == Game::RESULT_WIN) { $this->stats[$type]["wins"]++; }
if($game->getTeam1Result() == Game::RESULT_LOSS) { $this->stats[$type]["losses"]++; }
}
}
foreach($this->stats as $type => $data)
{
$this->stats[$type]["ratio"] = (($data["losses"] + $data["wins"]) == 0)
? 0
: round(100 * $data["wins"] / ($data["losses"] + $data["wins"]));
}
$this->statsInit = true;
return $this->stats;
}
public function initStatsVariables()
{
$this->stats = array(
"_1v1" => array(),
"_2v2" => array(),
"_3v3" => array(),
"_4v4" => array(),
"_1v1protoss" => array(),
"_1v1terran" => array(),
"_1v1zerg" => array(),
"_1v1random" => array()
);
foreach($this->stats as $type => $data)
{
$this->stats[$type] = array(
"wins" => 0,
"losses" => 0,
"ratio" => 0
);
}
}
public function get2v2Teams()
{
$teams = array();
foreach($this->getWarGames() as $game)
{
if($game->getType() != Game::TYPE_2v2)
{
continue;
}
$team2 = false;
foreach($game->getTeam2() as $p2)
{
if($p2->getPlayer() && $p2->getPlayer()->getId() == $this->getId()) { $team2 = true; break; }
}
if($team2) { continue; }
// looking for ally
$ally = null;
$members = $game->getTeam1();
foreach($members as $member)
{
if($member->getName() != $this->getSc2Account())
{
$ally = $member;
break;
}
}
// updating hash table
$key = $ally->getName(). '_' . $ally->getRace();
if(!isset($teams[$key]))
{
$teams[$key] = array(
"allyName" => $ally->getName(),
"allyRace" => $ally->getRace(),
"wins" => 0,
"losses" => 0
);
}
if($game->getTeam1Result() == Game::RESULT_WIN) { $teams[$key]["wins"]++; }
if($game->getTeam1Result() == Game::RESULT_LOSS) { $teams[$key]["losses"]++; }
}
foreach($teams as $key => $team)
{
$teams[$key]["ratio"] = (($team["losses"] + $team["wins"]) == 0)
? 0
: round(100 * $team["wins"] / ($team["losses"] + $team["wins"]));
}
usort($teams, function($a, $b) {
if($a['wins'] == $b['wins'])
{
if($a['losses'] == $b['losses']) { return 0; }
return $a['losses'] > $b['losses'] ? 1 : -1;
}
return $a['wins'] < $b['wins'] ? 1 : -1;
});
return $teams;
}
public function setSc2Ranks(array $sc2ranks)
{
$this->sc2Ranks = serialize($sc2ranks);
}
public function getSc2Ranks()
{
return unserialize($this->sc2Ranks);
}
public function __toString() {
return $this->getSc2Account();
}
}
And i'm also meetin the same problem with the Constraint/Regex who is not auto-loaded or doesn't exists.Though i have all my doctrine bundles working.
My question is kinda simple : What i'm doing wrong? (I know it's not a very spécific one!)
The problem doesn't look to be with the #ORM\OrderBy({"id" = "DESC"}) annotation. That looks correct and you have included use Doctrine\ORM\Mapping as ORM;.
It looks like the problem has to do with the relationship between your SC2Profile entity and your GamePlayer entity. Are both these entities in the IHQS\NuitBlancheBundle\Entity namespace?
You could try updating the relationship to use the fully qualified class name.
/**
* #ORM\OneToMany(targetEntity="\IHQS\NuitBlancheBundle\Entity\GamePlayer", mappedBy="player")
* #ORM\OrderBy({"id" = "DESC"})
*/
protected $games;
Lastly, ensure that the opposite relationship (ManyToOne) has been setup in your GamePlayer entity.
/**
* #ORM\ManyToOne(targetEntity="SC2Profile", inversedBy="games")
* #ORM\JoinColumn(name="id", referencedColumnName="referenced_id")
*/
protected $player;

Categories