How to use buttonOptions on GridView on Yii2 - php

I would like to change the default button name on grid view On YII2
on Yii 1 we have this:
http://www.yiiframew...s-in-cgridview/
array
(
'class'=>'CButtonColumn',
'template'=>'{email}{down}{delete}',
'buttons'=>array
(
'email' => array
(
'label'=>'Send an e-mail to this user',
'imageUrl'=>Yii::app()->request->baseUrl.'/images/email.png',
'url'=>'Yii::app()->createUrl("users/email", array("id"=>$data->id))',
),
'down' => array
(
'label'=>'[-]',
'url'=>'"#"',
'visible'=>'$data->score > 0',
'click'=>'function(){alert("Going down!");}',
),
),
),
I would like something like that for Yii2
For now I would like to change only the label.
Reading the documentation for Yii2 I tried that:
[
'class' => 'yii\grid\ActionColumn',
'buttonOptions' => [
[
'name' => 'update',
'additionalOptions' => [
'label' => 'Super Update',
]
],
[
'name' => 'delete',
'additionalOptions' => [
'label' => 'Super Delete',
]
],
],
],
But it does not work.
I know I can recreate the button from scratch with :
'buttons' => [
'update' => function ($url, $model) {
$t = 'index.php?r=site/update&id='.$model->id;
return Html::button('<span class="glyphicon glyphicon-pencil"></span>', ['value'=>Url::to($t), 'class' => 'btn btn-default btn-xs']);
},
],
But I do not want to do that.
thanks

buttonOptions will be applied to all default buttons, you can't separate them, but it's possible to apply general options (to all buttons):
'class' => 'yii\grid\ActionColumn',
'buttonOptions' => [
'title' => 'This is custom title for default 3 buttons',
],
If you want to use custom HTML options, you'll have to create new class, extend ActionColumn and overwrite (2) protected methods, for example:
<?php
namespace app\models;
use yii\grid\ActionColumn;
use yii\helpers\Html;
use Yii;
class customActionColumn extends ActionColumn
{
/**
* Initializes the default button rendering callbacks.
*/
protected function initDefaultButtons()
{
$this->initDefaultButton('view', 'eye-open', [
'title' => 'Super View',
]);
$this->initDefaultButton('update', 'pencil', [
'title' => 'Super Update',
]);
$this->initDefaultButton('delete', 'trash', [
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'data-method' => 'post',
'title' => 'Super Delete'
]);
}
/**
* Initializes the default button rendering callback for single button
* #param string $name Button name as it's written in template
* #param string $iconName The part of Bootstrap glyphicon class that makes it unique
* #param array $additionalOptions Array of additional options
* #since 2.0.11
*/
protected function initDefaultButton($name, $iconName, $additionalOptions = [])
{
if (!isset($this->buttons[$name]) && strpos($this->template, '{' . $name . '}') !== false) {
$this->buttons[$name] = function ($url, $model, $key) use ($name, $iconName, $additionalOptions) {
$title = Yii::t('yii', ucfirst($name));
$options = array_merge([
'title' => $title,
'aria-label' => $title,
'data-pjax' => '0',
'title' => 'atata'
], $additionalOptions, $this->buttonOptions);
$icon = Html::tag('span', '', ['class' => "glyphicon glyphicon-$iconName"]);
return Html::a($icon, $url, $options);
};
}
}
}
Now in GridView you just need to specify custom class and that's all.
[
'class' => app\models\customActionColumn::className(),
],

Related

I don't get "add button" with inline create on Backpack Laravel

Following this documentation : https://backpackforlaravel.com/docs/4.1/crud-operation-inline-create
I try to create a link between invoices (primary) and invoices lines (secondary).
The link seems good, but I don't succeed to have the "+add" button needed to have the secondary form.
My code.
Primary class (invoiceCrudController)
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Invoice;
use Backpack\CRUD\app\Http\Controllers\CrudController;
/**
* Class InvoiceCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class InvoiceCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use SetAccesses;
protected function setupCreateOperation()
{
$this->crud->setValidation(InvoiceRequest::class);
$this->crud->addFields([
/*other cases*/
[
'name' => 'invoiceLines',
'type' => 'relationship',
'tags'=> 'invoice lines',
'ajax'=>true,
[ // specify the entity in singular
'entity' => 'invoiceLine', // the entity in singular
]
],
]);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
}
secondary class (invoiceLinesController)
<?php
namespace App\Http\Controllers\Admin;
use App\Models\InvoiceLine;
use Backpack\CRUD\app\Http\Controllers\CrudController;
/**
* Class InvoiceCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class InvoiceLinesCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
public function setup()
{
$this->setAccesses('invoiceLine');
$this->crud->setModel('App\Models\InvoiceLine');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/invoiceLine');
$this->crud->setEntityNameStrings('invoiceLine', 'invoiceLines');
$this->crud->addColumns([
[
'name' => 'slug',
'type' => 'text',
],
[
'name' => 'quantity',
'type' => 'number',
'default' => 1,
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
],
[
'name' =>'unit_vat_excluded',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
]
]);
}
protected function setupListOperation()
{
$this->crud->enableExportButtons();
CustomerCrudController::addFilterCustomer();
}
protected function setupCreateOperation()
{
$this->crud->addFields([
[
'name' => 'slug',
'type' => 'text',
'allows_null' => false,
],
[
'name' => 'quantity',
'type' => 'number',
'default' => 1,
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
],
[
'name' =>'unit_vat_excluded',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
]
]);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
protected function setupShowOperation()
{
}
public static function getColumn()
{
return [
'name' => 'invoice_line_id',
'label' => 'InvoiceLines',
'type' => 'select',
'entity' => 'invoiceLine',
'attribute' => 'pretty_print',
'model' => InvoiceLine::class,
];
}
}
I think the wrong is in your Filed definistion:
$this->crud->addFields([
/other cases/
[
'name' => 'invoiceLines',
'type' => 'relationship',
'tags'=> 'invoice lines',
'ajax'=>true,
[ // specify the entity in singular
'entity' => 'invoiceLine', // the entity in singular
]
],
since the relation is on to many (I guess) then the filed should be:
[
'type' => "relationship",
'name' => 'invoiceLines',
'ajax' => true,
'inline_create' => true,
]

Yii2 Kartik-v fileiput: Get uploaded images when wrapped in the array of $_FILES instead of $_POST

I am developing my app using the yii2-formwizard widget. I have gotten it working fine in all the other parts and even submits a single image perfectly. The problem comes when I try to submit multiple images. I get the $_POST array with form model values and the image model as an empty array inside the $_POST, but then all the image model values are wrapped in an array of $_FILES. How do I go about solving this as I have never dealt with such before? Here are the relevant codes:
_form view
<?php
use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use kartik\builder\Form;
use kartik\datecontrol\DateControl;
use kartik\widgets\Select2;
use buttflattery\formwizard\FormWizard;
use yii\helpers\ArrayHelper;
use kartik\file\FileInput;
/**
* #var yii\web\View $this
* #var common\models\Listing $model
* #var yii\widgets\ActiveForm $form
*/
?>
<?php
echo FormWizard::widget([
'theme' => FormWizard::THEME_MATERIAL,
'labelFinish' => 'Submit',
// 'formOptions'=>[
// 'options'=>['enctype'=>'multipart/form-data'],
// ],
'steps' => [
[
'model'=>$listingModel,
'title'=>'Basic',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'created_by' => false, //hide a specific field
'updated_at' => false, //hide a specific field
'created_at' => false, //hide a specific field
'expires_on' => false, //hide a specific field
'status' => false, //hide a specific field
'listing_type_id' => false, //hide a specific field
'latitude' => false, //hide a specific field
'longitude' => false, //hide a specific field
'listing_title' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Listing Title...', 'maxlength' => 50]],
'country' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\Country::find()->all(), 'country_id', 'country_name'),
'options' => [
'prompt'=>'Select Country',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-state?id=').'"+$(this).val(), function( data ) {
$( "select#state_id" ).html( data );
});
'
]
]
],
'states' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\States::find()->all(), 'state_id', 'state_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Select the Country First',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-area?id=').'"+$(this).val(), function( data ) {
$( "select#area_code" ).html( data );
});
'
]
]
],
'area_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\Areas::find()->all(), 'area_id', 'area_name'),
'options' => [
'prompt'=>'Please Select the State/Region First',
'id' => 'area_code'
],
]
],
'physical_address' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Actual Physical Address...', 'maxlength' => 50]],
'neighborhood' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Nearby Landmark or Neighbourhood...', 'maxlength' => 50]],
'address' => [
'widget' => \kalyabin\maplocation\SelectMapLocationWidget::className(),
'options' => [
'attributeLatitude' => 'latitude',
'attributeLongitude' => 'longitude',
'googleMapApiKey' => 'AIzaSyDU30XgKi1ik7wpWteHUENKVH_d09sTqRg',
'draggable' => true,
],
]
]
],
[
'model'=>$model,
'title'=>'Prices and More',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['property_category', 'sub_category_id', 'available_from', 'desc', 'price', 'currency_id', 'price_conditions', 'deposit', 'agent_commission', 'other_payments'],
'only' => ['property_category', 'sub_category_id', 'price', 'currency_id'],
'property_category' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\PropertyCategory::find()->all(), 'category_id', 'category_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Property Category',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-property-category?id=').'"+$(this).val(), function( data ) {
$( "select#sub_category_value" ).html( data );
});
'
]
]
],
'sub_category_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\PropertySubCategory::find()->all(), 'sub_category_id', 'name'),
'options' => [
'prompt'=>'Please Select the Property Category First',
'id' => 'sub_category_value'
],
]
],
'currency_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\Currency::find()->all(), 'currency_id', 'title'),
]
],
'price' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Price...']],
]
],
[
'model'=>$model,
'title'=>'Features',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['beds', 'baths', 'rooms', 'living_area', 'living_size', 'floor', 'total_floors', 'build_year', 'car_spaces', 'fully_furnished', 'property_features'],
'only' => ['property_features'],
'property_features' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(common\models\PropertyFeatures::find()->all(), 'feature_id', 'feature_name', 'featuresType.type_name'),
'options' => ['multiple' => true, 'placeholder' => 'Select Property Features ...']
]
],
]
],
[
'model'=>$imageModel,
'title'=>'Images',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'only' => ['image'],
'image' => [
'multifield'=>true,
'widget' => FileInput::classname(),
'options' =>[
'options' => [
'multiple' => true,
'accept' => 'image/*',
'pluginOptions' => [
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'browseClass' => 'btn btn-primary btn-block',
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'browseLabel' => 'Attach Listing Images',
'allowedFileExtensions' => ['jpg','gif','png'],
'overwriteInitial' => false
],
],
],
]
]
],
]
]);
?>
Controller Action
/**
* Creates a new Property model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionProperty()
{
$listingModel = new Listing;
$imageModel = new ListingImages;
$model = new Property;
if ($listingModel->load(Yii::$app->request->post()) && $imageModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post())) {
$transaction = Yii::$app->db->beginTransaction();
try {
$listingModel->listing_type_id = $listingModel->listingType('Property');
$listingModel->created_by = Yii::$app->user->id;
if ($flag = $listingModel->save(false)) {
$model->listing_id = $listingModel->listing_id;
$model->physical_address = $listingModel->physical_address;
$model->neighborhood = $listingModel->neighborhood;
$model->area_id = $listingModel->area_code;
$model->address = $listingModel->physical_address;
$model->latitude = $listingModel->latitude;
$model->longitude = $listingModel->longitude;
$model->created_by = Yii::$app->user->id;
$flag = $model->save(false);
foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) {
$image = $imageModel->uploadImage();
$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';
if ($flag = $imageModel->save()) {
if ($image !== false) {
$path = $imageModel->getImageFile();
$image->saveAs($path);
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $listingModel->listing_id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
} else {
return $this->render('create', [
'listingModel' => $listingModel, 'model' => $model, 'form' => '_property', 'imageModel' => $imageModel,
]);
}
}
ListingImages model
<?php
namespace common\models;
use Yii;
use yii\web\UploadedFile;
use yii\helpers\FileHelper;
/**
* This is the model class for table "listing_images".
*
* #property int $image_id
* #property int $listing_id
* #property string $image_url_link generated filename on server
* #property string $updated_at
* #property string $created_at
* #property int $created_by
* #property string $active
* #property string $filename source filename from client
*
* #property Listing $listing
*/
class ListingImages extends \yii\db\ActiveRecord
{
const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $filename;
public $image;
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'listing_images';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['listing_id', 'image_url_link', 'created_by', 'active'], 'required'],
[['listing_id', 'created_by'], 'integer'],
[['updated_at', 'created_at', 'filename'], 'safe'],
[['active'], 'string'],
[['image_url_link'], 'string', 'max' => 80],
[['listing_id'], 'exist', 'skipOnError' => true, 'targetClass' => Listing::className(), 'targetAttribute' => ['listing_id' => 'listing_id']],
// [['image'], 'file', 'extensions'=>'jpg, gif, png'],
// [['image'], 'file', 'maxSize'=>'2048000'],
// [['image'], 'file','maxFiles' => 30],
[['image'], 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 2048000, 'maxFiles' => 30],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'image_id' => Yii::t('app', 'Image ID'),
'listing_id' => Yii::t('app', 'Listing ID'),
'image_url_link' => Yii::t('app', 'Listing Image'),
'updated_at' => Yii::t('app', 'Updated At'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'active' => Yii::t('app', 'Active'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getListing()
{
return $this->hasOne(Listing::className(), ['listing_id' => 'listing_id']);
}
/**
* fetch stored image file name with complete path
* #return string
*/
public function getImageFile()
{
$directory = Yii::$app->params['uploadPath'];
if (!is_dir($directory)) {
FileHelper::createDirectory($directory);
}
return isset($this->image_url_link) ? $directory . '/' . $this->image_url_link : null;
}
/**
* fetch stored image url
* #return string
*/
public function getImageUrl()
{
$directory = Yii::$app->params['uploadUrl'];
// return a default image placeholder if your source image_url_link is not found
$image_url_link = isset($this->image_url_link) ? $this->image_url_link : 'default_user.jpg';
return $directory . $image_url_link;
}
/**
* Process upload of image
*
* #return mixed the uploaded image instance
*/
public function uploadImage() {
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstance($this, 'image');
// if no image was uploaded abort the upload
if (empty($image)) {
return false;
}
// store the source file name
$tmp = explode(".", $image->name);
$ext = end($tmp);
// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".{$ext}";
// the uploaded image instance
return $image;
}
/**
* Process deletion of image
*
* #return boolean the status of deletion
*/
public function deleteImage() {
$file = $this->getImageFile();
// check if file exists on server
if (empty($file) || !file_exists($file)) {
return false;
}
// check if uploaded file can be deleted on server
if (!unlink($file)) {
return false;
}
// if deletion successful, reset your file attributes
$this->image_url_link = null;
$this->filename = null;
return true;
}
}
Note that the other part of the code is working fine. I have only twisted some few parts to get a favourable results. Here is the submitted data via the form. The part that is really confusing me is that wrapped in the $_FILES array at the end of this code that has all the uploaded files information.
$_POST = [
'_csrf-backend' => '_ioSvkoWdYDTEG_L4AHgnyQSEe7pZOqEWwQfPANPbM2uGkbIKHo8y5ZAGriqT4XsQCBkl5sOnvweT31wUx01kg==',
'Listing' => [
'listing_title' => 'tyguhijokpl[',
'country' => '2',
'states' => '4',
'area_id' => '1537',
'physical_address' => 'yghbunjikmol,',
'neighborhood' => 'gvybhunjimko,l',
'address' => 'Dandora phase 4, Nairobi, Kenya',
'latitude' => '-1.2423923',
'longitude' => '36.90438449999999',
],
'Property' => [
'property_category' => '1',
'sub_category_id' => '2',
'currency_id' => '1',
'price' => '897465123',
'property_features' => [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
],
],
'ListingImages' => [
'image' => [
'',
],
],
];
$_FILES = [
'ListingImages' => [
'name' => [
'image' => [
'coins-1015125_1920.jpg',
'computer-768608_1920.jpg',
'content-is-king-1132259_1920.jpg',
'content-marketing.jpg',
'contentpyramid.png',
'cup-of-coffee-1280537_1920.jpg',
'ecommerce-3546296_1920.jpg',
'email-3249062_1280.png',
],
],
'type' => [
'image' => [
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/png',
'image/jpeg',
'image/jpeg',
'image/png',
],
],
'tmp_name' => [
'image' => [
'C:\\xampp\\tmp\\php8AF1.tmp',
'C:\\xampp\\tmp\\php8B02.tmp',
'C:\\xampp\\tmp\\php8B03.tmp',
'C:\\xampp\\tmp\\php8B23.tmp',
'C:\\xampp\\tmp\\php8B34.tmp',
'C:\\xampp\\tmp\\php8B35.tmp',
'C:\\xampp\\tmp\\php8B46.tmp',
'C:\\xampp\\tmp\\php8B47.tmp',
],
],
'error' => [
'image' => [
0,
0,
0,
0,
0,
0,
0,
0,
],
],
'size' => [
'image' => [
364796,
275881,
310313,
301511,
119458,
508911,
219479,
242737,
],
],
],
];
i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.
And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too
$imageInstances=UploadedFile::getInstances('image');
foreach ($imageInstances as $instance) {
$imageModel=new ListingImages();
$image = $imageModel->uploadImage($instance);
$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';
if ($flag = $imageModel->save()) {
if ($image !== false) {
$path = $imageModel->getImageFile();
$image->saveAs($path);
}
}
}
and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields
/**
* Process upload of image
*
* #return mixed the uploaded image instance
*/
public function uploadImage($image) {
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
// store the source file name
$tmp = explode(".", $image->name);
$ext = end($tmp);
// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".{$ext}";
// the uploaded image instance
return $image;
}

Typo3: Extended tt_content, Repo returns empty QueryResultInterface

I extended the tt_content table with an relationship to the tags of the news extension. (So I can Tag all tt_content elements.)
The methods like findAll and findByUid always return an empty QueryResultInterface.
I created the extension with extensionbuilder.
I defined the Storage in the extensions right and ignore the storage on own methods.
ext_typoscript_setup.txt:
config.tx_extbase {
persistence {
classes {
EXAMP\ExampContentTagging\Domain\Model\ContentTagRelation {
mapping {
tableName = tt_content
recordType = Tx_ExampContentTagging_ContentTagRelation
}
}
}
}
}
ContentTagRelationRepository.php:
<?php
namespace EXAMP\ExampContentTagging\Domain\Repository;
/**
* The repository for ContentTagRelations
*/
class ContentTagRelationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
/**
* #var array
*/
protected $defaultOrderings = array(
'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
/**
* Find tt_content by a given pid
*
* #param array $includeIdList list of id s
* #param array $excludeIdList list of id s
* #return QueryInterface
*/
public function findByTagIdList(array $includeIdList, array $excludeIdList = [])
{
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(false);
$query->getQuerySettings()->setRespectSysLanguage(false);
return $query->execute();
}
TCA/Overrides/tt_content.php:
defined('TYPO3_MODE') || die();
if (!isset($GLOBALS['TCA']['tt_content']['ctrl']['type'])) {
if (file_exists($GLOBALS['TCA']['tt_content']['ctrl']['dynamicConfigFile'])) {
require_once($GLOBALS['TCA']['tt_content']['ctrl']['dynamicConfigFile']);
}
// no type field defined, so we define it here. This will only happen the first time the extension is installed!!
$GLOBALS['TCA']['tt_content']['ctrl']['type'] = 'tx_extbase_type';
$tempColumnstx_exampcontenttagging_tt_content = [];
$tempColumnstx_exampcontenttagging_tt_content[$GLOBALS['TCA']['tt_content']['ctrl']['type']] = [
'exclude' => true,
'label' => 'LLL:EXT:examp_content_tagging/Resources/Private/Language/locallang_db.xlf:tx_exampcontenttagging.tx_extbase_type',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['ContentTagRelation','Tx_exampContentTagging_ContentTagRelation']
],
'default' => 'Tx_exampContentTagging_ContentTagRelation',
'size' => 1,
'maxitems' => 1,
]
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $tempColumnstx_exampcontenttagging_tt_content);
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'tt_content',
'tx_news_domain_model_tag'
);
$tmp_examp_content_tagging_columns = [
'tx_news_domain_model_tag' => [
'exclude' => true,
'label' => 'LLL:EXT:examp_content_tagging/Resources/Private/Language/locallang_db.xlf:tx_exampcontenttagging_domain_model_contenttagrelation.tx_news_domain_model_tag',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_news_domain_model_tag',
'MM' => 'tx_exampcontenttagging_contenttagrelation_tag_mm',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'wizards' => [
'_PADDING' => 1,
'_VERTICAL' => 1,
'edit' => [
'module' => [
'name' => 'wizard_edit',
],
'type' => 'popup',
'title' => 'Edit', // todo define label: LLL:EXT:.../Resources/Private/Language/locallang_tca.xlf:wizard.edit
'icon' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_edit.gif',
'popup_onlyOpenIfSelected' => 1,
'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
],
'add' => [
'module' => [
'name' => 'wizard_add',
],
'type' => 'script',
'title' => 'Create new', // todo define label: LLL:EXT:.../Resources/Private/Language/locallang_tca.xlf:wizard.add
'icon' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_add.gif',
'params' => [
'table' => 'tx_news_domain_model_tag',
'pid' => '###CURRENT_PID###',
'setValue' => 'prepend'
],
],
],
],
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content',$tmp_examp_content_tagging_columns);
/* inherit and extend the show items from the parent class */
if (isset($GLOBALS['TCA']['tt_content']['types']['1']['showitem'])) {
$GLOBALS['TCA']['tt_content']['types']['Tx_exampContentTagging_ContentTagRelation']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['1']['showitem'];
} elseif(is_array($GLOBALS['TCA']['tt_content']['types'])) {
// use first entry in types array
$tt_content_type_definition = reset($GLOBALS['TCA']['tt_content']['types']);
$GLOBALS['TCA']['tt_content']['types']['Tx_exampContentTagging_ContentTagRelation']['showitem'] = $tt_content_type_definition['showitem'];
} else {
$GLOBALS['TCA']['tt_content']['types']['Tx_exampContentTagging_ContentTagRelation']['showitem'] = '';
}
$GLOBALS['TCA']['tt_content']['types']['Tx_exampContentTagging_ContentTagRelation']['showitem'] .= ',--div--;LLL:EXT:examp_content_tagging/Resources/Private/Language/locallang_db.xlf:tx_exampcontenttagging_domain_model_contenttagrelation,';
$GLOBALS['TCA']['tt_content']['types']['Tx_exampContentTagging_ContentTagRelation']['showitem'] .= 'tx_news_domain_model_tag';
$GLOBALS['TCA']['tt_content']['columns'][$GLOBALS['TCA']['tt_content']['ctrl']['type']]['config']['items'][] = ['LLL:EXT:examp_content_tagging/Resources/Private/Language/locallang_db.xlf:tt_content.tx_extbase_type.Tx_exampContentTagging_ContentTagRelation','Tx_exampContentTagging_ContentTagRelation'];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr(
'',
'EXT:/Resources/Private/Language/locallang_csh_.xlf'
);
Mostly to this problem, the solution is to check if the right storage is set. But I did this and still have the problem. So I think tt_content is the problem. But the only thing I could find to this was:
"tt_content is special."
Which dosen't help. (Offtopic: This Typo3 Documentation makes me mad every time I've to look into it.)

Laravel 5.2 backpack get the parameter from url

I am stuck with a problem that don't know how to get the value from url. I am new in backpack. please help me with this.....
I want my details on a view based on the id that is passed from another view, how to implement this?? this is my code
Adcontroller.php
public $crud = array(
"model" => "App\Larapen\Models\Ad",
"entity_name" => "ad",
"entity_name_plural" => "ads",
"route" => "admin/ad",
"reorder" => false,
"add_permission" => false,
"columns" => [
[
'name' => 'reviewed',
'label' => "Reviewed",
'type' => "model_function",
'function_name' => 'getReviewedHtml',
],
],
"fields" =>[
[ // Hidden
'name' => 'id',
'label' => "id",
'type' => 'hidden'
],
],
);
Ad.php(model)
public function getReviewedHtml()
{
if ($this->reviewed == 1) {
return '<i class="fa fa-check-square-o" aria-hidden="true"></i><span> Reviews</span>';
} else {
return '<i class="fa fa-square-o" aria-hidden="true"></i>';
}
}
route.php
CRUD::resource('ad', 'AdController');
CRUD::resource('reviews', 'AdReviewController');
AdReviewController.php
public $crud = array(
"model" => "App\Larapen\Models\AdReviews",
"entity_name" => "Reviews",
"entity_name_plural" => "Reviews",
"route" => "admin/reviews",
"reorder" => false,
"add_permission" => false,
// *****
// COLUMNS
// *****
"columns" => [
[
'name' => 'created_at',
'label' => "Date",
],
[
'name' => 'user',
'label' => "User",
'type' => "model_function",
'function_name' => 'getuser',
],
[
'name' => 'review',
'label' => "Review",
],
],
"fields" => [
[
'name' => 'review',
'label' => "Review",
],
],
);
public function __construct()
{
//$this->crud['update_fields'][1]['options'] = $this->adType();
// $this->crud['update_fields'][2]['options'] = $this->categories();
parent::__construct();
}
public function store(StoreRequest $request)
{
return parent::storeCrud();
}
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}
}
"I want to display the reviews based on each Ads now it display all the reviews from the review table, where should i write the condition???"
Waiting for a response...............
I presume you have one-to-one or one-to-many relationships between AdReview and Review, defined both in your Review model and your AdReview model.
If so, you can add:
a "select" column in your table view;
a "select" / "select2" field in your create/update views;
That will show the entity it's "connected" with and allow the user to edit it.
Is this what you were trying to achieve?

ZF2 - How to add a new Form in an existing Controller?

I have a login Form LoginForm.php with its Filter LoginFilter.php, that has a View /login/index.phtml, a Controller LoginController.php, two Factory LoginControllerFactory.php & LoginFormFactory.php and it is called in the config.module.php and works perfect. The Form is correctly displayed.
I have a ViewController.php that has a method idAction that shows a post by its id passed by parameter from the homepage in a View called /view/id.phtml. I want to display this Form I created within this View and I don't know how. First, I created the Form exactly as I created the login Form, but I realized that I already configured my id child-route, inside of view route with a Factory in module.config.php.
Then, I tried to set the form in the idAction method, exactly as I did in indexAction in LoginController.php Controller, but I'm receiving the following error: An exception was raised while creating "Rxe\Factory\ViewController"; no instance returned.
I will now show you what I did to try to display this new Form.
First, the Form itself:
class CommentForm extends Form
{
public function buildForm()
{
$this->setAttribute('method', 'POST');
$this->setAttribute('id', 'add-comment-form');
$this->add(array(
'name' => 'comment',
'type' => 'textarea',
'options' => array(
'label' => 'Category'
),
'attributes' => array(
'class' => 'form-control'
)
));
$this->add(array(
'name' => 'submit',
'type' => 'submit',
'attributes' => array(
'class' => 'btn btn-success',
'value' => 'Comment'
)
));
}
}
Form's CommentFormFactory.php calling its Filter and building the Form:
class CommentFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$form = new CommentForm();
$form->setInputFilter($serviceLocator->get('Rxe\Factory\CommentFilter'));
$form->buildForm();
return $form;
}
}
The ViewControllerFactory.php calling the CommentFormFactory.php, just like in LoginControllerFactory.php:
class ViewControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$viewController = new ViewController();
$viewController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));
$viewController->setCommentsTable($serviceManager->get('Rxe\Factory\CommentsTable'));
$viewController->setCommentForm($serviceManager->get('Rxe\Factory\CommentForm'));
return $viewController;
}
}
The ViewController.php, calling the form within its idAction's ViewModel:
class ViewController extends AbstractActionController
{
use PostsTableTrait;
use CommentsTableTrait;
private $commentForm;
function setCommentForm($commentForm)
{
$this->commentForm = $commentForm;
}
public function indexAction()
{
$category = $this->params()->fromRoute('category');
return new ViewModel(array(
'posts' => $this->postsTable->getPostsByCategory($category),
'categories' => $category
));
}
public function idAction()
{
$id = $this->params()->fromRoute('id');
$viewModel = new ViewModel(array(
'commentForm' => $this->commentForm,
'commentParams' => $this->params()->fromPost(),
'messages' => $this->flashMessenger()->getMessages(),
'posts' => $this->postsTable->getPostById($id),
'posts' => $this->commentsTable->getNumberOfCommentsByPost($id),
'comments' => $this->commentsTable->getCommentsByPost($id)
));
$viewModel->setTemplate('rxe/view/id.phtml');
if ($this->getRequest()->isPost()) {
$this->commentForm->setData($this->params()->fromPost());
if ($this->commentForm->isValid()) {
$this->flashMessenger()->addMessage('Thank you for your comment. :)');
} else {
$this->flashMessenger()->addMessage('Your comment wasn\'t sent.');
}
}
return $viewModel;
}
}
And finally my module.config.php
'controllers' => array(
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
'factories' => array(
'Rxe\Factory\LoginController' => 'Rxe\Factory\LoginControllerFactory',
'Rxe\Factory\ViewController' => 'Rxe\Factory\ViewControllerFactory',
'Rxe\Factory\IndexController' => 'Rxe\Factory\IndexControllerFactory'
)
),
'service_manager' => array(
'factories' => array(
'Rxe\Factory\LoginForm' => 'Rxe\Factory\LoginFormFactory',
'Rxe\Factory\LoginFilter' => 'Rxe\Factory\LoginFilterFactory',
'Rxe\Factory\CommentForm' => 'Rxe\Factory\CommentFormFactory',
'Rxe\Factory\CommentFilter' => 'Rxe\Factory\CommentFilterFactory',
'Rxe\Factory\PostsTable' => 'Rxe\Factory\PostsTableFactory',
'Rxe\Factory\CategoriesTable' => 'Rxe\Factory\CategoriesTableFactory',
'Rxe\Factory\CommentsTable' => 'Rxe\Factory\CommentsTableFactory',
'Zend\Db\Adapter\AdapterService' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
),
Please, let me know if you need me to show you more codes. Thank you in advance.
EDIT #1
If I remove the line that calls the Form in the ViewControllerFactory.php, I get the following error: Fatal error: Call to a member function prepare() on a non-object in /home/vol12_3/byethost4.com/b4_16354889/htdocs/module/Rxe/view/rxe/view/id.phtml on line 31
The id.phtml is:
<!-- Comment form -->
<div id="comment-form-area" class="col-xs-3">
<?php $this->commentForm->prepare() ?>
<?php echo $this->form()->openTag($this->commentForm); ?>
<div class="form-group comment-area">
<?php echo $this->formRow($this->commentForm->get('comment_content')); ?>
</div>
<div class="form-group">
<?php echo $this->formRow($this->commentForm->get('submit')); ?>
</div>
<?php echo $this->form()->closeTag(); ?>
</div>
<!-- /Comment form -->
Try removing these lines
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
If it doesn't work, have a look at this tutorial how to create proper controller factories and pass dependencies. https://samsonasik.wordpress.com/2015/03/31/zend-framework-2-using-__invokepluginmanager-manager-in-services-factory/
An example how I build my forms:
namespace Admin\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class ContentForm extends Form implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct("content");
}
public function init()
{
$this->setAttribute('method', 'post');
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'title',
'attributes' => [
'required' => true,
'size' => 40,
'id' => "seo-caption",
'placeholder' => 'Title',
],
'options' => [
'label' => 'Title',
],
]);
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'text',
'attributes' => [
'class' => 'ckeditor',
'rows' => 5,
'cols' => 80,
],
'options' => [
'label' => 'Text',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
],
[
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
],
];
}
}
Than I create a Factory
namespace Admin\Factory\Controller;
use Admin\Controller\ContentController;
use Zend\Mvc\Controller\ControllerManager;
class ContentFormFactory
{
/**
* #{inheritDoc}
*/
public function __invoke(ControllerManager $controllerManager)
{
return new ContentController(
$controllerManager->getServiceLocator()->get('FormElementManager')->get('Admin\Form\ContentForm')
);
}
}
Inside module.config.php I have this code
'controllers' => [
'factories' => [
'Admin\Controller\Content' => "Admin\Factory\Controller\ContentFormFactory",
],
'invokables' => [
...
],
],
Please, show us some more code.

Categories