I'm trying to implement a function to be able to add directional (up / down) icons next to each of the table headers for a pagination table within CakePHP.
My current code is as follows:
$sort_key = $this->Paginator->sortKey();
$type = $this->Paginator->sortDir() === 'asc' ? 'up' : 'down';
function sortArrows($key, $title, $sort_key, $type)
{
$type_opposite = ($type === 'asc' ? 'down' : 'up');
if($key == $sort_key)
{
$icon = " <i class='fa fa-angle-" . $type . "'></i>";
}
else
{
$icon = " <i class='fa fa-angle-" . $type_opposite . "'></i>";
}
return "'$key', '$title' " . "$icon";
}
Which I am calling on the page as (on each of the table header fields):
<?php echo $this->Paginator->sort(sortArrows('street_suburb', 'Suburb', $sort_key, $type), array('escape' => false)); ?>
This produces the following error:
Notice (8): Array to string conversion [CORE/Cake/View/Helper/HtmlHelper.php, line 372]
I think I am quite close to what I need, I just cannot figure out what I am returning incorrectly from the function to get this to work.
Thanks
Inspired by your solution I have created a Helper extending PaginatorHelper to solve the problem.
Here is the code of file name MyPaginatorHelper.php:
<?php
namespace App\View\Helper;
use Cake\View\Helper\PaginatorHelper;
use Cake\Utility\Inflector;
class MyPaginatorHelper extends PaginatorHelper
{
public function sort($key, $title = null, array $options = [])
{
if (empty($title)) {
$title = $key;
if (strpos($title, '.') !== false) {
$title = str_replace('.', ' ', $title);
}
$title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
}
$sortKey = $this->sortKey();
if (strpos($sortKey, '.') !== false) {
$sortKey = substr($sortKey, strpos($sortKey, '.')+1);
}
$sortDir = $this->sortDir() === 'asc' ? 'up' : 'down';
if($key == $sortKey)
{
$title .= " <i class='fa fa-angle-" . $sortDir . "'></i>";
$options['escape'] = false;
}
return parent::sort($key, $title, $options);
}
}
To use this helper you have to add this line in the AppView::initialize() method:
$this->loadHelper('Paginator', ['className' => 'MyPaginator']);
And then all the Paginator->sort() calls will have this feature by default.
I ended up coming up with a solution however I don't know if it is the best way around it. It does work however.
<?php
$sort_key = $this->Paginator->sortKey();
$type = $this->Paginator->sortDir() === 'asc' ? 'up' : 'down';
function sortArrows($key, $title, $sort_key, $type)
{
if($key == $sort_key)
{
$icon = " <i class='fa fa-angle-" . $type . "'></i>";
return $title . " " . $icon;
}
else
{
return $title;
}
}
?>
Called like:
<?php echo $this->Paginator->sort('street_suburb', sortArrows('street_suburb', 'Suburb', $sort_key, $type), array('escape' => false)); ?>
Related
I have the function displayName in php that returns a string like this:
"${name} <i class=\"fa fa-check-circle\" style=\"font-size:22px;color:green\"/>"
public function getDisplayName()
{
/** #var Module $module */
$module = Yii::$app->getModule('user');
if ($module->displayNameCallback !== null) {
return call_user_func($module->displayNameCallback, $this);
}
$name = '';
$format = Yii::$app->settings->get('displayNameFormat');
if ($this->profile !== null && $format == '{profile.firstname} {profile.lastname}') {
$name = $this->profile->firstname . ' ' . $this->profile->lastname;
if (($this->profile->user_id == 1)){
$check_mark = '<i class="fa fa-check-circle" style="font-size:22px;color:green"/>';
}
else{
$check_mark = '';
}
}
// Return always username as fallback
if ($name == '' || $name == ' ') {
return $this->username;
}
return $name . ' '. $check_mark;
}
I call that function in my component like this:
public function run() {
return $this->render('containerProfileHeader', [ 'title' => $this->title, ]);
}
<h1 class="<?= $classPrefix ?>"><?= Html::encode($title) ?></h1>
public function init() {
parent::init();
$this->title = $this->container->getDisplayName();
}
The expectation was having the string returned by getDisplayName() rendered in the html as is but instead I've got this:
Issue resolved from
<?= Yii::$app->formatter->asHtml($title); ?>
Used
Yii::$app->formatter->asHtml instead of Html::encode
You should try echo() functions in the return function. I hope it will work.
I have a SilverStripe (3.4) Page with a form that would work if I didn't have a DataObject in it.
public function AntwortForm($ID) {
$Nummer = Vortest_Fragen::get()->byID($ID);
if ($Nummer) {
$Art=$Nummer->Art;
}
if ($Art == 'Normal') {
$fields = new FieldList(
TextAreaField::create('Antwort'),
HiddenField::create('ID', 'ID', $ID),
HiddenField::create('VortestID', 'VortestID', $this->request->param('ID')),
HiddenField::create('Aktion', 'Aktion', $this->request->param('Action'))
);
} else {
$Optionen = explode(';', $Nummer->Optionen);
$a = 'A';
for ( $i = 0 ; $i < count ($Optionen); $i++) {
$Op[$a] ='<div style="width:25px;display:inline;">' . $a . ')</div> ' . $Optionen[$i];
$a++;
}
$fields = new FieldList(
CheckboxSetField::create('Antwort', 'Antwort', $Op),
HiddenField::create('ID', 'ID', $ID),
HiddenField::create('VortestID', 'VortestID', $this->request->param('ID')),
HiddenField::create('Aktion', 'Aktion',$this->request->param('Action')),
HiddenField::create('Art', 'Art', $Nummer->Art)
);
}
$actions = new FieldList(
FormAction::create('AntwortEintragen', 'Eintragen')
);
$form = new Form($this, 'AntwortForm', $fields, $actions);
return $form;
}
function AntwortEintragen($data, $form) {
$Antwort = Vortest_Antwort::get()->filter(array('FrageID' => $data['ID'], 'SchreiberID' => Member::currentUserID()));
foreach($Antwort as $item) {
$item->delete();
}
foreach ($data['Antwort'] as $Antwort) {
$Ant .= $Antwort . ',';
}
$Antwort = new Vortest_Antwort();
if ($data['Antwort']) {
$form->saveInto($Antwort);
if ($data['Art'] == 'Mechanics') {
$Antwort->Antwort = $Ant;
}
$Antwort->SchreiberID = Member::currentUserID();
$Antwort->FrageID = $data['ID'];
$Antwort->write();
}
$VID = $data['VortestID'];
if ($data['Aktion'] == 'AlleFragen') {
$this->redirect('/vortest/AlleFragen/' . $VID . '#' . $data['FrageNr']);
} elseif ($data['Aktion'] == 'Einzelfrage') {
$this->redirect('/vortest/Einzelfrage/' . $VID);
} else {
$this->redirect('/vortest/Test/' . $VID.'#' . $data['FrageNr']);
}
}
It works when I change the $ID to a number in this line $Nummer = Vortest_Fragen::get()->byID($ID);
When I don't change it I get the following error:
[Recoverable Error] Object of class SS_HTTPRequest could not be converted to string
How do I fix this problem?
Althought it is not clearly documented, Silverstripe secretly passes a request argument to and form methods on a controller. Your $ID argument is actually not what you think it is, you will find it is actually an SS_HTTPRequest object that Silverstripe has passed (without you realising).
To fix this, change the first line:
public function AntwortForm($ID) {
To:
public function AntwortForm($request, $ID) {
And make sure you update anywhere that you call this method :-)
I am running with some weird situation with Switch Case statement in PHP, where it is somehow ignoring the case and throwing default value. However this is not limited to the Switch Case only and happening with if else as well. So might be something wrong I am doing apart from conditional check.
I am using codeingiter and below I am posting all my code and helpers. I hope this would be enough information but let me know if you need any more information.
Helpers
// get employees
function get_employees(array $array = array())
{
$CI = get_instance();
return $CI->db->get_where('employees', $array)->result();
}
// get employee status from the `employment_status`
function get_employee_status($id)
{
$result = get_employees(array('id' => $id));
foreach ($result as $employee)
{
$status = $employee->employment_status;
}
return ($status !== '') ? $status : 'none';
}
// get employee status icon (based on status)
function get_employee_status_icon($id, $tooltip = TRUE)
{
$status = get_employee_status($id);
$get_icon = ($tooltip) ? 'rel="tooltip" title="' . ucwords(str_replace('_', ' ', $status)) . '"' : NULL;
switch ($status)
{
case 'active':
$status_icon = '<span class="glyphicon glyphicon-ok" ' . $get_icon . '></span>';
break;
case 'at_risK':
$status_icon = '<span class="glyphicon glyphicon-warning-sign" ' . $get_icon . '></span>';
break;
case 'attrition':
$status_icon = '<span class="glyphicon glyphicon-ban-circle" ' . $get_icon . '></span>';
break;
default:
$status_icon = '<span class="glyphicon glyphicon-exclamation-sign" ' . $get_icon . '></span>';
break;
}
return $status_icon;
}
Controller
public function employees()
{
$this->data['title'] = '<i class="fa fa-users"></i> ' . lang('emp_all');
$base_url = base_url() . 'admin/hr/employees';
$numbs = $this->employees_model->filter_count();
$total_rows = $numbs['count'];
$limit = get_option('per_page');
$page = ($this->uri->segment(4) !== FALSE) ? (int) $this->uri->segment(4) : 0;
get_pagination($base_url, $total_rows, $limit, 4, 2, TRUE);
$this->data['results'] = $this->employees_model->fetch_rows($limit, $page);
$this->data['links'] = $this->pagination->create_links();
$this->load->view('hr/employees/index', $this->data);
}
View file
// view file
foreach ($results as $employee):
do_print(get_employee_status($employee->id) . ' - ' .get_employee_status_icon($employee->id));
echo '<tr>';
...
echo '<td class="status-' . get_employee_status($employee->id) . '">' . get_employee_status_icon($employee->id) . '</td>';
...
echo '</tr>';
endforeach;
To clear things again: the code outputs the default value (icon) for the last case. It is ignoring the last case just only for the ICON and not for the tooltip or even th class
So how can I fix this where I can get output same as the case everywhere?
EDIT: --- Added output images and var_dump image
Please see the second last var_dump and output result to match the at_risk icon. Which is wrong
HTML Output
var_dump()
First of all you should correct your this function by properly initializing $status variable;
// get employee status from the `employment_status`
function get_employee_status($id)
{
$result = get_employees(array('id' => $id));
$status = '';
foreach ($result as $employee)
{
$status = $employee->employment_status;
}
return ($status !== '') ? $status : 'none';
}
Now, you should do var_dump of $status and see what you find in status variable value.
I overrode CButtonColumn class and code worked in perfect way on localhost(windows) , but when I uploaded it to linux server I had this error :
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /home/xxx/public_html/protected/components/GridView/XCButtonColumn.php on line 65
I read about what mean "T_PAAMAYIM_NEKUDOTAYIM" , it's mean "::"
link here
,but I didn't understood what i can do to fix problem .
line 65:
if (is_array($modelClass::model()->primaryKey))
This is my code :
<?php
class XCButtonColumn extends CButtonColumn
{
public $htmlOptions = array('class' => 'center vcenter');
public $viewButtonOptions = array('class' => 'btn btn-default tip view');
public $viewButtonImageUrl = '';
public $viewButtonHtml;
public $updateButtonOptions = array('class' => 'btn btn-default tip update');
public $updateButtonImageUrl = '';
public $updateButtonHtml;
public $deleteButtonOptions = array('class' => 'btn btn-default tip delete');
public $deleteButtonImageUrl = '';
public $deleteButtonHtml;
public $showImage = false;
public $showHtml = true;
protected function renderButton($id, $button, $row, $data)
{
if (isset($button['visible']) && !$this->evaluateExpression($button['visible'], array('row' => $row, 'data' => $data))) return;
$label = isset($button['label']) ? $button['label'] : $id;
$url = isset($button['url']) ? $this->evaluateExpression($button['url'], array('data' => $data, 'row' => $row)) : '#';
$options = isset($button['options']) ? $button['options'] : array();
if (!isset($options['title'])) $options['title'] = $label;
if ($this->showImage) {
if (isset($button['imageUrl']) && is_string($button['imageUrl'])) {
echo CHtml::link(CHtml::image($button['imageUrl'], $label), $url, $options);
} else {
echo CHtml::link($label, $url, $options);
}
} else {
if (isset($button['html']) && is_string($button['html'])) {
echo CHtml::link($button['html'], $url, $options);
} else {
echo CHtml::link($button['html'], $url, $options);
}
}
}
protected function initDefaultButtons()
{
if ($this->viewButtonLabel === null) $this->viewButtonLabel = Yii::t('zii', 'View');
if ($this->updateButtonLabel === null)
$this->updateButtonLabel = Yii::t('zii', 'Update');
if ($this->deleteButtonLabel === null)
$this->deleteButtonLabel = Yii::t('zii', 'Delete');
if ($this->viewButtonImageUrl === null)
$this->viewButtonImageUrl = $this->grid->baseScriptUrl .
'/view.png';
if ($this->updateButtonImageUrl === null)
$this->updateButtonImageUrl = $this->grid->baseScriptUrl
. '/update.png';
if ($this->deleteButtonImageUrl === null)
$this->deleteButtonImageUrl = $this->grid->baseScriptUrl
. '/delete.png';
if ($this->viewButtonHtml === null)
$this->viewButtonHtml = '<i class="icon-zoom-in iconwhite"></i>';
if ($this->updateButtonHtml === null)
$this->updateButtonHtml = '<i class="icon-edit iconwhite"></i>';
if ($this->deleteButtonHtml === null)
$this->deleteButtonHtml = '<i class="icon-trash iconwhite"></i>';
if ($this->deleteConfirmation === null)
$this->deleteConfirmation = Yii::t('zii', 'Are you sure you want to delete this item?');
$modelClass = $this->grid->dataProvider->modelClass;
$controller = strtolower($modelClass);
if (is_array($modelClass::model()->primaryKey))
$paramExpression = '",$data->primaryKey)';
else
$paramExpression = '",array("id"=>$data->primaryKey))';
foreach (array('view', 'update', 'delete') as $id) {
$button = array(
'label' => $this->{$id . 'ButtonLabel'},
'url' => 'Yii::app()->urlManager->createUrl("' . "$controller/$id$paramExpression",
'imageUrl' => $this->{$id . 'ButtonImageUrl'},
'html' => $this->{$id . 'ButtonHtml'},
'options' => $this->{$id . 'ButtonOptions'},
);
if (isset($this->buttons[$id]))
$this->buttons[$id] = array_merge($button, $this->buttons[$id]);
else
$this->buttons[$id] = $button;
}
if (!isset($this->buttons['delete']['click'])) {
if (is_string($this->deleteConfirmation))
$confirmation = "if(!confirm(" .
CJavaScript::encode($this->deleteConfirmation) . ")) return false;";
else
$confirmation = '';
if (Yii::app()->request->enableCsrfValidation) {
$csrfTokenName = Yii::app()->request->csrfTokenName;
$csrfToken = Yii::app()->request->csrfToken;
$csrf = "\n\t\tdata:{ '$csrfTokenName':'$csrfToken'
},";
} else
$csrf = '';
if ($this->afterDelete === null)
$this->afterDelete = 'function(){}';
$this->buttons['delete']['click'] = <<<EOD
function() {
$confirmation
var th = this,
afterDelete = $this->afterDelete;
jQuery('#{$this->grid->id}').yiiGridView('update', {
type: 'POST',
url: jQuery(this).attr('href'),$csrf
success: function(data) {
jQuery('#{$this->grid->id}').yiiGridView('update');
afterDelete(th, true, data);
},
error: function(XHR) {
return afterDelete(th, false, XHR);
}
});
return false;
}
EOD;
}
}
}
Thanks in advance
First thanks to benka to help , the problem is in php version and php 5.2 not support
this line :
if (is_array($modelClass::model()->primaryKey))
So to be work on php 5.2 I changed it to be :
if (is_array(CActiveRecord::model($modelClass)->primaryKey))
References :
Link 1
Link 2
should be -> instead of ::
if (is_array($modelClass->model()->primaryKey))
I have this line in php
<a title="'.htmlspecialchars($User->Name).'" href="'.$Href.'"'.$LinkClass.'>
I need to add another class which is known called tip
The code above generates something like this:
<a class="ProfileLink" href="/respond/profile/2/422" title="422">
As you can see $LinkClass gives me the class "ProfileLink" which is great
But I need to parse the class like "ProfileLink tip"
So just not sure how to amend $LinkClass above to something like $LinkClass tip
This is probably so basic I just cant see the wood for the trees
//
Edit: to add
Final html output needs to be :
<a class="ProfileLink tip" href="/respond/profile/2/422" title="422">
//
Added:
Entire php output for this function is:
if (!function_exists('UserPhoto')) {
function UserPhoto($User, $Options = array()) {
$User = (object)$User;
if (is_string($Options))
$Options = array('LinkClass' => $Options);
$LinkClass = GetValue('LinkClass', $Options, 'ProfileLink');
$ImgClass = GetValue('ImageClass', $Options, 'ProfilePhotoMedium');
$LinkClass = $LinkClass == '' ? '' : ' class="'.$LinkClass.'"';
$Photo = $User->Photo;
if (!$Photo && function_exists('UserPhotoDefaultUrl'))
$Photo = UserPhotoDefaultUrl($User);
if ($Photo) {
if (!preg_match('`^https?://`i', $Photo)) {
$PhotoUrl = Gdn_Upload::Url(ChangeBasename($Photo, 'n%s'));
} else {
$PhotoUrl = $Photo;
}
$Href = Url(UserUrl($User));
return '<a title="'.htmlspecialchars($User->Name).'" href="'.$Href.'"'.$LinkClass.'>'
.Img($PhotoUrl, array('alt' => htmlspecialchars($User->Name), 'class' => $ImgClass))
.'</a>';
} else {
return '';
}
}
}
How about using an array for the class attribute? Like this:
$LinkClass= array();
$LinkClassVal = GetValue('LinkClass', $Options, 'ProfileLink');
if($LinkClassVal){
$LinkClass[] = $LinkClassVal;
}
$LinkClass[] = "tip";
and then on return :
return '<a title="'.htmlspecialchars($User->Name).'" href="'.$Href.'"'.implode(" ",$LinkClass).'>'
.Img($PhotoUrl, array('alt' => htmlspecialchars($User->Name), 'class' => $ImgClass))
.'</a>';