Skip to content

Commit e436f07

Browse files
committed
Added TaggableComponent
1 parent 5d35dae commit e436f07

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
App::uses('Component', 'Controller');
3+
class TaggableComponent extends Component {
4+
public $name = 'Taggable';
5+
6+
public $controller;
7+
public $request;
8+
9+
public function initialize(Controller $controller) {
10+
$this->controller = $controller;
11+
$this->request = $controller->request;
12+
13+
return parent::initialize($controller);
14+
}
15+
16+
/**
17+
* Checks for passed tag parameters and adds them to a query array
18+
*
19+
* @param array $query The query
20+
* @return $query;
21+
**/
22+
public function filterQuery($query = array()) {
23+
$tags = array();
24+
if (!empty($this->request->named['tag'])) {
25+
$tags = array($this->request->named['tag']);
26+
$query['tags'] = $tags;
27+
}
28+
$this->controller->set(array('taggableTags' => $tags));
29+
return $query;
30+
}
31+
}

Model/Behavior/TaggableBehavior.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function beforeFind(Model $Model, $query = array()) {
2424
if (!empty($query['tags'])) {
2525
$tags = $query['tags'];
2626
unset($query['tags']);
27-
$query = $this->filterTagQuery($Model, $query, $query['tags']);
27+
$query = $this->filterTagQuery($Model, $query, $tags);
2828
}
2929
return $query;
3030
}
@@ -134,12 +134,12 @@ public function filterTagQuery(Model $Model, $query = array(), $tags = array())
134134
if (!is_array($tags)) {
135135
$tags = $this->translateTagStrToArray($tags);
136136
}
137-
foreach ($tags as $k => $tagId) {
137+
foreach ($tags as $k => $tag) {
138138
$joinAlias = 'TagFilterJoin' . $k;
139139
$tagAlias = 'TagFilter' . $k;
140140
$type = 'INNER';
141141
$conditions = array(
142-
$this->Tag->escapeField(null, $tagAlias) => $tagId
142+
$this->Tag->escapeField($this->Tag->displayField, $tagAlias) => $tag
143143
);
144144
$query = $this->joinTags($Model, $query, compact('joinAlias', 'tagAlias', 'conditions', 'type'));
145145
}

Model/Tag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Tag extends TaggableAppModel {
66

77
public $hasMany = array(
88
'ModelsTag' => array(
9-
'className' => 'Tag.ModelsTag',
9+
'className' => 'Taggable.ModelsTag',
1010
'foreignKey' => 'tag_id',
1111
),
1212
);

View/Helper/TaggableHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?phpConfigure::load('Taggable.config');class TaggableHelper extends AppHelper { public $name = 'Taggable'; public $helpers = array( 'Html', 'Form', ); public function beforeRender($writeFile, $options = array()) { $this->Html->css('Taggable.style', null, array('inline' => false)); return parent::beforeRender($writeFile, $options); } /** * Outputs a version of the tag input, but wrapped in a form element to make it stand alone * * @param string $model The model related to the tags * @param array $options Options based on the input method options * @return string; **/ public function form($model, $options = array()) { $options['form'] = true; return $this->input($model, $options); } /** * Outputs a form input for entering tags associated with a model * * @param string $model The model name of the associated model * @param array $options * - form: Boolean to wrap the input in a form tag * - id: Includes an additional model id (Useful if form is true) * - tags: An array of existing tags (Most times this will be auto-set by the TaggableBehavior) * - legend: The legend to be written across the tags input * * @return string; **/ public function input($model, $options = array()) { $this->Html->script('Taggable.form', array('inline' => false)); $options = array_merge(array( 'form' => false, 'id' => false, 'tags' => array(), 'legend' => 'Tags', ), $options); extract($options); $wrapClass = 'taggable-tags-input'; $out = ''; if (empty($tags)) { // Looks for values stored by the TaggableBehavior $fieldValue = $model . '.' . Configure::read('Taggable.resultField'); if ($this->Html->value($fieldValue)) { $tags = $this->Html->value($fieldValue); } else if ($this->Html->value('Tag')) { $tags = array(); if (!empty($this->request->data['Tag']['Tag'])) { $tags = $this->request->data['Tag']['Tag']; } else { foreach ($this->request->data['Tag'] as $k => $tag) { $tags[$tag['id']] = $tag['tag']; } } } } // Outputs tags input $options = array( 'type' => 'text', 'label' => 'Separate tags with commas', 'placeholder' => '(ie: tag 1, tag 2, tag 3)', ); if (!empty($class)) { $options = $this->Html->addClass($options, $class); } if (!empty($form)) { $options = $this->Html->addClass($options, 'input-append', 'div'); $options['after'] = $this->Form->submit('Add Tags', array('div' => false)); } $out .= $this->Form->input(Configure::read('Taggable.saveField'), $options); // Outputs existing tags a checkbox list if (!empty($tags)) { if (isset($tags[0]['id'])) { $newTags = array(); foreach ($tags as $tag) { $newTags[$tag['id']] = $tag['tag']; } $tags = $newTags; } $out .= $this->Form->input('Tag', array( 'hiddenField' => false, 'options' => $tags, 'multiple' => 'checkbox', 'label' => false, 'value' => array_keys($tags), //selected 'div' => $wrapClass . '-checkboxes', )); } if (!empty($legend)) { $out = $this->Html->tag('legend', $legend) . $out; } $out = $this->Html->tag('fieldset', $out); if (!empty($id)) { $out .= $this->Form->hidden('id', array('value' => $id)); } // Wraps output in a form if (!empty($form)) { $formOpen = $this->Form->create($model, array('action' => 'edit')); $formClose = $this->Form->end(); $out = $formOpen . $out . $formClose; } return $this->Html->div($wrapClass, $out); } public function tag($text, $options = array()) { $options = array_merge(array( 'tag' => 'span', 'x' => null, 'url' => null, 'class' => 'taggable-tag', ), $options); extract($options); $out = $text; debug(compact('text')); if ($url) { $out = $this->Html->link($out, $this->_getTagUrl($text, $url)); } if ($x) { $out .= $this->_getXLink($x); } return $this->Html->tag($tag, $out, compact('class')); } public function resultTagList($result = null, $options = array()) { $tags = !empty($result['taggable_tags']) ? $result['taggable_tags'] : array(); return $this->tagList($tags, $options); } public function tagList($tags = null, $options = array()) { if (empty($tags)) { return ''; } $out = ''; foreach ($tags as $tag) { if (isset($tag['tag'])) { $tag = $tag['tag']; } $options['class'] = 'taggable-tags-list-item taggable-tag'; debug(compact('tag', 'options')); $out .= $this->tag($tag, $options); } return $this->Html->tag('div', $out, array('class' => 'taggable-tags-list')); } public function cloud($tagCount, $options = array()) { if (empty($tagCount)) { return false; } $minFontSize = 10; $maxFontSize = 36; $fontUnit = 'px'; $min = min($tagCount); $max = max($tagCount); $passTag = !empty($this->request->named['tag']) ? $this->request->named['tag'] . ',' : ''; $out = ''; foreach ($tagCount as $tag => $count) { if ($max == $min || $count == $min) { $fontSize = $minFontSize; } else { $fontSize = ((($maxFontSize - $minFontSize) * ($count - $min)) / ($max - $min)) + $minFontSize; } $out .= $this->Html->link($tag, array('tag' => $passTag . $tag), array( 'class' => 'tag', 'style' => 'font-size:' . $fontSize . $fontUnit, 'title' => 'Found ' . $count . ' Tagged as "' . $tag . '"', )); } return $this->Html->div('tags-cloud', $out); } /** * Generates a url including the current tag * * @param string $tag The current tag * @param string|array|bool $url The url. If true it will grab the current url * @return string|array; **/ private function _getTagUrl($tag, $url = true) { if ($url === true) { $url = $this->_currentUrl(); } $slug = Inflector::slug($tag); if (is_array($url)) { $url['tag'] = $slug; } else { $url .= '/tag:' . $slug; } return $url; }/** * Returns the link to remove a tag from the current url * * @param array $url The given url array * @return string; **/ private function _getXLink($url = array()) { if (!$url) { return ''; } if ($url === true || $url == 'remove') { $url = array('tag' => false) + $this->_currentUrl(); } return $this->Html->link('&times;', $url, array('escape' => false)); } /** * Returns the current url of the page * * @return array; **/ private function _currentUrl() { $url = Router::parse($this->request->url); if (!empty($url['pass'])) { $url['?'] = $url['pass']; unset($url['pass']); } if (!empty($url['named'])) { $url = $url['named'] + $url; unset($url['named']); } return $url; }}
1+
<?phpConfigure::load('Taggable.config');class TaggableHelper extends AppHelper { public $name = 'Taggable'; public $helpers = array( 'Html', 'Form', ); public function beforeRender($writeFile, $options = array()) { $this->Html->css('Taggable.style', null, array('inline' => false)); return parent::beforeRender($writeFile, $options); } /** * Outputs a version of the tag input, but wrapped in a form element to make it stand alone * * @param string $model The model related to the tags * @param array $options Options based on the input method options * @return string; **/ public function form($model, $options = array()) { $options['form'] = true; return $this->input($model, $options); } /** * Outputs a form input for entering tags associated with a model * * @param string $model The model name of the associated model * @param array $options * - form: Boolean to wrap the input in a form tag * - id: Includes an additional model id (Useful if form is true) * - tags: An array of existing tags (Most times this will be auto-set by the TaggableBehavior) * - legend: The legend to be written across the tags input * * @return string; **/ public function input($model, $options = array()) { $this->Html->script('Taggable.form', array('inline' => false)); $options = array_merge(array( 'form' => false, 'id' => false, 'tags' => array(), 'legend' => 'Tags', ), $options); extract($options); $wrapClass = 'taggable-tags-input'; $out = ''; if (empty($tags)) { // Looks for values stored by the TaggableBehavior $fieldValue = $model . '.' . Configure::read('Taggable.resultField'); if ($this->Html->value($fieldValue)) { $tags = $this->Html->value($fieldValue); } else if ($this->Html->value('Tag')) { $tags = array(); if (!empty($this->request->data['Tag']['Tag'])) { $tags = $this->request->data['Tag']['Tag']; } else { foreach ($this->request->data['Tag'] as $k => $tag) { $tags[$tag['id']] = $tag['tag']; } } } } // Outputs tags input $options = array( 'type' => 'text', 'label' => 'Separate tags with commas', 'placeholder' => '(ie: tag 1, tag 2, tag 3)', ); if (!empty($class)) { $options = $this->Html->addClass($options, $class); } if (!empty($form)) { $options = $this->Html->addClass($options, 'input-append', 'div'); $options['after'] = $this->Form->submit('Add Tags', array('div' => false)); } $out .= $this->Form->input(Configure::read('Taggable.saveField'), $options); // Outputs existing tags a checkbox list if (!empty($tags)) { if (isset($tags[0]['id'])) { $newTags = array(); foreach ($tags as $tag) { $newTags[$tag['id']] = $tag['tag']; } $tags = $newTags; } $out .= $this->Form->input('Tag', array( 'hiddenField' => false, 'options' => $tags, 'multiple' => 'checkbox', 'label' => false, 'value' => array_keys($tags), //selected 'div' => $wrapClass . '-checkboxes', )); } if (!empty($legend)) { $out = $this->Html->tag('legend', $legend) . $out; } $out = $this->Html->tag('fieldset', $out); if (!empty($id)) { $out .= $this->Form->hidden('id', array('value' => $id)); } // Wraps output in a form if (!empty($form)) { $formOpen = $this->Form->create($model, array('action' => 'edit')); $formClose = $this->Form->end(); $out = $formOpen . $out . $formClose; } return $this->Html->div($wrapClass, $out); } public function tag($text, $options = array()) { $options = array_merge(array( 'tag' => 'span', 'x' => null, 'url' => null, 'class' => 'taggable-tag', ), $options); extract($options); $out = $text; if ($url) { $out = $this->Html->link($out, $this->_getTagUrl($text, $url)); } if ($x) { $out .= $this->_getXLink($x); } return $this->Html->tag($tag, $out, compact('class')); } public function filterHeading($options = array()) { $options = array_merge(array( 'title' => 'Tags:', 'x' => true, )); return $this->tagList(false, $options); } public function resultTagList($result = null, $options = array()) { $resultField = Configure::read('Taggable.resultField'); $tags = !empty($result[$resultField]) ? $result[$resultField] : array(); return $this->tagList($tags, $options); } public function tagList($tags = false, $options = array()) { if ($tags === false && !empty($this->_View->viewVars['taggableTags'])) { $tags = $this->_View->viewVars['taggableTags']; } if (empty($tags)) { return ''; } $out = ''; if (!empty($options['title'])) { $out .= $this->Html->tag('span', $options['title'], array( 'class' => 'taggable-tags-list-item taggable-tag-title', )); } foreach ($tags as $tag) { if (isset($tag['tag'])) { $tag = $tag['tag']; } $options['class'] = 'taggable-tags-list-item taggable-tag'; $out .= $this->tag($tag, $options); } return $this->Html->tag('div', $out, array('class' => 'taggable-tags-list')); } public function cloud($tagCount, $options = array()) { if (empty($tagCount)) { return false; } $minFontSize = 10; $maxFontSize = 36; $fontUnit = 'px'; $min = min($tagCount); $max = max($tagCount); $passTag = !empty($this->request->named['tag']) ? $this->request->named['tag'] . ',' : ''; $out = ''; foreach ($tagCount as $tag => $count) { if ($max == $min || $count == $min) { $fontSize = $minFontSize; } else { $fontSize = ((($maxFontSize - $minFontSize) * ($count - $min)) / ($max - $min)) + $minFontSize; } $out .= $this->Html->link($tag, array('tag' => $passTag . $tag), array( 'class' => 'tag', 'style' => 'font-size:' . $fontSize . $fontUnit, 'title' => 'Found ' . $count . ' Tagged as "' . $tag . '"', )); } return $this->Html->div('tags-cloud', $out); } /** * Generates a url including the current tag * * @param string $tag The current tag * @param string|array|bool $url The url. If true it will grab the current url * @return string|array; **/ private function _getTagUrl($tag, $url = true) { if ($url === true) { $url = $this->_currentUrl(); } $slug = Inflector::slug($tag); if (is_array($url)) { $url['tag'] = $slug; } else { $url .= '/tag:' . $slug; } return $url; }/** * Returns the link to remove a tag from the current url * * @param array $url The given url array * @return string; **/ private function _getXLink($url = array()) { if (!$url) { return ''; } if ($url === true || $url == 'remove') { $url = array('tag' => false) + $this->_currentUrl(); } return $this->Html->link('&times;', $url, array('escape' => false)); } /** * Returns the current url of the page * * @return array; **/ private function _currentUrl() { $url = Router::parse($this->request->url); if (!empty($url['pass'])) { $url['?'] = $url['pass']; unset($url['pass']); } if (!empty($url['named'])) { $url = $url['named'] + $url; unset($url['named']); } return $url; }}

0 commit comments

Comments
 (0)