Last active
December 29, 2016 11:11
-
-
Save garyconstable/0610234468789ed2047d to your computer and use it in GitHub Desktop.
Craft CMS Loop through categories and children from within a plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Craft; | |
| class TestPlugin extends BasePlugin | |
| { | |
| function getName() | |
| { | |
| return Craft::t('Test Plugin'); | |
| } | |
| function getVersion() | |
| { | |
| return '1.0'; | |
| } | |
| function getDeveloper() | |
| { | |
| return 'Gary Constable - Yello Studio'; | |
| } | |
| function getDeveloperUrl() | |
| { | |
| return 'http://yellostudio.co.uk'; | |
| } | |
| public function getSourceLanguage(){ | |
| return 'en'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Craft; | |
| class TestVariable | |
| { | |
| public function p($data = array() ){ | |
| echo '<pre>'.print_r($data, true).'</pre>'; | |
| } | |
| public function d($data = array() ){ | |
| echo '<pre>'.print_r($data, true).'</pre>';die(); | |
| } | |
| public function test(){ | |
| $this->p(' --- BEGIN HERE --- '); | |
| //this returns an element criteria model | |
| $o_criteria = craft()->elements->getCriteria(ElementType::Category); | |
| //set the model params - level 1 order by level limit 20! | |
| $o_criteria->group = 'catParent2'; | |
| $o_criteria->order = 'level'; | |
| $o_criteria->level = 1; | |
| $o_criteria->limit = 20; | |
| //check we have some matching categories | |
| if( $o_criteria->getDescendants()->total() > 0 ){ | |
| //loop through | |
| foreach ($o_criteria as $o_entry) | |
| { | |
| $this->p("Level 1: " . $o_entry->title); | |
| //if we have some children, i.e the next level down | |
| if( $o_entry->getDescendants()->total() > 0 ){ | |
| //get the current levels children | |
| $o_children = $o_entry->getChildren(); | |
| //loop each child | |
| foreach ($o_children as $d){ | |
| $this->p(" Level 2: " . $d->title); | |
| } | |
| } | |
| } | |
| } | |
| $this->d(' --- END HERE --- '); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Craft; | |
| class TestVariable | |
| { | |
| public function p($data = array() ){ | |
| echo '<pre>'.print_r($data, true).'</pre>'; | |
| } | |
| public function d($data = array() ){ | |
| echo '<pre>'.print_r($data, true).'</pre>';die(); | |
| } | |
| protected $preferencesBlocks = array( | |
| 'preference' | |
| ); | |
| /** | |
| * get the matrix block id's using the hardcoded preference block handle; | |
| * @return type | |
| */ | |
| public function getPreferenceIds(){ | |
| $a_id = array(); | |
| $this->preferencesBlocks = $this->preferencesBlocks; | |
| foreach( $this->preferencesBlocks as $x){ | |
| $q = | |
| " select fields.id as main_id , types.id as block_type_id from craft_fields fields LEFT JOIN craft_matrixblocktypes types ON fields.id = types.fieldId | |
| where lower(fields.type) = 'matrix' and lower(fields.handle) like '%%".$x."%%' | |
| -- AND types.handle = 'contact' "; | |
| $o_db_command = craft()->db->createCommand($q)->queryAll(true); | |
| $a_id[ $x ] = $o_db_command; | |
| } | |
| return $a_id; | |
| } | |
| public function getPreferencesForMatrixBlock( $s_blockname = ''){ | |
| //the retunr array should contain the user preferences | |
| $a_return_attributes = array(); | |
| //get the user model | |
| $o_user_model = craft()->userSession->getUser(); | |
| //see a row exists - actually a user will have a row for each element type so for one user may have 10 rows - crap no? | |
| if( $o_user_model->$s_blockname->count() ) { | |
| //null the block | |
| $block = null; | |
| //itterate through each of the existing blocks | |
| foreach( $o_user_model->$s_blockname->iterator as $o_current_block){ | |
| //get the attributes | |
| $a_attributes = $o_current_block->getContent()->getAttributes(); | |
| //add to the return array | |
| $a_return_attributes[] = $a_attributes; | |
| } | |
| } | |
| return $a_return_attributes; | |
| } | |
| public function findPreferenceValueInBlock( $a_prefernces_block = array(), $s_findme = '' ){ | |
| foreach( $a_prefernces_block as $row ){ | |
| foreach( $row as $key => $value ){ | |
| if( $key == $s_findme){ | |
| return $value; | |
| } | |
| } | |
| } | |
| } | |
| public function getCategories( $group = "" ){ | |
| //$this->d($group); | |
| $ret = array(); | |
| //this returns an element criteria model | |
| $o_criteria = craft()->elements->getCriteria(ElementType::Category); | |
| //set the model params - level 1 order by level limit 20! | |
| $o_criteria->groupId = str_replace('group:', '', $group); | |
| $o_criteria->order = 'level'; | |
| $o_criteria->level = 1; | |
| $o_criteria->limit = 20; | |
| //check we have some matching categories | |
| if( $o_criteria->getDescendants()->total() > 0 ){ | |
| //loop through | |
| foreach ($o_criteria as $o_entry) | |
| { | |
| //$this->p("Level 1: " . $o_entry->title); | |
| $ret[] = "Level 1: " . $o_entry->title; | |
| //if we have some children, i.e the next level down | |
| if( $o_entry->getDescendants()->total() > 0 ){ | |
| //get the current levels children | |
| $o_children = $o_entry->getChildren(); | |
| //loop each child | |
| foreach ($o_children as $d){ | |
| //$this->p(" Level 2: " . $d->title); | |
| $ret[] = " Level 2: " . $d->title; | |
| } | |
| } | |
| } | |
| } | |
| return $ret; | |
| } | |
| /** | |
| * Get the matrix block columns | |
| * we end up with a multi dimen array that looks like the matrik blocks we setup, top level, 2nd level and then third level | |
| * @param type $a_matrix_block_ids | |
| * @return type | |
| */ | |
| public function getTableColumns( $a_matrix_block_ids = array() ){ | |
| //the return array | |
| $a_block_colums = array(); | |
| //the current logged in user | |
| $o_user_model = craft()->userSession->getUser(); | |
| foreach( $a_matrix_block_ids as $key => $value ){ | |
| //the block name i.e contactPreferences | |
| $s_block_name = $key; | |
| //get all of the user prefernces (rows in the table i.e. craft_matrixcontent_contactpreference) for the current block | |
| $a_my_prefernce = $this->getPreferencesForMatrixBlock( $s_block_name ); | |
| //temp array to hold the current chunk of chunks! | |
| $a_tmps = array(); | |
| foreach( $value as $x ){ | |
| //these are the cunks! | |
| $a_tmp = array(); | |
| //craft_fields table id 158 = brochures, in the context table we want the matrix block type of 6 | |
| $i_matrix_block_id = $x['block_type_id']; | |
| //get the model | |
| $o_matrix_block_type_model = craft()->matrix->getBlockTypeById( $i_matrix_block_id ); | |
| //refernce this section by name | |
| $s_section = $o_matrix_block_type_model->name; | |
| //get the fields for the current model | |
| $a_fields = $o_matrix_block_type_model->getFieldLayout()->getFields(); | |
| //loop through the fields and grab the required data to be return ed as the chunk in the array | |
| foreach($a_fields as $o_field_layout_field_model) { | |
| //the current field from the layour loop | |
| $o_field = $o_field_layout_field_model->getField(); | |
| //create the array chunk | |
| $a_tmp[] = array( | |
| //block name | |
| 'blockname' => $s_block_name, | |
| //parent | |
| 'matrixBlockId' => $x['main_id'], // 145 - contact preferences | |
| //prefernce | |
| 'fieldId' => $x['block_type_id'], // craft_fields table id 158 = brochures, in the context table we want the matrix block type of 6 | |
| //others | |
| 'type' => $o_field->type, | |
| 'handle' => $o_field->handle, | |
| 'name' => $o_field->name, | |
| 'instructions' => $o_field->instructions, | |
| 'placeholder' => isset($o_field->settings['placeholder']) ? $o_field->settings['placeholder'] : null, | |
| 'options' => isset($o_field->settings['options']) ? $o_field->settings['options'] : null, | |
| //the preference value | |
| 'preference' => $this->findPreferenceValueInBlock( $a_my_prefernce, $o_field->handle ) | |
| ); | |
| if($o_field->type == 'Categories'){ | |
| $cats = $this->getCategories( $o_field->settings['source'] ); | |
| $this->d($cats); | |
| } | |
| $this->p($o_field); | |
| } | |
| //add the chunks to the chunk! | |
| $a_tmps[$s_section] = $a_tmp; | |
| } | |
| //add the chunk to the return array | |
| $a_block_colums[$s_block_name] = $a_tmps; | |
| } | |
| //$this->pr( $a_block_colums, true ); | |
| return $a_block_colums; | |
| } | |
| /** | |
| * In the front end design, some of the fields are grouped - such as telephone | |
| * this function will lopp through and group matching names in to their own array part | |
| * the front end then notices that there is not a type but and array and deals with it.. | |
| * @param type $a_table_columns | |
| * @return type | |
| */ | |
| public function groupforGui( $a_table_columns = array() ){ | |
| $a_groups = array( | |
| 'telephone' | |
| ); | |
| $a_grouped_columns = array(); | |
| /** | |
| * contactPreference | |
| * propertyPreference | |
| * etc.. | |
| */ | |
| foreach( $a_table_columns as $key => $x){ | |
| /** | |
| * Contact | |
| * Direct Mail | |
| * etc.. | |
| */ | |
| foreach( $x as $k => $y ){ | |
| $a_tmp = array(); | |
| $a_tmp_group = array(); | |
| /** | |
| * telephoneDaytime | |
| * telephoneEvening | |
| * etc.. | |
| */ | |
| foreach($y as $v ){ | |
| foreach( $a_groups as $s_current_group){ | |
| /** | |
| * telephone - is part of a group so add it to its own array | |
| */ | |
| if( strstr( $v['handle'] , $s_current_group) ){ | |
| $a_tmp_group[$s_current_group][] = $v; | |
| }else{ | |
| $a_tmp[] = $v; | |
| } | |
| } | |
| } | |
| if(!empty($a_tmp_group)){ | |
| if( count($a_tmp_group) > 1){ | |
| $a_tmp[] = $a_tmp_group; | |
| }else{ | |
| $a_first_element = reset($a_tmp_group); | |
| if( count($a_first_element) > 1){ | |
| $a_tmp[] = $a_tmp_group; | |
| }else{ | |
| $a_tmp[] = $a_first_element[0]; | |
| } | |
| } | |
| } | |
| /** | |
| * add to the return array | |
| */ | |
| $a_grouped_columns[$key][$k] = $a_tmp; | |
| } | |
| } | |
| return $a_grouped_columns; | |
| } | |
| /** | |
| * this is a test case function - | |
| * plug some numbers in and watch the prefernce change in the database | |
| * handy for getting the correct matrix id's | |
| * | |
| * If run this will break the preference page | |
| */ | |
| public function testCase(){ | |
| $parent = 145; | |
| $preference = 5; | |
| $value = '07702795435'; | |
| $handle = 'sms'; | |
| $blockname = 'contactPreference'; | |
| craft()->log->removeRoute('WebLogRoute'); | |
| craft()->log->removeRoute('ProfileLogRoute'); | |
| //clean the values | |
| if($value === true || $value === 'true' ){ | |
| $value = 1; | |
| } | |
| if($value === false || $value === 'false' ){ | |
| $value = 0; | |
| } | |
| //debug the posted vars | |
| // $this->pr(array( | |
| // | |
| // 'parent' => $parent, | |
| // 'preference' => $preference, | |
| // 'value' => $value, | |
| // 'handle' => $handle, | |
| // 'blockname' => $blockname | |
| // | |
| // ), true); | |
| //get the user model | |
| $o_user_model = craft()->userSession->getUser(); | |
| //see a row exists - actually a user will have a row for each element type so for one user may have 10 rows - crap no? | |
| if( $o_user_model->$blockname->count() ) { | |
| //null the block | |
| $block = null; | |
| //itterate through each of the existing blocks | |
| foreach( $o_user_model->$blockname->iterator as $o_current_block){ | |
| //get the attributes | |
| $a_attributes = $o_current_block->getContent()->getAttributes(); | |
| //if the attrubute exists in the loop block , the global block become a matrix object | |
| if( in_array($handle, array_keys($a_attributes)) ){ | |
| $block = $o_current_block; | |
| } | |
| } | |
| //though we had blocks they were the wrong blocks - go figure! | |
| if( is_null($block) ){ | |
| //create a new block wit the correct params | |
| $block = new MatrixBlockModel(); | |
| $block->fieldId = intval($parent); | |
| $block->ownerId = $o_user_model->id; | |
| $block->typeId = intval($preference); // ID of block type | |
| } | |
| } | |
| //the row did not exist so create a new row | |
| else { | |
| $block = new MatrixBlockModel(); | |
| $block->fieldId = intval($parent); | |
| $block->ownerId = $o_user_model->id; | |
| $block->typeId = intval($preference); // ID of block type | |
| } | |
| //now we have a block we can add the content | |
| $block->getContent()->setAttributes(array( | |
| (string)$handle => (string)$value | |
| )); | |
| if( craft()->matrix->saveBlock( $block ) ) { | |
| $a_errors = array(); | |
| echo json_encode(array( | |
| 'success' => 'ok', | |
| 'errors' => $a_errors, | |
| 'parent' => $parent, | |
| 'preference' => $preference, | |
| 'value' => $value, | |
| 'handle' => $handle, | |
| 'blockname' => $blockname, | |
| )); | |
| die(); | |
| } | |
| else { | |
| $a_errors = $block->getErrors(); | |
| echo json_encode(array( | |
| 'success' => 'fail', | |
| 'errors' => $a_errors, | |
| 'parent' => $parent, | |
| 'preference' => $preference, | |
| 'value' => $value, | |
| 'handle' => $handle, | |
| 'blockname' => $blockname, | |
| )); | |
| die(); | |
| } | |
| } | |
| /** | |
| * This function is called within the template to create a preference structure using the methods above | |
| * @return type | |
| */ | |
| public function test(){ | |
| $this->p(' --- BEGIN HERE --- '); | |
| $return = array(); | |
| //get the block ids | |
| $a_blockids = $this->getPreferenceIds(); | |
| //turn the block ids into columns that we can use in the front end | |
| $a_table_columns = $this->getTableColumns($a_blockids); | |
| //group the table columns so we can alter the front end gui | |
| $a_grouped_table_columns = $this->groupforGui($a_table_columns); | |
| //return the structure | |
| $this->p($a_grouped_table_columns); | |
| $this->d(' --- END HERE --- '); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment