I have created custom form from form API and I want to fetch records from DB and display below form after submit.
I have tried few reference with no success. Here is my code
public function submitForm(array &$form, FormStateInterface $form_state) {
$terms = db_query("select name from taxonomy_term_field_data where vid = 'category'");
$termsData = $terms->fetchAll();
$form_state->setRebuild();
$form_state->setStorage= $termsData;
$output = '';
foreach($termsData as $d){
$output .= $d->name;
}
$form_state->setStorage= $output;
return $output;
}
any help would be great.
If you want to use db_select use the following snippet
public function submitForm(array &$form, FormStateInterface $form_state) {
$db = \Drupal::database();
$terms = $db->select('taxonomy_term_field_data','tfd')->fields('tfd')->condition('vid','category')->execute();
$termsData = $terms->fetchAll();
$form_state->setRebuild();
$form_state->setStorage= $termsData;
$output = '';
foreach($termsData as $d){
$output .= $d->name;
}
$form_state->setStorage= $output;
return $output;
}
but I suggest do it by Entity API.for more information taking a look on Drupal Entity API on Drupal 8 and Drupal Entity Cheat Sheet
let me know if it doesn't work for you.
Related
In Silverstripe 4 I have a
DataObject 'PublicationObject',
a 'PublicationPage' and
a 'PublicationPageController'
PublicationObjects are displayed on PublicationPage through looping a PaginatedList. There is also a Pagination, showing the PageNumbers and Prev & Next - Links.
The Detail of PublicationObject is shown as 'Dataobject as Pages' using the UrlSegment.
If users are on the Detail- PublicationObject i want them to get back to the PublicationPage (the paginated list) with a Back - Link.
Two situations:
The user came from PublicationPage
and
The User came from a Search - Engine (Google) directly to the
DataObject- Detail.
I have done this like so:
$parentPage = Page::get()->Filter(array('UrlSegment' => $request->param('pageID')))->First();
$back = $_SERVER['HTTP_REFERER'];
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
$back = $parentPage->Link();
}
}
Thats not satisfying.
Question:
How do i get the Pagination - Link ( e.g: ...publicationen?start=20 ) when we are on the Detail - DataObject? How can we find the Position of the current Dataobject in that paginatedList in correlation with the Items per Page? (The Page- Link This Dataobject is on)
<?php
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\View\Requirements;
use SilverStripe\Core\Convert;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\ORM\PaginatedList;
use SilverStripe\Control\Director;
use SilverStripe\ORM\DataObject;
use SilverStripe\ErrorPage\ErrorPage;
use SilverStripe\Dev\Debug;
use SilverStripe\Dev\Backtrace;
class PublicationPageController extends PageController
{
private static $allowed_actions = ['detail'];
private static $url_handlers = array(
);
public static $current_Publication_id;
public function init() {
parent::init();
}
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
if (!$publication) {
return ErrorPage::response_for(404);
}
// HERE I WANT TO FIND THE POSITION OF THE DATAOBJECT IN THE PAGINATEDLIST OR RATHER THE PAGE - LINK THIS DATAOBJECT IS IN
//$paginatedList = $this->getPaginatedPublicationObjects();
//Debug::show($paginatedList->find('URLSegment', Convert::raw2sql($request->param('ID'))));
//Debug::show($paginatedList->toArray());
$parentPage = Page::get()->Filter(array('UrlSegment' => $request->param('pageID')))->First();
$back = $_SERVER['HTTP_REFERER'];
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
$back = $parentPage->Link();
}
}
static::$current_Publication_id = $publication->ID;
$id = $publication->ID;
if($publication){
$arrayData = array (
'Publication' => $publication,
'Back' => $back,
'SubTitle' => $publication->Title,
'MetaTitle' => $publication->Title,
);
return $this->customise($arrayData)->renderWith(array('PublicationDetailPage', 'Page'));
}else{
return $this->httpError(404, "Not Found");
}
}
public function getPaginatedPublicationObjects()
{
$list = $this->PublicationObjects()->sort('SortOrder');
return PaginatedList::create($list, $this->getRequest()); //->setPageLength(4)->setPaginationGetVar('start');
}
}
EDIT:
is there a more simple solution ? than this ? :
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
if (!$publication) {
return ErrorPage::response_for(404);
}
//*******************************************************
// CREATE BACK - LINK
$paginatedList = $this->getPaginatedPublicationObjects();
$dO = PublicationObject::get();
$paginationVar = $paginatedList->getPaginationGetVar();
$sqlQuery = new SQLSelect();
$sqlQuery->setFrom('PublicationObject');
$sqlQuery->selectField('URLSegment');
$sqlQuery->setOrderBy('SortOrder');
$rawSQL = $sqlQuery->sql($parameters);
$result = $sqlQuery->execute();
$list = [];
foreach($result as $row) {
$list[]['URLSegment'] = $row['URLSegment'];
}
$list = array_chunk($list, $paginatedList->getPageLength(), true);
$start = '';
$back = '';
$i = 0;
$newArray = [];
foreach ($list as $k => $subArr) {
$newArray[$i] = $subArr;
unset($subArr[$k]['URLSegment']);
foreach ($newArray[$i] as $key => $val) {
if ($val['URLSegment'] === Convert::raw2sql($request->param('ID'))) {
$start = '?'.$paginationVar.'='.$i;
}
}
$i = $i + $paginatedList->getPageLength();
}
$back = Controller::join_links($this->Link(), $start);
// END CREATE BACK - LINK
//*****************************************************
static::$current_Publication_id = $publication->ID;
$id = $publication->ID;
if($publication){
$arrayData = array (
'Publication' => $publication,
'Back' => $back,
'MyLinkMode' => 'active',
'SubTitle' => $publication->Title,
'MetaTitle' => $publication->Title,
);
return $this->customise($arrayData)->renderWith(array('PublicationDetailPage', 'Page'));
}else{
return $this->httpError(404, "Not Found");
}
}
You can simply pass the page number as a get var in the URL from the PublicationPage. The detail() method can then grab the get var and if there's a value for the page number passed in, add it to the back link's URL.
In the template:
<% loop $MyPaginatedList %>
Click me
<% end_loop %>
In your controller's detail() method:
$pageNum = $request->getVar('onPage');
if ($pageNum) {
// Add the pagenum to the back link here
}
Edit
You've expressed that you want this to use the page start offset (so you can just plug it into the url using ?start=[offset]), and that you want an example that also covers people coming in from outside your site. I therefore propose the following:
Do as above, but using PageStart instead of CurrentPage - this will mean you don't have to re-compute the offset any time someone clicks the link from your paginated list.
If there is no onPage (or pageOffset as I've renamed it below, assuming you'll use PageStart) get variable, then assuming you can ensure your SortOrder values are all unique, you can check how many items are in the list before the current item - which gives you your item offset. From that you can calculate what page it's on, and what the page offset is for that page, which is your start value.
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
$paginatedList = $this->getPaginatedPublicationObjects();
// Back link logic starts here
$pageOffset = $request->getVar('pageOffset');
if ($pageOffset === null) {
$recordOffset = $paginatedList->filter('SortOrder:LessThan', $publication->SortOrder)->count() + 1;
$perPage = $paginatedList->getPageLength();
$page = floor($recordOffset / $perPage) + 1;
$pageOffset = ($page - 1) * $perPage;
}
$back = $this->Link() . '?' . $paginatedList->getPaginationGetVar() . '=' . $pageOffset;
// Back link logic ends here
//.....
}
I have created a model and added the $has_many for selecting multiple products. This is working fine but I am unable to make the selected products sortable by drag and drop. I know this is possible I have seen it. But I am unable to find anything in the documentation that shows how to get this done. Here is my model:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(FUEL_PATH.'models/Base_module_model.php');
/**
* This model handles setting up the form fields for our contact form
*
*/
class Products_category_model extends Base_module_model {
public $required = array('name', 'published');
public $has_many = array('products' => array(FUEL_FOLDER => 'Products_model'));
function __construct()
{
parent::__construct('w_product_categories');
}
/*
This will provide the list of records for display in the Admin Panel
Note how the "excerpt" will display, but truncated
Because we are using some MySQL functions in our select statement,
we pass FALSE in as the second parament to prevent CI auto escaping of fields
*/
function list_items($limit = null, $offset = null, $col = 'name', $order = 'asc', $just_count = false)
{
$this->db->select('id, name, published', FALSE);
$data = parent::list_items($limit, $offset, $col, $order);
return $data;
}
function form_fields($values = array(), $related = array())
{
$fields = parent::form_fields($values, $related);
return $fields;
}
}
class Product_category_model extends Base_module_record {
}
So it is very simple I discovered. I added this in the form fields function:
// Makes the has many drag and drop sortable.
$fields['products']['sorting'] = TRUE;
$fields['products']['after_html'] = "<div style=\"clear:both;font-style:italic\">NOTE: you can sort selected product to your choosing by clicking on the product and then dragging it into the desired placement in the list</div>";
With lumen, I have the problem that this is always 1, also when I go to /artikel?page=2:
LengthAwarePaginator::resolveCurrentPage();
the complete code:
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class ArtikelController extends Controller {
public function index()
{
$dir = '../resources/views/artikel/';
$files = array_diff(scandir($dir), array('..', '.'));
$artikel = array();
foreach($files as $k => $v)
{
$id = substr($v,0,1);
$artikel[$id]['id'] = $id;
$artikel[$id]['name'] = substr($v,0,strpos($v,'.blade.php'));
}
//Get current page form url e.g. &page=6
$currentPage = LengthAwarePaginator::resolveCurrentPage();
#dd($currentPage);
//Create a new Laravel collection from the array data
$collection = new Collection($artikel);
//Define how many items we want to be visible in each page
$perPage = 2;
//Slice the collection to get the items to display in current page
$currentPageResults = $collection->slice($currentPage * $perPage, $perPage)->sortByDesc('id')->all();
//Create our paginator and pass it to the view
$paginatedResults = new LengthAwarePaginator($currentPageResults, count($collection), $perPage);
$paginatedResults->setPath('artikel');
return view('artikel', ['artikel' => $paginatedResults]);
}
I can't find the mistake. What could be the reason? (I have also updated to "laravel/lumen-framework": "5.1.*")
You can use this simple way to get your current page:
$currentPage = (int) app('request')->get('page', $default = '0');
I'm writing a plug-in for my component. For this component I have table "#__radiocatalog_item" with columns id, name, description, and I need to lookup at column name. For this, I wrote this plugin:
<?php
defined('JPATH_BASE') or die;
require_once JPATH_ADMINISTRATOR.'/components/com_finder/helpers/indexer/adapter.php';
class PlgFinderRadioitem extends FinderIndexerAdapter
{
protected $context = 'Radioitem';
protected $extension = 'com_radiocatalog';
protected $layout = 'item';
protected $type_title = 'item';
protected $table = '#__radiocatalog_item';
protected $state_field = 'parent';
protected $autoloadLanguage = true;
protected function setup()
{
return true;
}
public function onFinderDelete($context, $table)
{
if ($context == 'com_radiocatalog.item')
{
$id = $table->id;
}
elseif ($context == 'com_finder.index')
{
$id = $table->id;
}
else
{
return true;
}
return $this->remove($id);
}
public function onFinderChangeState($context, $pks, $value)
{
if ($context == 'com_radiocatalog.item')
{
$this->itemStateChange($pks, $value);
}
if ($context == 'com_plugins.plugin' && $value === 0)
{
$this->pluginDisable($pks);
}
}
protected function index(FinderIndexerResult $item, $format = 'html')
{
if (JComponentHelper::isEnabled($this->extension) == false)
{
return;
}
$item->url = $this->getURL($item->id, 'com_radiocatalog&layout=item', $this->layout);
$item->route = 'index.php?option=com_radiocatalog&view=item&layout=item&id='.$item->id;
$item->addTaxonomy('Type', 'Radioitems');
$item->addTaxonomy('Language', $item->language);
$this->indexer->index($item);
}
protected function getListQuery($sql = null)
{
$db = JFactory::getDbo();
$sql = $sql instanceof JDatabaseQuery ? $sql : $db->getQuery(true);
$sql->select('a.id as id, a.name as title, a.description as description');
$sql->from('#__radiocatalog_item AS a');
return $sql;
}
protected function getStateQuery()
{
$sql = $this->db->getQuery(true);
$sql->select($this->db->quoteName('a.id'));
$sql->select($this->db->quoteName('a.name').' as title');
$sql->from($this->db->quoteName('#__radiocatalog_item') . ' AS a');
return $sql;
}
}
?>
After full indexing, search on the site does not work.
I was struggling with the same problem. So I enabled Joomla debugging {Global Configuration / System / Debug System = true} and tried to search for a term "myterm" using public site SmartSearch module. Then I checked the performed SQL queries. First, the term was found:
SELECT t.term, t.term_id
FROM j_finder_terms AS t
WHERE t.term = 'myterm'
AND t.phrase = 0
with ID=653 (used later):
SELECT l.link_id,m.weight AS ordering
FROM `j_finder_links` AS l
INNER JOIN `j_finder_links_terms2` AS m
ON m.link_id = l.link_id
WHERE l.access IN (1,1)
AND l.state = 1
AND (l.publish_start_date = '0000-00-00 00:00:00' OR l.publish_end_date <= '2014-01-04 17:34:00')
AND (l.publish_end_date = '0000-00-00 00:00:00' OR l.publish_end_date >= '2014-01-04 17:34:00')
AND m.term_id IN (653)
But this query didn't return any result, because j_finder_links.access and j_finder_links.state values were set to 0 instead of 1.
So my suggest you to check the queries and if you have the same problem, try to change your query from getStateQuery() method or select "1 AS access, 1 AS state" in the getListQuery() query and leave the $state_field variable unset.
I'm sorry for a vague explanation, I don't know much about how the SmartSearch work, I'm just trying to make it work somehow with my component.
I'm new to drupal, and very new to panels. I have a custom module which displays rss feed items based on user taxonomy. It displays the correct info as a block, but it needs to be on the users' dashboard page, which uses panels. When I try to insert it, it is always blank.
The code inserts a default view I already created, showing all feed items (1_feeds_defaults_feed_items) into a block. I can't edit it to work in a panel. I imagine that there are 10 different things I may have done wrong, but have tried every permutation I can think of.
<?php
//.this function generates a block and calls the second
//function for the content of this block
function custom_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$block[0]['info'] = 'Custom View';
$block[2]['cache'] = BLOCK_NO_CACHE;
return $block;
break;
case 'view':
switch ($delta) {
case 0:
$block['subject'] = '';
$block['content'] = custom_userfeeds() ;
break;
}
return $block;
}
}
function custom_userfeeds() {
//finds the user id from argument on user page.
//You can also find the user id the way the page you linked me to did,
//but if you do it the way I am below it would allow admins
//to view other users feeds
$uid = arg(1);
//loads the profile node -- 'profile' is the profile content type.
$node = content_profile_load('profile', $uid);
//find the terms associated with the user's profile
if ($node && $node->taxonomy) {
foreach($node->taxonomy as $term) {
$terms[] = $term->tid;
}
}
//embeds a view with those terms passed to it.
View display is something like block_1 or page_1
if($terms) {
$t = implode('+',$terms);
return views_embed_view("1_feeds_defaults_feed_items","page_1", $t);
}
}
Here is how I fixed it in a view:
-Add Argument -> Taxonomy -> Taxonomy Term ID
-Provide default argument
-PHP Code
-PHP argument code:
global $user;
$query = "SELECT tid FROM {term_user} WHERE uid = %d";
$result = db_query($query, $user->uid);
if ($result) {
$terms = array();
while ($term = db_fetch_array($result)) {
$terms[] = $term['tid'];
}
if ($terms) {
$termargs = implode("+", $terms);
return $termargs;
}
}
else {
return FALSE;
}
-Check "Allow multiple terms per argument."