Categories tags in module (mod_articles_categories) - joomla3.0

I need to display tags of every sub category in categories list module (mod_articles_categories).
For articles in similar module (mod_articles_news) I always do something like this:
<?php $itemtags = (new JHelperTags)->getItemTags('com_content.article', $item->id);
$taglayout = new JLayoutFile('joomla.content.tags');
foreach ($itemtags as $tag) { echo $tag->title; } ?>
But code like this doesn't work fork categories even I change 'com_content.article' to 'com_content.category'
Maybe someone knows what I doin' wrong?
Thanks in advance

Ok, finally I got the solution:
<?php foreach ($list as $item) :
$itemtags = (new JHelperTags)->getItemTags('com_content.category', $item->id);
$taglayout = new JLayoutFile('joomla.content.tags');?>
<?php if (!empty($itemtags)) { foreach ($itemtags as $tag) { echo $tag->title.' '; }; } ?>
<div><?php echo $item->title; ?></div>
<?php endforeach; ?>

Related

Why is my function not working in phtml file?

I have created a collection.php model and added a addOrderFilter() function, but when I try to call addOrderFilter() in my phtml file, it gives me
Fatal error: Call to a member function addOrderFilter() on boolean in [...]\magento\app\design\adminhtml\default\default\template\paketid\shipping.phtml on line 5
This is my shipping.phtml :
<?php echo $this->getChildHtml('PaketId_Shipping');?>
<h1>Test custom block</h1>
<?php $order = $this->getOrder()?>
<?php $shipping = Mage::getModel('paketid_shipping/result')->getCollection()->addOrderFilter($order) ?>
<?php if(count($shipping)):
foreach($shipping as $shipping): ?>
<?php echo $this->__('Booking Code') ;?>
<?php echo $shipping->getBookingCode(); ?>
<?php endforeach; ?>
<?php endif; ?>
My collection.php model :
class PaketId_Shipping_Model_Resource_Result_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
protected $order;
protected function _construct()
{
$this->_init('paketid_shipping/result');
}
public function addOrderFilter($order)
{
if ($order instanceof Mage_Sales_Model_Order) {
$order = (int) $order->getId();
}
if (!is_array($order)) {
$order = array($order);
}
$this->getSelect()->where("main_table.order_id IN (?)", $order);
//$this->getSelect()->where("main_table.order_id IN (?)", $order)->order('id DESC');
return $this;
}
The confusing part is, why does my phtml doesn't render my collection model ? Am I doing something wrong ?
Make sure magento is not running in compilation mode.
OR
There is something wrong in syntax Mage::getModel('paketid_shipping/result')->getCollection() . This is not returning correct collection object. Try debugging whether it returns collection object or not.
OR
You can try different similar syntax
Mage::getResourceModel('paketid_shipping/result_collection')->addOrderFilter($order);

CakePHP different tables displays in the same page

I'd like to make website, with news and comments attached to them.
I made Model Infos.php ( connected to news on my page) and Model Infos_coms.php ( where comment should be saved for each news). For each Model I've got controlleres as follows
InfosController.php
class InfosController extends AppController
{
public $helpers = array('Html','Form','Session');
public $components = array('Session');
public function index()
{
$this->set('inform', $this->Info->find('all'));
//$this->loadModel('Infos_com');
//$this->set('com', $this->Infos_com->find('all'));
}}
, Info_comsController.php.
<?php
class Infos_comsController extends AppController
{
public $helpers = array('Html','Form','Session');
public $components = array('Session');
public function index()
{
$this->set('com', $this->Infos_com->find('all'));
}}
and there is my problem, couse i don't know how to display both tables (news and their comments on one page)
here is my index, i've red twice cookbook chapter about view and i didn't find there answer for solving my problem.
here is my Index file in folder (View/Infos)
<body>
<?php echo $this->Html->link(__('Dodaj newsa',true),array('action'=>'add')); ?>
<div class="container">
<?php
foreach ($inform as $news) : ?>
<h3>
<?php echo $news['Info']['title']; ?>
</h3>
<p>
<?php echo $news['Info']['body']; ?>
</p>
<small>
<?php echo $news['Info']['created']; ?>
</small>
<small>IP:
<?php echo $news['Info']['ip']; ?>
</small>
<!-- existing comments -->
<?php foreach ($com as $comment): ?>
<h4>
<?php echo $comment['Infos_com']['body']; ?>
</h4>
<small>
<?php echo $comment['Infos_com']['created']; ?><br>
<?php echo $comment['Infos_com']['ip']; ?>
</small>
<!-- adding comments -->
<div class="form-group">
<?php echo $this->Form->create('Infos_com'); ?>
<?php echo $number = $comment['Info']['id']; ?>
<?php echo $this->Form->input(__('mail',true),array('class'=>'form-control')) ?>
<?php echo $this->Form->input(__('Comment body',true), array('class'=>'form-control')); ?>
<?php echo $this->Form->submit(__('Dodaj komentarz',true),array('class'=>'btn btn-info')); ?>
<?php echo $this->Form->end(); ?>
</div>
<?php endforeach; ?>
<?php endforeach; unset($news); unset($comment);?>
i will be gratefull for any tip
Edit.
I followed Guillemo Mansilla suggest, but now i got issue with database. I've used Guillemo Mansilla code, with changed names, and also adde something i think correctly. There are my Modal
Info.php
<?php
class Info extends AppModel
{
public $hasMany = array('Infos_com');
public $validate = array(
'title'=>array(
'rule'=>'notEmpty'
),
'body'=>array(
'rule'=>'notEmpty'
)
);
}
?>
Infos_com.php
<?php
class Infos_com extends AppModel
{
public $belongsTo = array('Info');
public $validate = array(
'mail'=>array(
'requierd'=>array(
'rule'=>'notEmpty',
'message'=>'Write your email'
)
),
'body'=>array(
'rule'=>'notEmpty',
'message'=>'Write a comment'
)
);
}
?>
i changed my index.ctp inside body part to
<?php if (isset($inform)) {
foreach($inform as $info) {
echo $info['Info']['title'];
foreach($info['Infos_com'] as $comment) {
echo $comment['Infos_com']['body'];
}
}
} ?>
now i'm getting error
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Infos_com.info_id' in 'field list'
SQL Query: SELECT Infos_com.id, Infos_com.id_infos, Infos_com.username, Infos_com.mail, Infos_com.ip, Infos_com.created, Infos_com.body, Infos_com.info_id FROM blogdb.infos_coms AS Infos_com WHERE Infos_com.info_id IN (1, 2, 3, 4, 5)
i have both tables so i don't understand where is mistake.
I will assume that your associations are correct, that is, Info hasMany Infos_com, so in your Info Model you have something like
public $hasMany => array('Infos_com')
I am going to assume that both models are correctly created (You didn't paste your models)
Now, in your controller InfosController, just do this
$this->Info->recursive = 1;
$this->set('inform', $this->Info->find('all'));
In your view, you will have all "infos" along with its comments in a var named $inform, just iterate over it recursively
if (isset($inform)) {
foreach($inform as $info) {
echo $info['Info']['title']; //I dont even know if you have a field named "title"
foreach($info['Infos_com'] as $comment) {
echo $comment['Infos_com']['comment'];
}
}
}
bear in mind that this piece of code probably don't work because we use different names, just adapt it to what you have in there
I finnaly make it , after all night !!!
i Changed column name in my Infos_com from id_infos to info_id
next i edit my index code to
<?php if (isset($inform)) {
foreach($inform as $info) {
echo $info['Info']['title']; echo '<br>';
echo $info['Info']['body']; echo '<br>';
foreach($info['Infos_com'] as $comment) {
echo $comment['body']; echo '<br>';
echo $comment['mail']; echo '<br>';
}
}
} ?>
and finnaly i got my comment under my news, THANK YOU !

Get array from model, then pass to view

Simple, but for me as a beginner, a problem. I need to pass an array from my model (array is filled with info while reading a text file) to a controller and then finally to a view.
My model:
function show_notes(){
$file = "notes.txt";
foreach(file($file) as $entry)
{
list($user, $content) = array_map('trim', explode(':', $entry));
$notes = array (
'user'=> '$user',
'content'=> '$content'
);
}
return $notes;
}
Controller:
function members_area()
{
$this->load->model('Note_model');
$notes[] = $this->Note_model->show_notes();
$this->load->view('includes/header');
$this->load->view('members_area', $notes);
$this->load->view('includes/footer');
}
And in view I use this:
foreach ($notes as $item)
{
echo "<h1>$user</h>";
echo "<p>$content</p>";
}
And I am getting error that notes variable is undefined in my view.
I think I just don't understand how arrays work. I have tried to read about that, I have tried some examples similar to this, but still can't get it.
In your controller:
$data['notes'] = $this->Note_model->show_notes();
...
$this->load->view('members_area', $data);
EDIT:
In your view:
<?php foreach ($notes as $item):?>
<h1><?php echo $item['user']; ?></h1>
<p><?php echo $item['content'] ?></p>
<?php endforeach; ?>
In your model:
$notes = array();
foreach(file($file) as $entry)
{
list($user, $content) = array_map('trim', explode(':', $entry));
array_push($notes, array('user' => $user, 'content' => $content));
}
return $notes;
Replace this
$notes[] = $this->Note_model->show_notes();
with this
$notes['notes'] = $this->Note_model->show_notes();

Updating specified rows in CakePHP using array of ID's?

This code is only updating one row (the one that matches the first in the array):
Edit: showing more code!
Here's my view. It's grabbing db entries based on an association (there's one model "clients" that has a one-to-many relationship with two other models, Programs and Users).
<div class="view">
<h2><?php echo h($program['Program']['title'])?></h1>
<?php echo $this->Form->create('User', array('action' => 'pushing')); ?>
<table id="pushTable">
<tr><th colspan="5">Select the athletes you would like to push this program to:</th></tr>
<tr>
<?php $i=0; ?>
<?php foreach ($clients['Players'] as $player) {?>
<?php if ($i == 0) {?><tr><?php } ?>
<td><?php echo $this->Form->checkbox($player['id']) . ' ' . $player['username'];?></td>
<?php if ($i == 4) {?></tr><?php $i = 0; } else { $i++; } ?>
<?php } ?>
</tr>
</table>
<?php echo $this->Form->end(__('Push')); ?>
</div>
In my Users controller:
public function pushing() {
if ($this->request->is('post') || $this->request->is('put')) {
$athletes = $this->request->data['User'];
foreach ( $athletes as $player => $flag){
if ($flag == 0){
unset($athletes[$player]);
}
}
$this->User->updateAll(
array('User.data' => "'foo'"),
array('User.id' => $athletes)
);
$this->Session->setFlash(__('Programs were pushed!'));
}
}
}
$athletes is the array is collected from checked boxes, and there seem to me no problems with that... so I'm not sure why the updateAll isn't iterating over each ID in the array...
Maybe it's not working for a db related reason? I'm developing on MAMP... maybe the db isn't set up for "atomic" stuff (only heard about that here today!).
I had previously tried using a foreach to loop over the id's, then in the foreach just did this (edit: more code!)
public function pushing() {
if ($this->request->is('post') || $this->request->is('put')) {
foreach ($this->request->data['User'] as $player => $flag) {
if ($flag) {
$this->User->id = $player; // set ID to player we want to save ($player is id that was suplpied in view to checkbox
$this->User->saveField('data', 'foo'); // then, push the data!
}
}
$this->Session->setFlash(__('Programs were pushed!'));
}
$this->autoRender = false;
$this->redirect(array('action' => 'index'));
}
But that caused weird results with redirection. No matter where I put redirection in that action, the save just wanted to do its own thing. That $this->autoRender did nothing. The controller still tried to resolve to the /pushing/ route
Give this a shot :)
In your view:
<div class="view">
<h2><?php echo h($program['Program']['title'])?></h1>
<?php echo $this->Form->create('User', array('action' => 'pushing')); ?>
<table id="pushTable">
<tr><th colspan="5">Select the athletes you would like to push this program to:</th></tr>
<tr>
<?php $i=0; ?>
<?php foreach ($clients['Players'] as $player) {?>
<?php if ($i == 0) {?><tr><?php } ?>
<td><?php echo $this->Form->input('Player.' . $player['id']. '.id', array('type' => 'checkbox', 'value' => $player['id'])) . ' ' . $player['username'];?></td>
<?php if ($i == 4) {?></tr><?php $i = 0; } else { $i++; } ?>
<?php } ?>
</tr>
</table>
<?php echo $this->Form->end(__('Push')); ?>
</div>
In your controller:
public function pushing() {
if ($this->request->is('post') || $this->request->is('put')) {
$athletes = $this->request->data['Player'];
$athlete_ids = array();
foreach($athletes as $a){
$athlete_ids[$a['id']] = $a['id'];
}
$this->User->updateAll(
array('User.data' => "'foo'"),
array('User.id' => $athlete_ids)
);
$this->Session->setFlash(__('Programs were pushed!'));
}
}
}
Hi had to change the code a bit to make it for work me..
$contactsids = array();
foreach($selected as $key => $val){
if(($val <> '') && ($val <> 0) ) {
$contactsids[$val] = $val;
}
}
$this->Contact->updateAll(
array('Contact.contact_category_id' => $category_id),
array('Contact.id' => $contactsids)
);

Count associated records with tree model (full depth)

We have two models. Ebooks HABTM Tags, where tags follows the tree behavior.
For each tag we need two numbers. First, the number of ebooks associated to the tag, and secondly the number of ebooks associated to the tag + the number of associated ebooks for each descendant.
How can we get the tags with these numbers in an array in tree format?
Thank you very much for any help.
Update: There is a datetime parameter Ebook.published which defines when the book is to be counted or not. All the ebooks that have codeEbook.published < NOW() should be counted.
Cake has no basic support for this. You will need to do the calculations on the fly or create your own counter cache with custom code to update. This is messy.
I'd suggest overriding the beforeSave() and afterSave() function in your Ebooks controller. If updating, grab the current existing set of tags associated with the Ebook in your beforeSave(). In the afterSave() grab the new set of tags and merge it with the previous set. If there are any changes, iterate through all the tags and call $this->Tag->getPath($id) to get a list of all the ancestors. You'll now have all the tags that were affected by the save. You can now iterate through them and update the counts.
Actually, I found a simpler solution since I already have build the function that returns the tags tree. I used a query for each tag to get the actual count of that moment. Here is what I 've build. Feel free to use it according your needs.
In Tag model
// Returns the number of published ebooks of selected tag
function count_direct_published($tag_id = 0){
$temp = $this->query('SELECT count(*) as count FROM ebooks_tags LEFT JOIN ebooks ON ebooks_tags.ebook_id = ebooks.id WHERE ebooks.published < NOW() AND ebooks_tags.tag_id = '.$tag_id);
return $temp[0][0]['count'];
}
// Returns an array in tree format with $id tag and all his children
// $id = 0 start from the top (parent_id = null), or, from $id = the top's tag id
// $limit = boolean (default false)
// $level = Is the limit of depth applied only if $limit = true
// $ext = true Means this is the first time the function is called
// You can run tree_builder(), returns all the tree,
function tree_builder($id = 0, $limit = false, $level = 1, $ext = 1){
if($ext == 1){
$ext = 0;
$undo = true;
}else{
$undo = false;
}
$this->recursive=-1;
$this->contain('EbooksTag');
$var = array();
$count_all = 0;
// If limit = too big , exit
if($limit !== false && $level > $limit){
return '';
}
// Or else,
// If $id=0, find all the children
if($id == 0){
$tags = $this->find('all',array('conditions'=>array( 'Tag.parent_id IS NULL'), 'order'=>array('Tag.gre')));
// If $id!=0 && runs internally
}elseif($id != 0 && !$undo ){
$tags = $this->find('all',array('conditions'=>array( 'Tag.parent_id'=>$id ), 'order'=>array('Tag.gre')));
}
// If $id!=0 && is called from outside
elseif($id != 0 && $undo){
$tags = $this->find('all',array('conditions'=>array( 'Tag.id'=>$id )));
}
foreach($tags as $key => $tag){
$var[] = $tag;
$next = $this->tree_builder($tag['Tag']['id'], $limit, $level+1, $ext);
end($var); // move the internal pointer to the end of the array
$last_key = key($var); // fetches the key of the element pointed to by the internal pointer
$var[$last_key]['children'] = $next['var'];
$counter_direct = $this->count_direct_published($id);
$var[$last_key]['Tag']['count_all'] = $next['count_all']+$counter_direct;
$count_all += $var[$last_key]['Tag']['count_all'];
}
if( $undo )
{
return $var;
}else{
return array('count_all'=> $count_all, 'var' => $var);
}
}
In tags_controller.php
$this->set('tags', $this->Tag->tree_builder());
In the view
<?php foreach($tags as $tag){?>
<?php // Ο Γονέας σε dropdown box ?>
<div class="main-categ">
<?php echo $tag['Tag']['gre']; ?>
<?php echo $html->image('layout/arrows.png', array('alt'=> "Expand")); ?>
</div>
<div class="collapse">
<?php // Τα στοιχεία του γονέα ?>
<div class="tag-1">
<span class="tag-1">
<?php // Αν ?>
<?php if($tag['Tag']['count_direct']>0){
// Display link
echo $html->link($tag['Tag']['gre'],array('action'=>'view',$tag['Tag']['id']));
echo ' ('.$tag['Tag']['count_direct'].')';
}else{
// Display text
echo $tag['Tag']['gre'];
} ?>
</span>
<?php echo $html->link( 'view all' ,array('action'=>'view_all',$tag['Tag']['id'])); ?>
(<?php echo $tag['Tag']['count_all']; ?>)
</div>
<?php // Για κάθε πρώτο παιδί ?>
<?php foreach($tag['children'] as $tag_1){ ?>
<div>
<span class="tag-2">
<?php if($tag_1['Tag']['count_direct']>0){
// Display link
echo $html->link($tag_1['Tag']['gre'],array('action'=>'view',$tag_1['Tag']['id']));
echo ' ('.$tag_1['Tag']['count_direct'].')';
}else{
// Display text
echo $tag_1['Tag']['gre'];
} ?>
</span>
<?php echo $html->link( 'view all' ,array('action'=>'view_all',$tag_1['Tag']['id'])); ?>
(<?php echo $tag_1['Tag']['count_all']; ?>)
<?php // Τα δεύτερα παιδιά ?>
<?php $i=0; ?>
<?php foreach($tag_1['children'] as $tag_2){ ?>
<?php if($i==0){ echo '<ul class="split">'; $i++; } ?>
<li>
<?php if($tag_2['Tag']['count_direct']>0){
// Display link
echo $html->link($tag_2['Tag']['gre'],array('action'=>'view',$tag_2['Tag']['id']));
echo ' ('.$tag_2['Tag']['count_direct'].')';
}else{
// Display text
echo $tag_2['Tag']['gre'];
} ?>
</li>
<?php } ?>
<?php if($i==1) echo '</ul>'; ?>
<div class="clear"></div>
</div>
<?php } ?>
</div>
Perhaps its not the best solution but it works. Hope that helps

Resources