how to use sonata media bundle with my entities - symfony-sonata

I want to use sonata media bundle for medias in my bundle.
I have one entity which should have a gallery. After installing sonata media bundle and generating easy:extends, there are 3 diffrent entities:
Media.php
Gallery.php
GalleryHasMedia.php.
How can I link these entities to my own entity for gallery implementation???

You can link one-to-one.
for example, my implementation:
config.yml:
contexts:
product:
providers:
- sonata.media.provider.image
formats:
big: { width: 1680 , quality: 100}
Gallery.php:
private $product;
Gallery.orm.xml:
<one-to-one field="product" target-entity="Alteza\ProductBundle\Entity\Product" inversed-by="gallery">
<join-column name="product_id" referenced-column-name="id" />
</one-to-one>
Product.php:
/**
* #ORM\OneToOne(targetEntity="\Application\Sonata\MediaBundle\Entity\Gallery", mappedBy="product", cascade={"all"})
*/
private $gallery;
ProductAdmin.php:
->add('gallery', 'sonata_type_model_list', array('required' => false), array('link_parameters' => array('context' => 'product')))

Here is the documentation about the implementation:
http://sonata-project.org/blog/2013/10/11/mediabundle-mediatype-improved

Related

Show Thumbnails in Backend Model Columns

I'm using OctoberCMS with Laravel.
I use File Upload / Media Finder to attach an image. I'm trying to add thumbnails to the Backend Model columns.
I tried following these guides:
https://octobercms.com/forum/post/how-to-display-pictures-in-backend-lists
https://octobercms.com/docs/database/attachments
File Upload
Columns Thumbnail
Model
I have in my Model Catalog.php
public $attachOne = [
'photo' => 'System\Models\File'
];
In columns.yamal
Field photo set to partial and added path.
In the partial _photo.htm I have
<?php echo $this->photo->getThumb(100, 100, ['mode' => 'crop']); ?>
Error
I get Error: Call to a member function getThumb() on null.
If I use <img src="" /> in the partial it will display an empty image in the columns, but I don't know what php to put as the src.
According to column widget when you are using partial it will pass $record variable corresponding to that row, [ do not use $this there ]
means for that row $record will point to current record so you can use $record
your _photo.htm should be like this
<img src="<?php echo $record->photo->getThumb(100, 100, ['mode' => 'crop']); ?>" />
<!-- OR -->
<img src="<?= $record->photo->getThumb(100, 100, ['mode' => 'crop']) ?>" />
update
If you are using media finder then you can not use getThumb on the file as it will be just path for that file so its not possible to resize that image using getThumb [ Its only possible with relational attachments (attachMany, attachone etc...) ]
Although you can use this to show small image
<img height="64" width="64" src="<?= 'https://october-plaza.com/storage/app/media/'
. $model->photo ?>"` />
you can add this height="64" width="64" to show image as thumbnail (but it will be full image just scale down using attributes).
if any doubts please comment
You can do this with OCTOBER IMAGE RESIZER plugin in your columns.yaml file
Usage in Backend List
The image resizer can also be used on backend lists with the type of thumb, e.g.
image:
label: Image
type: thumb
sortable: false
This works with:
AttachMany (uses first image) Docs
AttachOne Docs
Mediafinder Docs
You can also optionally pass width (default 50), height (default 50) and options as follows:
image:
label: Image
type: thumb
sortable: false
width: 75
height: 100
options:
mode: crop

Angular material 2 data table Error Uncaught Error: Template parse errors:

The md-table provides a Material Design styled data-table that can be used to display rows of data.
This table builds on the foundation of the CDK data-table and uses a similar interface for its data source input and template, except that its element selectors will be prefixed with md- instead of cdk-
I have this error Uncaught Error: Template parse errors:
This is my products.component.html
<md-card class="chart-container">
<div class="example-container mat-elevation-z8">
<md-table #table [dataSource]="dataSource">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- ID Column -->
<ng-container cdkColumnDef="userId">
<md-header-cell *cdkHeaderCellDef> ID </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
</ng-container>
<!-- Progress Column -->
<ng-container cdkColumnDef="progress">
<md-header-cell *cdkHeaderCellDef> Progress </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
</ng-container>
<!-- Name Column -->
<ng-container cdkColumnDef="userName">
<md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
</ng-container>
<!-- Color Column -->
<ng-container cdkColumnDef="color">
<md-header-cell *cdkHeaderCellDef>Color</md-header-cell>
<md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell>
</ng-container>
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row> <----- Heare is the problem
<md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row> <----- Heare is the problem
</md-table>
</div>
</md-card>
Uncaught Error: Template parse errors:
Can't bind to 'cdkHeaderRowDef' since it isn't a known property of 'md-header-row'.
1. If 'md-header-row' is an Angular component and it has 'cdkHeaderRowDef' input, then verify that it is part of this module.
2. If 'md-header-row' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
</ng-container>
<md-header-row [ERROR ->]*cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let row; col"): ng:///AppModule/AdminProductsComponent.html#60:31
Property binding cdkHeaderRowDef not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "#NgModule.declarations". ("
</ng-container>
[ERROR ->]<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDe"): ng:///AppModule/AdminProductsComponent.html#60:16
Can't bind to 'cdkRowDefColumns' since it isn't a known property of 'md-row'.
1. If 'md-row' is an Angular component and it has 'cdkRowDefColumns' input, then verify that it is part of this module.
2. If 'md-row' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. (" <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row [ERROR ->]*cdkRowDef="let row; columns: displayedColumns;"></md-row>
</md-table>
</di"): ng:///AppModule/AdminProductsComponent.html#61:24
Property binding cdkRowDefColumns not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "#NgModule.declarations". (" <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
[ERROR ->]<md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
</md-table>
"): ng:///AppModule/AdminProductsComponent.html#61:16
at syntaxError (http://localhost:4200/vendor.bundle.js:86242:34)
at TemplateParser.parse (http://localhost:4200/vendor.bundle.js:97363:19)
at JitCompiler._compileTemplate (http://localhost:4200/vendor.bundle.js:111515:39)
at http://localhost:4200/vendor.bundle.js:111435:62
at Set.forEach (native)
at JitCompiler._compileComponents (http://localhost:4200/vendor.bundle.js:111435:19)
at http://localhost:4200/vendor.bundle.js:111322:19
at Object.then (http://localhost:4200/vendor.bundle.js:86231:148)
at JitCompiler._compileModuleAndComponents (http://localhost:4200/vendor.bundle.js:111321:26)
at JitCompiler.compileModuleAsync (http://localhost:4200/vendor.bundle.js:111250:37)
This is the products.componetn.ts
import { Component, OnInit } from '#angular/core';
import {DataSource} from '#angular/cdk';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
#Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: ['./admin-products.component.css']
})
export class AdminProductsComponent implements OnInit {
curentPage: string;
isDarkTheme: any;
totalProducts: any = 88;
totalNeeds: any = 88;
totalBrands: any = 88;
totalAgeGroups: any = 88;
constructor() {
this.curentPage = 'Products';
this.isDarkTheme = false;
}
ngOnInit() {
}
}
/** Constants used to fill up our data base. */
const COLORS = ['maroon', 'red', 'orange', 'yellow', 'olive', 'green', 'purple',
'fuchsia', 'lime', 'teal', 'aqua', 'blue', 'navy', 'black', 'gray'];
const NAMES = ['Maia', 'Asher', 'Olivia', 'Atticus', 'Amelia', 'Jack',
'Charlotte', 'Theodore', 'Isla', 'Oliver', 'Isabella', 'Jasper',
'Cora', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];
export interface UserData {
id: string;
name: string;
progress: string;
color: string;
}
/** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
/** Stream that emits whenever the data has been modified. */
dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
get data(): UserData[] { return this.dataChange.value; }
constructor() {
// Fill up the database with 100 users.
for (let i = 0; i < 100; i++) { this.addUser(); }
}
/** Adds a new user to the database. */
addUser() {
const copiedData = this.data.slice();
copiedData.push(this.createNewUser());
this.dataChange.next(copiedData);
}
/** Builds and returns a new User. */
private createNewUser() {
const name =
NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';
return {
id: (this.data.length + 1).toString(),
name: name,
progress: Math.round(Math.random() * 100).toString(),
color: COLORS[Math.round(Math.random() * (COLORS.length - 1))]
};
}
}
/**
* Data source to provide what data should be rendered in the table. Note that the data source
* can retrieve its data in any way. In this case, the data source is provided a reference
* to a common data base, ExampleDatabase. It is not the data source's responsibility to manage
* the underlying data. Instead, it only needs to take the data and send the table exactly what
* should be rendered.
*/
export class ExampleDataSource extends DataSource<any> {
constructor(private _exampleDatabase: ExampleDatabase) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<UserData[]> {
return this._exampleDatabase.dataChange;
}
disconnect() {}
}
import CdkTableModule in your app.module.ts file
import { CdkTableModule } from '#angular/cdk';
and add CdkTableModule to the imports
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
CdkTableModule,
MaterialModule
]
Answered here: md-table in Angular Material 2
The cdkHeaderCellDef and cdkCellDef are part of the #angular/cdk library and exported in the CdkTableModule.
Include this module in your app's imports
In my case, I'm starting at angular, and I had a similar error, using version 2.0.0-beta.12 of angular material, the documentation of your page (material.angular.io/components/table/examples ) uses the prefix "md", which was removed in this new version(now mat), here you can see the notes of said change
https://github.com/angular/material2/blob/master/CHANGELOG.md#deprecation-of-md-prefix
It may be useful for someone to use this information if they are new, since I followed the examples and did everything that indicates the answer to this question and the example did not work until I change to this example:
github.com/angular/material2/blob/master/src/material-examples/table-basic/table-basic-example.html
Greetings.

Add store view selector to admin toolbar in Magento 2

I am creating a module which will support different configuration settings for different store views and it would be great to have a store view selector similar to the one which appears when one is editing a product in the admin.
I have managed to add buttons to my module toolbar using the code:
class Edit extends \Magento\Backend\Block\Template
{
protected function _prepareLayout()
{
$this->getToolbar()->addChild(
'save_button',
'Magento\Backend\Block\Widget\Button',
[
'label' => __('Save'),
'data_attribute' => [
'role' => 'save',
],
'class' => 'save primary',
'onclick' => "jQuery('#mp_mymodule_edit_form').submit();",
]
);
return parent::_prepareLayout();
}
}
I wondered if it was possible to insert the store view selector using Tools::addChild method? Looked around Stack Overflow and Google in general and have not managed to find any thing on this. Fingers crossed, someone does know.
Thanks in advance
Eventually managed to work this out by poking around various Magento files, posting here in case anyone is looking for the same solution:
Method 1 - Adding to the _prapareLayout function:
$this->getToolbar()->addChild(
'store_switcher',
'Magento\Backend\Block\Store\Switcher'
);
Method 2 - Layout XML file (in my case I added this to my layout file in app/code/MP/MyModule/view/adminhtml/layout/productpricebysize_dimension_edit
<referenceContainer name="page.main.actions">
<block class="Magento\Backend\Block\Store\Switcher" name="store_switcher">
<action method="setUseConfirm">
<argument name="params" xsi:type="string">1</argument>
</action>
</block>
</referenceContainer>

Server side validation in module setting page in backend joomla

I am using joomla 2.5, i am working on joomla module, i want to perform server side custom form validation at backend setting page in module. I have checked joomla forums , but they all explained according to component , i strictly need to do it in module . I am new in joomla . Please explain the method.
Try this,
First of all you can't do a wide variety of validations like components forms in module params without hacking the core.
the available options are limiting INT,RAW data string only.
you can use the last option of module params called filter. Details take a look at this.
<field name="myintvalue" type="text" default="8" label="Enter some text" description="Enter some description" filter="integer" />
<field name="myhtmlvalue" type="text" default="" label="Enter some text" description="Enter some description" filter="raw" />
Alternate Options.
You can create a custom rule for validation. For example your module name is mod_mymodule:
Add addrulepath attribute to the fieldset in the .xml file:
addrulepath="modules/mod_mymodule"
This will be the path to the custom rule folder.
Add validate attribute to the field with the name of the rule file:
validate="testint"
This will give us the file testint.php.
Create the rule file testint.php and put it to the path specified in the addrulepath attribute. So the full path will be:
administrator/modules/mod_mymodule/testint.php
Here is a simple validation rule class:
class JFormRuleTestint extends JFormRule
{
public function test(&$element, $value, $group = null, &$input = null, &$form = null)
{
return ((int)$value > 0 && (int)$value < 2);
}
}
it should extend JFormRule class and you will need only one method, called test. $value will contain the input from the field. Here we are testing it to be integer between 0 and 2.
Hope its helps..

Stop validation on first error flag in Symfony2?

I'm searching for informations if there is some kind of flag/option that force symfony2 validation stop on first error in validation chain. For example I have three validators on my email field:
email:
- NotBlank: { groups: [ send_activation_email ] }
- Length: { min: 6, max: 80, charset: UTF-8, groups: [ send_activation_email ] }
- Email: { groups: [ send_activation_email ] }
I want to stop validation after first error. How can I achieve that? I read similar questions:
Symfony2 : Validation Halt on First Error
How to stop validation on constraint failure in Symfony2
Symfony-2 gives more than one validation error message
Last one is quite good but is there any way to do this without using validation groups every time, when there are more than one validator? I read somewhere that in Symfony 2.2 there will be a flag or option for this, but I have 2.2.1 version and can't find such option.
You can use the Chain validator for that purpose: https://gist.github.com/rybakit/4705749
Here's an example in plain PHP:
<?php
use Symfony\Component\Validator\Constraints\Date;
use Symfony\Component\Validator\Constraints\Type;
use Acme\Validator\Constraints\Chain;
$constraint = new Chain([new Type('string'), new Date()]);
In XML:
<!-- src/Acme/DemoBundle/Resources/config/validation.xml -->
<class name="Acme\DemoBundle\Entity\AcmeEntity">
<property name="date">
<constraint name="Acme\Validator\Constraints\Chain">
<option name="constraints">
<constraint name="Type">
<option name="type">string</option>
</constraint>
<constraint name="Date" />
</option>
</constraint>
</property>
</class>
But be aware that if you want to have nested Chain constraints, like:
<?php
$constraint = new Chain([
new Callback(...),
new Chain([new Type('string'), new Date()]),
]);
you have to override the validator.validator_factory symfony service to fix the issue with handling nested constraints in the current implementation: https://github.com/symfony/Validator/blob/fc0650c1825c842f9dcc4819a2eaff9922a07e7c/ConstraintValidatorFactory.php#L48.
See the NoCacheConstraintValidatorFactory.php file from the gist to get an idea how it could be solved.
As of Symfony 2.3 you can do this using Group Sequences (though form support for group sequences might be spotty).

Resources