Is there a way to query entries and categories together in Craft 3? - search

'm working on a global site search ( autocomplete ), right now it have almost all entries ( that have uri defined ) for results, it uses js fetch and Craft element api in a json file that filter results based on a query string. Works great!
I was wondering if it's possible to add to the query categories too, i don't know if this is possible buy maybe it's a way to merge them, here is my json api code, thanks!
'search.json' => function() {
$qParam = Craft::$app->request->getParam('q');
return [
'elementType' => Entry::class,
'paginate' => false,
'criteria' => [
'uri'=> ':notempty:',
'search' => $qParam,
'orderBy' => 'score',
'limit' => 20,
],
'cache' => false,
'transformer' => function(Entry $item) {
return [
'title' => $item->title,
'url' => $item->url,
];
},
];
}

Related

Gremlin groupCount, order and limit

I am currently using gremlin with aws neptune cluster and using nodejs for development. I have find friends with same interest and order by mutual interest count. I need to limit results to top 2.
const res = await g.V().has('user', 'name', 'Waruna').as('u')
.out('like').in_('like')
.where(P.neq('u'))
.valueMap()
.by(gremlin.process.statics.unfold())
.groupCount()
.order(gremlin.process.scope.local)
.by(gremlin.process.column.values, gremlin.process.order.desc)
.limit(2)
.toList();
console.log('RESULTS', res);
Results:
RESULTS [
Map {
Map { 'name' => 'Dimuthu', 'age' => 30 } => 2,
Map { 'name' => 'Kamal', 'age' => 25 } => 1,
Map { 'name' => 'Amal', 'age' => 34 } => 1,
Map { 'name' => 'Dhanushka', 'age' => 40 } => 1,
Map { 'name' => 'Sunimal', 'age' => 28 } => 1
}
]
Though I limit query to 2 it is not working. It resulted all nodes.
After the groupCount step you have essentially created a single map structure. So the limit(2) does nothing as that map is considered one entity. If you add an unfold() before the limit(2) you should get just two results. Bear in mind if the map created by groupCount has the potential to become large you may want to consider ways to filter the results sooner. As an alternative you can give the limit step local scope using limit(local,2).

Typo3: Where can i get list of TCA types?

I have bodytext and image so like this type of list where can I found? Can I get page list in select box?
$GLOBALS['TCA']['tt_content']['types']['text_image_left'] = [
'showitem' => '
--palette--;palette.general;general,
header, subheader, header_layout,menu,
bodytext;bodytext_formlabel,
--div--;tabs.images,
image,
--div--;tabs.appearance,
--palette--;palette.frames;frames,
--div--;tabs.access,
hidden;field.default.hidden,
--div--;tabs.extended
',
'columnsOverrides' => ['bodytext' => ['config' => ['enableRichtext' => true]]]
];
Hm, not sure if I get your question right. You asked
1. for a list of TCA types
2. how to get a list of pages in a select field (?)
You can find the complete TCA Documentation here:
https://docs.typo3.org/m/typo3/reference-tca/master/en-us/
Interesting part for you is the [column][*][config] part:
https://docs.typo3.org/m/typo3/reference-tca/master/en-us/ColumnsConfig/Index.html
In order to create a select with a page list, you need following kind of configuration.
I would suggest to use "group" type for field.
'page' => [
'exclude' => true,
'label' => 'List of Pages',
'config' => [
'type' => 'group',
'internal_type' => 'db',
'allowed' => 'pages',
'size' => 1,
'minitems' => 0,
'maxitems' => 1,
]
]

Wordpress Custom taxonomy dropdown list array to tagdiv composer

I am currently working on a new wordpress website which uses the Newspaper theme, which lets me compose pages with the tagdiv composer plugin.
This plugin makes it fairly easy to show posts of your choosing; with blocks/modules that have built in filters, that allow you to select the posts to be shown based upon the categories, authors, etc. that you choose.
However I would like to show custom taxonomies in there as well, so that I can choose for instance album reviews, which have the custom taxonomy of the letter A attached to it.
For my client I would need to do that since he requested a glossary (alphabetical index).
So far I have created a custom taxonomy called "alphabetical_letter", which houses all 26 characters with the linked posts to it.
The code which I need to alter is this one, preferrably I'd have a drop down list. However I keep failing in getting it right. Could anyone point me in the right direction please ?
/**
* the filter array (used by blocks and by the loop filters)
* #return array
*/
static function get_map_filter_array ($group = 'Filter') {
return array(
array(
"param_name" => "separator",
"type" => "text_separator",
'heading' => 'Filters',
"value" => "",
"class" => "",
'group' => $group
),
array(
"param_name" => "post_ids",
"type" => "textfield",
"value" => '',
"heading" => 'Post ID filter:',
"description" => "Filter multiple posts by ID. Enter here the post IDs separated by commas (ex: 10,27,233). To exclude posts from this block add them with '-' (ex: -7, -16)",
"holder" => "div",
"class" => "tdc-textfield-big",
'group' => $group
),
array(
"param_name" => "category_id",
"type" => "dropdown",
"value" => td_util::get_category2id_array(),
"heading" => 'Category filter:',
"description" => "A single category filter. If you want to filter multiple categories, use the 'Multiple categories filter' and leave this to default",
"holder" => "div",
"class" => "tdc-dropdown-big",
'group' => $group
),
array(
"param_name" => "category_ids",
"type" => "textfield",
"value" => '',
"heading" => 'Multiple categories filter:',
"description" => "Filter multiple categories by ID. Enter here the category IDs separated by commas (ex: 13,23,18). To exclude categories from this block add them with '-' (ex: -9, -10)",
"holder" => "div",
"class" => "tdc-textfield-big",
'group' => $group
),
array(
"param_name" => "alphabetical_letter_id",
"type" => "dropdown",
"value" => td_util::get_alphabetical_letter_id_array(),
"heading" => 'Custom taxonomy:',
"description" => "alphabetical letter custom taxonomy",
"holder" => "div",
"class" => "tdc-dropdown-big",
'group' => $group
),
array(
"param_name" => "tag_slug",
"type" => "textfield",
"value" => '',
"heading" => 'Filter by tag slug:',
"description" => "To filter multiple tag slugs, enter here the tag slugs separated by commas (ex: tag1,tag2,tag3)",
"holder" => "div",
"class" => "tdc-textfield-big",
'group' => $group
),`enter code here`
Edit:
in the meantime I have tried to figure out the td_util I keep seeing.
There is a file called td_util.php one folder up from where this file is, and it mentions the category2id_array so I am currently trying to find out if the problem lies here.
for completeness, this is the bit of text that refers to the category2id array function above (or the other way around more likely).
/**
* generates a category tree, only on /wp_admin/, uses a buffer
* #param bool $add_all_category = if true ads - All categories - at the begining of the list (used for dropdowns)
* #return array
*/
private static $td_category2id_array_walker_buffer = array();
static function get_category2id_array($add_all_category = true) {
if (is_admin() === false) {
return array();
}
if (empty(self::$td_category2id_array_walker_buffer)) {
$categories = get_categories(array(
'hide_empty' => 0,
'number' => 1500
));
$td_category2id_array_walker = new td_category2id_array_walker;
$td_category2id_array_walker->walk($categories, 4);
self::$td_category2id_array_walker_buffer = $td_category2id_array_walker->td_array_buffer;
}
if ($add_all_category === true) {
$categories_buffer['- All categories -'] = '';
return array_merge(
$categories_buffer,
self::$td_category2id_array_walker_buffer
);
} else {
return self::$td_category2id_array_walker_buffer;
}
}
And a bit further down the file it pops up one last time
class td_category2id_array_walker extends Walker {
var $tree_type = 'category';
var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
var $td_array_buffer = array();
function start_lvl( &$output, $depth = 0, $args = array() ) {
}
function end_lvl( &$output, $depth = 0, $args = array() ) {
}
function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
$this->td_array_buffer[str_repeat(' - ', $depth) . $category->name . ' - [ id: ' . $category->term_id . ' ]' ] = $category->term_id;
}
function end_el( &$output, $page, $depth = 0, $args = array() ) {
}
}

how to create search field in gridview without using search model

I have created sqlDataProvider in my controller and its working. My problem is i dont know how to provide search field since im not using the search model.
this is code in my controller
public function actionAnalisa()
{
$sql = "SELECT
tbl_permohonan.permohonan_id As permohonan_id,
user.id As id,
tbl_moderator.bm_id As bm_id,
tbl_bhgnmod.unit_kampuscawangan As unit_kampuscawangan,
tbl_bahagian.bahagian_nama As bahagian_nama,
tbl_unit.unit_nama As unit_nama
FROM tbl_permohonan
INNER JOIN user
ON tbl_permohonan.user_id=user.id
INNER JOIN tbl_moderator
ON user.id=tbl_moderator.user_id
INNER JOIN tbl_bhgnmod
ON tbl_moderator.bm_id=tbl_bhgnmod.bm_id
INNER JOIN tbl_bahagian
ON tbl_bhgnmod.bahagian_id=tbl_bahagian.bahagian_id
INNER JOIN tbl_unit
ON tbl_bhgnmod.unit_id=tbl_unit.unit_id";
$dataProvider = new SqlDataProvider([
'sql' => $sql,
]);
return $this->render('analisis', [
// 'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
this is in my view
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'permohonan_id',
'id',
'bm_id',
'unit_kampuscawangan',
'bahagian_nama',
'unit_nama',
//~ ['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I would advise against using raw SQL, especially when looking to provide search fields, since this provides a potential vulnerability within the application and opens it up to possibility of SQL injection attacks. Instead I would encourage the use of Yiis query builder or DAO, as is outlined here.
With that said, I have rewritten your code using Yiis inbuilt query builder.
public function actionAnalisa()
{
// store any $_GET parameters passed for filtering via GridView
$params = Yii::$app->request->queryParams;
// use query builder instead of raw SQL to avoid SQL injection attacks
$query = (new Query())
->select([
'permohonan_id' => 'tbl_permohonan.permohonan_id',
'id' => 'user.id',
'bm_id' => 'tbl_moderator.bm_id',
'unit_kampuscawangan' => 'tbl_bhgnmod.unit_kampuscawangan',
'bahagian_nama' => 'tbl_bahagian.bahagian_nama',
'unit_nama' => 'tbl_unit.unit_nama'
])
->from('tbl_permohonan')
->join('INNER JOIN', 'user', 'tbl_permohonan.user_id=user.id')
->join('INNER JOIN', 'tbl_moderator', 'user.id=tbl_moderator.user_id')
->join('INNER JOIN', 'tbl_bhgnmod', 'tbl_moderator.bm_id=tbl_bhgnmod.bm_id')
->join('INNER JOIN', 'tbl_bahagian', 'tbl_bhgnmod.bahagian_id=tbl_bahagian.bahagian_id')
->join('INNER JOIN', 'tbl_unit', 'tbl_bhgnmod.unit_id=tbl_unit.unit_id');
// Adds additional WHERE conditions to the existing query but ignores empty operands
$query->andFilterWhere(['like', 'tbl_permohonan.permohonan_id', $params['pid']])
->andFilterWhere(['like', 'user.id', $params['id']])
->andFilterWhere(['like', 'tbl_moderator.bm_id', $params['bm_id']])
->andFilterWhere(['like', 'tbl_bhgnmod.unit_kampuscawangan', $params['unitk']])
->andFilterWhere(['like', 'tbl_bahagian.bahagian_nama', $params['banama']])
->andFilterWhere(['like', 'tbl_unit.unit_nama', $params['unnama']]);
// an ActiveDataProvider will accept a Query object instead of raw SQL
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
return $this->render('analisis', [
'dataProvider' => $dataProvider,
]);
}
Bare in mind, you will have to add the following to the top of the controller file.
use yii\data\ActiveDataProvider;
use yii\db\Query;
In order to render search fields within the GridView of your view file, you have to specify a filterModel, as is explained here.
Columns within the GridView allow you to specify a filter attribute, which will render a filter cell at the top of the column using HTML specified by the attribute. These filters are automatically submitted via GET to the same page, which is why they have been handled in the controller using the names specified within this GridView.
<?
use yii\helpers\Html;
use yii\grid\GridView;
?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
// filterModel must be set to render filter cells within GridView
'filterModel' => true,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
// specify attribute to display
'attribute' => 'permohonan_id',
// filter attribute accepts HTML to render
// in this case an input field of type string, with a name of 'pid'
'filter' => Html::input('string', 'pid')
],
[
'attribute' => 'id',
'filter' => Html::input('string', 'id')
],
[
'attribute' => 'bm_id',
'filter' => Html::input('string', 'bmid')
],
[
'attribute' => 'unit_kampuscawangan',
'filter' => Html::input('string', 'unitk')
],
[
'attribute' => 'bahagian_nama',
'filter' => Html::input('string', 'banama')
],
[
'attribute' => 'unit_nama',
'filter' => Html::input('string', 'unnama')
],
],
]); ?>

Yii2 Search model without using GridView

There is a serch form on the mainpage of a realestate agency. The data about objects is stored in the table "realty" that uses relations. For example, there are related tables category (residential, commercial, land plots), deal (buy, sell, rent), object_type (apartment, house, office).
Then different categories have different properties and and there are three bootstrap tabs in the search form: residential, commercial, land plots. Under each tab there are selects and input fields that are specific for the choosen tab.
In the most cases, the examples of using Search model are given within a gridview.
Is it possible to adapt Search model logic so that it could return the array of results from the table 'realty' based on the values indicated in the search form on the mainpage ?
Yes, of course you can. you have several options:
Solution 1 - worst solution but the answer to your question
modify the search function of the model (or create a new function). The search functions usually looks like this
public function search($params)
{
$query = Bookmark::find()->where('status <> "deleted"');
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => Yii::$app->session->get(get_parent_class($this) . 'Pagination'),
],
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere([
'status' => $this->status,
'id' => $this->id,
'reminder' => $this->reminder,
'order' => $this->order,
'update_time' => $this->update_time,
'update_by' => $this->update_by,
'create_time' => $this->create_time,
'create_by' => Yii::$app->user->id,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'url', $this->url]);
return $dataProvider;
}
You can change it to something like
public function search($params)
{
$query = Bookmark::find()->where('status <> "deleted"');
if (!($this->load($params) && $this->validate())) {
THROW AN ERROR SOMEHOW HERE
}
$query->andFilterWhere([
'status' => $this->status,
'id' => $this->id,
'reminder' => $this->reminder,
'order' => $this->order,
'update_time' => $this->update_time,
'update_by' => $this->update_by,
'create_time' => $this->create_time,
'create_by' => Yii::$app->user->id,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'url', $this->url]);
return $query->all();
}
however this will return to you all the records because ActiveDataProvider takes care of the pagination based on the query given.
Solution 2, a better solution
read the first example here http://www.yiiframework.com/doc-2.0/yii-data-activedataprovider.html . You can call ->getModels() on an ActiveDataProvider to get the actual records. No changes needed to the search function. Do whatever you want with the array.
Solution 3 and what I use all the time
Use ActiveDataProvider with a ListView. The list view allows you to create the list of records however you want, it does not have to be a table. I personally do this in many places and it works quite well. I sometimes transform arrays to an ArrayDataProvider just to use it. More about data providers here: http://www.yiiframework.com/doc-2.0/guide-output-data-providers.html

Resources