Backpack Crud have clone function. But it isn't work when our table has unique field column.
Backpack clone Documentation
When table has unique column how to clone it?
public function clone($id)
{
$this->crud->hasAccessOrFail('clone');
$this->crud->setOperation('clone');
$clonedEntry = $this->crud->model->findOrFail($id)->replicate();
return (string) $clonedEntry->push();
}
Recently I experienced the same problem. Here is my solution:
public function clone($id)
{
$this->crud->hasAccessOrFail('clone');
$this->crud->setOperation('clone');
$clonedEntry = $this->crud->model->findOrFail($id)->replicate();
// now resolve the value for unique attribute before save. e.g.
$slug = Str::slug($clonedEntry->name, '-');
$count = $this->crud->model->whereRaw("slug RLIKE '^{$slug}(-[0-9]+)?$'")->count();
$clonedEntry->slug = $count ? "{$slug}-{$count}" : $slug;
// when you are done, save changes
return (string) $clonedEntry->push();
}
You didn't specify anything about that "unique" attribute. Feel free to customize the resolver according your needs.
Related
Hy,
I'm trying to call my action with allways a fixed Uid (configured by TS) so I could put a plugin on my page to register for a specific Event. And don't have to go over a Event List click the Event click register.
I tried the following which did not work out:
public function newAction(
\XYZ\xyz\Domain\Model\Registration $newRegistration = NULL,
\XYZ\xyz\Domain\Model\Event $event = 'DD8B2164290B40DA240D843095A29904'
)
The next didn't one work either!
public function newAction(
\XYZ\xyz\Domain\Model\Registration $newRegistration = NULL,
\XYZ\xyz\Domain\Model\Event $event = Null
) {
$myinstance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
'XYZ\\xyz\\Domain\\Model\\Event'
);
$event = $myinstance->findByUid('DD8B2164290B40DA240D843095A29904');
.......
}
So I was woundering is there a way to give my fixed Uid to the action?
In TYPO3 calling Extbase actions is done in the routing and dispatching components - to pass anything from the outside that is different from a numeric uid value a custom property TypeConverter would have to be implemented that transforms a particular string pattern into a value domain object of type Event.
However, there's a simpler approach by using configuration:
1) Provide configuration in TypoScript
Extbase uses a strong naming convention based on the extension name and optionally the plugin name. Thus, either tx_myextension or tx_myextension_someplugin can be used - latter is more specific for for according somePlugin. Besides that settings are automatically forwarded and provided in an Extbase controller context - accessible by $this->settings.
plugin.tx_xyz {
settings {
newActionEventIdentifier = DD8B2164290B40DA240D843095A29904
}
}
2) Retrieve data via repository
\XYZ\xyz\Domain\Repository\EventRepository
Use a dedicated EventRepository::findByIdentifier(string) method to retrieve the data. The property names are just assumptions since there are no explicit mentions how exactly the event data is persisted and whether it is persisted in a relational DBMS at all.
<?php
namespace XYZ\xyz\Domain\Repository;
class EventRepository
{
public function findByIdentifier($identifier)
{
$query = $this->createQuery();
$query->matching(
$query->equals('event_id', $identifier)
);
return $query->execute();
}
}
3) Putting all together in the according controller
The $event property was removed from the action since that entity is pre-defined and cannot be submitted from the outside (and to support the string to Event entity transformation a custom TypeConverter would be required as mentioned earlier).
public function newAction(
\XYZ\xyz\Domain\Model\Registration $newRegistration = null
) {
$event = $this->eventRepository->findByIdentifier(
$this->settings['newActionEventIdentifier']
);
if ($event === null) {
throw new \RuntimeException('No event found', 1522070079);
}
// the regular controller tasks
$this->view->assign(...);
}
I have a tricky question about the inheritance of TYPO3 models:
I want to extend the extension powermail with two seperate/independed (!) extensions. The first extend powermail TCA-forms and needs the new fields in the fluid template. The second extends also the TCA-forms, but not need an output in the frontend.
Now I use the mixed-ins hack from Franz Koch http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2010-September/006497.html which using the delete field as record type. But this solution works only for one extension. According to the loading of the TS persistence settings either the first or the second model of the extension will be loaded.
If I use an own field for the record type – eg. for the field record of powermail – I can use only one record type for the one extension, but can't access to the other.
Is there a way to "merge" ALL models related to the base model?
Next current TS config:
config.tx_extbase {
persistence {
classes {
# Using mixed-ins hack from Franz Koch to make map table extendable.
# #see http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2010-September/006497.html
Tx_Powermail_Domain_Model_Fields {
mapping.recordType = 0
subclasses.0 = Vendor\MyExtension\Domain\Model\Powermail\Fields
}
Vendor\MyExtension\Domain\Model\Powermail\Fields {
mapping {
tableName = tx_powermail_domain_model_fields
recordType = 0
columns {
tx_myfirstextension_field_one.mapOnProperty = FieldOne
}
}
}
}
}
}
ext_tables.php:
// Using mixed-ins hack from Franz Koch to make map table extendable.
// #see http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2010-September/006497.html
$TCA['tx_powermail_domain_model_forms']['ctrl']['type'] = 'deleted';
$TCA['tx_powermail_domain_model_pages']['ctrl']['type'] = 'deleted';
$TCA['tx_powermail_domain_model_fields']['ctrl']['type'] = 'deleted';
I am new to the Zend Framwork. I would like to add search function on the existing module. When the user enters the name in the textbox it should return the corresponding record. Could someone help me to add this function?
Thanks
PS: I don't want to use lucene
use this function:
define thes variable in your model
and add this function
protected $_name = 'your_table_name';// table name
public function getAll($order = null, $count = null, $offset = null) {
$rows = $this->fetchAll(NULL, $order, $count, $offset);
return $rows->toArray();
}
I am using Yii together with PostgreSQL and PostGIS in my application. I have a model "User" with a field "Location". The content of the Location-field makes no sense what so ever to a human, but Postgres can convert the value of the Location-field and turn it into Longitude and Latitude using the ST_asText-method. I have created dummy fields in my model for longitude and latitude. When i save my model, i use the beforeSave and afterSave methods to set location to it's right value.
My problem now is that i want the latitude and longitude dummy fields to be populated upon model creation (with existing objects in the db). I was thinking that there might be something like beforeSelect and afterSelect that i can use to append the query with an extra calculated column, and therefore be able to process the values returned from that extra column after the query has been ran.
Is this possible somehow?
I was able to solve this pretty easy. I was looking for a beforeSelect and afterSelect method in the CActiveRecord class when i should have been looking for beforeFind and afterFind.
Here's how i did it. Any improvement suggestion are welcome :)
public function beforeFind(){
$criteria = new CDbCriteria;
$criteria->select = "*,ST_asText(location) as location";
$this->dbCriteria->mergeWith($criteria);
return parent::beforeFind();
}
public function afterFind(){
$location = str_replace('POINT(','',$this->location);
$location = str_replace(')','',$location);
$location = explode(" ", $location);
$this->lon = $location[0];
$this->lat = $location[1];
return parent::afterFind();
}
I met this problem with Yii2 and here is how I solved it.
Override find() method of AR and define your own ActiveQuery class:
public static function find()
{
$query = new MyActiveQueryClass(get_called_class());
return $query->select('*, ST_AsGeoJSON(location) AS location');
}
In afterFind() you will have geo-json and with that you can get lat/lng:
public function afterFind()
{
parent::afterFind();
$geoJson = json_decode($this->location, true);
$this->lat = $geoJson['coordinates'][0];
$this->lng = $geoJson['coordinates'][1];
}
That is it for Yii2. Remember to convert your lat/lng to correct object before saving. Mine was geography column. Here is a bonus:
public function beforeSave($insert)
{
//create field as expression
if(!empty($this->lat) && !empty($this->lng))
$this->location = new \yii\db\Expression("'POINT({$this->lat} {$this->lng})'");
return parent::beforeSave($insert);
}
is there a way how to use Zend_Db relations for setting related objects?
I am looking for something like following code:
$contentModel = new Content();
$categoryModel = new Category();
$category = $categoryModel->createRow();
$category->setName('Name Category 4');
$content = $contentModel->createRow();
$content->setTitle('Title 4');
$content->setCategory($category);
$content->save();
this provides small library:
http://code.google.com/p/zend-framework-orm/
does somebody have experience with that? Isn't there a plan for something similar in ZF ? Or is there something better for use? (I don't wnat to use doctrine ORM or something external)
thanks
I designed and implemented the table-relationships code in Zend Framework.
A foreign key ($content->category in your example) contains the value of the the primary key in the parent row it references. In your example, the $category doesn't contain a primary key value yet because you haven't saved it (assuming it uses an auto-incrementing pseudokey). You can't save the $content row until you populate its foreign key, so referential integrity is satisfied:
$contentModel = new Content();
$categoryModel = new Category();
$category = $categoryModel->createRow();
$category->setName('Name Category 4');
$content = $contentModel->createRow();
$content->setTitle('Title 4');
// saving populates the primary key field in the Row object
$category->save();
$content->setCategory($category->category_id);
$content->save();
It would do no good to pass the Row object to setCategory() if it doesn't have the primary key populated. $content->save() will fail if it doesn't have a valid primary key value to reference.
Since you need that primary key field to be populated in any case, it's not so difficult to access the field when you call setCategory().
I always override Zend_Db_Table and Zend_Db_Table_Row and use my own subclasses. In my Db_Table class I have:
protected $_rowClass = 'Db_Table_Row';
In my Db_Table_Row I have the following __get() and __set() functions:
public function __get($key)
{
$inflector = new Zend_Filter_Word_UnderscoreToCamelCase();
$method = 'get' . $inflector->filter($key);
if(method_exists($this, $method)) {
return $this->{$method}();
}
return parent::__get($key);
}
public function __set($key, $value)
{
$inflector = new Zend_Filter_Word_UnderscoreToCamelCase();
$method = 'set' . $inflector->filter($key);
if(method_exists($this, $method))
return $this->{$method}($value);
return parent::__set($key, $value);
}
Bascially that just tells the class to look for methods called getFoo() and setFoo() or whatever. You could then pretty much make up your own fields as long as your write your own logic behind. In you case maybe:
public function setCategory($value)
{
$this->category_id = $value->category_id;
}