I'm using the following module for uploading multiple images:
https://github.com/bummzack/sortablefile
I use the has-many relationship.
class PortfolioPage extends Page
{
private static $has_many = array(
'Images' => 'PortfolioImage'
);
class PortfolioImage extends Image
{
private static $has_one = array(
'PortfolioPage' => 'PortfolioPage'
);
}
The problem is that when uploading multiple images with the same file name it gives me the following error: File with the same name already exists .
How can I avoid this such that it will be possible to upload multiple images when they have the same filename?
Thank you
SortableUploadField is extending the UploadField, try adding setOverwriteWarning to False in your getCMSFields section. Check the code below:
$uploadField = new SortableUploadField('Images', 'Upload Images');
$uploadField->setOverwriteWarning(FALSE);
$fields->addFieldToTab("Root.Main", $uploadField);
Take note, this only prevents the error and rename the duplicate file name. Example: if you upload same file name like file.jpg, the second file.jpg will be renamed to 2.jpg, 3.jpg, etc.
Actually this error is "natural" behavior, it's impossible to store multiple files with identical names in one directory.
Please read discussion on GitHub for more information.
Related
I'am searching for solution for adding metadata to a sys_file fileObject in TYPO3 Extbase.
I'am adding a file to the storage in this way:
$resourceFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class);
$storage = $resourceFactory->getDefaultStorage();
$fileObject = $storage->addFile(
$temporaryFile,
$storage->getFolder('some-folder/'),
$newfilename
);
And can manipulate a bunch of properties with updateProperties() like so:
$fileObject->updateProperties(array(
'name' => 'foo',
));
But how can I set further metadata properties in sys_file_metadata like title or alternative texts when I create the file? Is there a documentation out there, how to do this. I have only found this:
https://docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/ApiOverview/Fal/UsingFal/ExamplesFileFolder.html#
But this documentation contains no hints about metadata handling.
I solved it using the MetaDataAspect which is available on a File object.
$metaData = $fileObject->getMetaData();
$metaData->offsetSet('title', 'Image title');
$metaData->save();
Use with care, as the save method is marked as #internal. Also checkout this changelog document, which is the only document I could found.
I'm following the steps outlined in this documentation https://symfony.com/doc/current/controller/upload_file.html to allow a file to be uploaded. It is working perfectly for adding a new item, but when I try to edit my entity, I'm getting the following error:
The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.
I've tried code like what is suggested in that article to append the path of the folder as File type to the entity like this in my update method:
public function editAction(Request $request, Advertiser $advertiser)
{
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
$editForm = $this->createForm(AdvertiserType::class, $advertiser);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('advertiser_list');
}
return $this->render('advertiser/index.html.twig', [
'form' => $editForm->createView()
]);
}
The logo_directory parameter is properly defined (and working fine for creating new entities).
Please let me know if you have any ideas what I am doing wrong.
Thanks for the help.
UPDATE: In this article The form's view data is expected to be an instance of class ... but is a(n) string there is a proposed solution to include in the form builder code the following:
->add('file', FileType::class, array('data_class' => null))
So I'm doing this now and the edit form will show - but it doesn't prepoulate with the previous selection.
->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])
Any thoughts on how this can be changed to allow the form to show with the previous selection pre-populated?
Setting a null data_class will remove the warning but it will not work, you don't need it at this point.
This is due to the fact that once your file is persisted, what remains in your database is just a path, not the file itself (which is on disk);
If you want to edit this entity again, the path (a string) must be converted to a File entity again; That's what the error message says.
.. and this is what you did when you wrote :
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
Now, the problem that remains is that you want to prepopulate the file field. In fact, that is not possible, since the file field points to a location in your own computer, not to a file on your server (and you cannot automatically upload something from someone's computer like that, that would be very dangerous).
What you want to do is possibly indicate that a file is already stored, get its path and maybe display it to your user.
So in your Twig template, something like that (change with your real logo directory) :
{% if form.logo.vars.data %}
<img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}
Hope it's clear.
I've one repository where I create some Site for store all documents and folders that my organization create.
I've one web app that include this php library https://github.com/dkd/php-cmis-client (port of Apache Chemistry Java implementation).
So I can creates documents, folder, set some properties, etc... but I would like to do "more".
I would like to extend the model and create my own model. In this case, It's very simple, I create "myPersonal" model, and create one custom type 'folderAmp' (his parents is cm:folder). And I extend this custom type and create a new property "myP:idNew" where I want to store some id code.
So, When I create a folder with this library (or maybe in java) I create it with...
JAVA
Folder parent = ....
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.NAME, "a new folder");
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
// create the folder
Folder newFolder = parent.createFolder(properties);
PHP
$properties = array(
\Dkd\PhpCmis\PropertyIds::OBJECT_TYPE_ID => 'cmis:folder',
\Dkd\PhpCmis\PropertyIds::NAME => 'Demo Folder'
);
try {
$folder = $session->createFolder(
$properties,
$session->createObjectId($session->getRepositoryInfo()->getRootFolderId())
);
So if I want to add my new custom type... What I've to do?
I try to add with this:
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder, myP:folderAmp" but it doesn't works.
You are looking for createType(). Not all repositories support it.
Get the CMIS Workbench from https://chemistry.apache.org/java/download.html , login into your repository, and open the "Types window". Select the folder type (cmis:folder). If the "Create Type" button on the top is enabled you can create a new subtype of cmis:folder. If not, either the repository doesn't support it or you don't have the permissions to do this.
But...if create type button is not enable... this repository is not "CMIS standar" ¿no?
Finally, the problem I solved it...very simple... I change
$properties = array(
\Dkd\PhpCmis\PropertyIds::OBJECT_TYPE_ID => 'cmis:folder',
\Dkd\PhpCmis\PropertyIds::NAME => 'Demo Folder'
);
try {
$folder = $session->createFolder(
$properties,
$session->createObjectId($session->getRepositoryInfo()->getRootFolderId())
);
By this...
$properties = array(
\Dkd\PhpCmis\PropertyIds::OBJECT_TYPE_ID => 'F:oto:Historia',
\Dkd\PhpCmis\PropertyIds::NAME => 'Demo Folder'
);
try {
$folder = $session->createFolder(
$properties,
$session->createObjectId($session->getRepositoryInfo()->getRootFolderId())
);
Where oto it's a model and Historia it's a custom type that I create with Alfresco Console Admin. I included all parent (cm:folder) properties in oto:Historia and create same custom properties.
When I create the folder, it's create with oto:Historia type.
I need to import a list of terms into my taxonomy from a source I loaded in the database.
The problem is I allready have this taxonomy on my site (loaded wihtout migrate) with terms that are used by reference in other content, so I got to keep existing term and update them or create the new ones.
To link my taxonomy source and the existing taxonomy I have an unique code for each term, so I added a code field to my vocabulary and filled it for each existing term.
I am currently able to create and update terms with my current Migration class, but if the name of my term on the site and the name of the term in my source is different, the import will create a new term instead of updating its name even if the code is the same.
Here my Migration Class :
class TotoMigration extends Migration {
private $list_term = array();
public function __construct($arguments) {
parent::__construct();
$this->softDependencies = array('TotoParent');
// get data from the custom table containing the new terms to create or update
$query = db_select('toto', 'f')
->fields('f', array(
'CODE', // code
'LIBLONG', // name
'PARENT', // parent
)
);
$this->source = new MigrateSourceSQL($query);
$this->destination = new MigrateDestinationTerm('toto_tax');
$this->map = new MigrateSQLMap($this->machineName,
array(
'CODE' => array('type' => 'varchar',
'length' => 5,
'not null' => TRUE,
'description' => 'Code',
)
),
MigrateDestinationTerm::getKeySchema()
);
$this->addFieldMapping('name', 'LIBLONG');
$this->addFieldMapping('field_code', 'CODE');
$this->addFieldMapping('parent', 'PARENT')
->arguments(array('source_type' => 'tid'))
->sourceMigration('TotoParent');
// create a list of existing toto terms with code => tid
$list_term = db_query("select fc.field_code_value, ttd.tid
from taxonomy_term_data ttd
left join taxonomy_term_hierarchy tth on tth.tid=ttd.tid
left join field_data_field_code fc on fc.entity_id = ttd.tid
where ttd.vid=10
and tth.parent!=0;")->fetchAllKeyed();
}
public function prepareRow($row) {
// Always include this fragment at the beginning of every prepareRow()
// implementation, so parent classes can ignore rows.
if (parent::prepareRow($row) === FALSE) {
return FALSE;
}
// if the destination is not mapped in migrate we tell him where to go
if (!isset($row->migrate_map_destid1) && isset($list_term[$row->CODE])) {
$row->migrate_map_destid1 = $list_term[$row->CODE];
}
}
}
I then load the import with drush (and --update option).
I must be missing something, if anyone got a clue it will be welcome.
After many tries, the problem reside in the fact the module Migrate does not support Creating content and Updating content in the same migration class (I even read it will sometime claim to update content and just do nothing).
So the solution is pretty simple, create 2 classes :
One for Creating content
One for Updating content
Your Creating class will be the same.
Your Updating class will need to have a systemeOfRecord set to DESTINATION :
$this->systemOfRecord = Migration::DESTINATION;
So it knows to only update and not recreate the content, it will keep current fields not mapped and update fields mapped that are not part of the MigrateSQLMap :
$this->map = new MigrateSQLMap($this->machineName,array(...));
The tricky part will be to find corresponding nid/tid of your content so you can map it to your imported data and then to separate data used to update or create content.
I am getting a bit confused with loading my themes .MO file.
I have did a lot of searching on google and I got a version working but I don't understand why.
First of all, I have set my text domain in the themes CSS file:
Text Domain: beauty
I started out with the Roots theme, which does the after_setup_theme and I load the MO file there:
load_theme_textdomain('beauty', get_template_directory() . '/lang');
This MO file has a 'beauty' context and a 'roots' context.
The MO file is loading, cause when I dump $l10n[$domain] I see my 3 values the have the beauty context.
For the sake of space I will show only one entry:
array (size=3)
'beautyInloggen' =>
object(Translation_Entry)[218]
public 'is_plural' => boolean false
public 'context' => string 'beauty' (length=6)
public 'singular' => string 'Inloggen' (length=8)
public 'plural' => null
public 'translations' =>
array (size=1)
0 => string 'Login' (length=5)
public 'translator_comments' => string '' (length=0)
public 'extracted_comments' => string '' (length=0)
public 'references' =>
array (size=0)
empty
public 'flags' =>
array (size=0)
empty
I have 2 locals in my site, nl_NL and en_UK. This are set using WPML and are loaded correctly.
I have a nl_NL.mo and an en_UK.mo file in the lang folder of the theme.
So, this all looks good.
However, in my header.php I have a login anchor:
<?php _e( 'Inloggen', 'beauty' ); ?>
which in my understanding should load the context 'beauty' and the key 'Inloggen'.
So, it doesn't work when I am in my locale nl_UK, I see the standard Dutch text of 'Inloggen' instead of 'Login'.
Strangely, when I remove the msgctxt "beauty" context from my PO file and save it to create a new MO file, it DOES work.
I have used contexts before in my plugin where I use load_textdomain for loading MO files and that works fine.
The reason I want to use contexts is because the one file contains Roots and Beauty related texts and I am only interested in the Beauty texts. I don't want to remove all the _e entries of the Roots theme so it doesn't come up when I load sources.
So that was one question.
Question 2 is less important but also puzzling me: When I look at the example of the theme twentyfiftheen the have their PO and MO files in the wp-content/languages/themes/ folder as twentyfiftheen-nl_NL.mo.
I read this great article (https://localise.biz/help/wordpress/loading-translations) and this post (https://wordpress.stackexchange.com/questions/137427/themes-text-domain-language-po-file-not-working) and understood that you should always give the MO file the name of the locale and not of the contextname + locale.
In this nice doc (https://localise.biz/help/wordpress/loading-translations) I find
So in short, WordPress will look in only two places for a theme's MO file:
{absolute_path}/{locale}.mo
wp-content/languages/themes/{domain}-{locale}.mo
e.g. for twentyfourteen's French translations:
wp-content/themes/twentyfourteen/languages/fr_FR.mo
wp-content/languages/themes/twentyfourteen-fr_FR.mo
However, when I had my MO/PO file in the wp-content/languages/themes it wasn't working, but It could be related to the same issue I have with the context (question 1).
cheers
Okay, I found out that I abused the Context attribute in POEdit as if it was a domain.
I was confused by another post thinking that it would work like that.
Well it doesn't.
So I did what #Václav Slavík recommended and wrapped the _e and __ functions into my own functions so that POEdit could search for those end I would not get the Roots language tags in my files.
Problem solved.
It also loads from the default language folder of Wordpress, it was all related to the context/domain confusion.