Delete image on database delete symfony2 - symfony

Symfony Forms
I have this all working correctly. One thing that I am not sure is how to delete the image that is uploaded in the uploads folder when the associated entry in the database is deleted.
I really just need an idea on how to do it to get headed in the right direction.
Thanks in advance.

You are both correct I did a var dump on the code that was in the entity...
/**
* #ORM\PostRemove
*/
public function removeUpload()
{
if(file_exists($file)) {
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
}
if file exists $file was showing an empty variable. In the upload it saves the variable as $logo
I changed the code to the following
/**
* #ORM\PostRemove
*/
public function removeUpload() {
// ** Original Code used file but logo has the name in it.
if(file_exists($this->getAbsolutePath())) {
if ($this->getUploadRootDir() . $this->logo = $this->getAbsolutePath()) {
unlink($this->logo);
}
}
}
It now deletes the file correctly. Thank you both.

In your delete action, you would have to delete the file manually. I assume you will be storing the file path in the database, so this should be relatively easy.
$path = ....//query db to get the path to the file
if($path){
unlink($path);
}
//now you can delete the record in the database
See php docs for deleting a file

What you are probably searching for are Doctrine2 Lifecycles. Just add a method to your entity:
/**
* #ORM\PreRemove
*/
public function deleteImage()
{
// unlink your image and what not.
}
Also don't forget the #ORM\HasLifecycleCallbacks() annotation for your entity class.

Related

Symfony - Doctrine Listener create url from name

can someone please explain, how to create listener to fill url field from name field without using existing slug libraries?
Example:
Name filed: this is an example #1
Url field: this-is-an-example-1
Now I have it in __constructor in entitiy... But I want to know how to use listeners... And I can't find example on google.
Thank you
You can try something like this :
/**
* #ORM\HasLifecycleCallbacks()
*/
class YourEntity
{
/**
* #ORM\PrePersist
*/
public function slugify()
{
$name = $this->getName();
$slug = functionToSlugify($name)
$this->setUrl($slug);
}
}
So you can create your own slugify function and before persisting your entity it will set your url for you.
That said, I highly recommend Doctrine Extension Bundle :
http://symfony.com/doc/current/doctrine/common_extensions.html
There's no point to reinvent the wheel ...

SilverStripe Subsite module delete all related data on subsite deletion

I m using Silverstripe subsite module. When Subsite is deleted I want to delete all other information related to Subsite as well, like, Domains, Settings etc. I have created an extension that'll extend Subsite model.
<?php
class SubsiteExtension extends DataExtension {
public function onAfterWrite(){
parent::onAfterWrite();
//Some codes here
}
public function onBeforeDelete(){
//Check if member exist for Subsite, if so show warning.
}
public function onAfterDelete(){
$id = $this->owner->ID;
//DELETE ALL SUBDOMAINS RELATED TO DELETED SUBSITE
DB::query("DELETE FROM SubsiteDomain WHERE SubsiteID='".$id."'");
//DELETE SITE CONFIG
DB::query("DELETE FROM SiteConfig WHERE SubsiteID='".$id."'");
}
}
Problem
The code works flawlessly. Just wondering is there any other better way of deleting related records from other tables??
On method onBeforeDelete , how to show custom message saying "You can't delete this subsite unless you delete all the members" ?
Using onAfterDelete to delete related records is perfectly fine, although it really sounds a lot like you're doing unnecessary work here. Who's going to be bothered by some stray DB entries?
Regarding your onBeforeDelete approach: I would solve it otherwise. Override canDelete in your extension instead, something like this:
public function canDelete($member)
{
if( /* check if member exist for Subsite */ ){
return false;
}
// returning null here means that this extension doesn't influence
// the delete permission at this point
return null;
}
This will prevent deleting of the record in the CMS. Additionally, you could use updateCMSFields to display a notice to the user why he can't delete the record.
public function updateCMSFields(FieldList $fields)
{
if (!$this->owner->canDelete()) {
$fields->addFieldToTab(
'Root.Main',
LiteralField::create('_deleteInfo', 'Your info text')
);
}
}

Adding images from an external gallery to a SilverStripe site via a BuildTask

I'm making a Silverstripe build task to get many images from an external gallery, and create/upload them into the /assets/images/gallery folder with the necessary database links to the GalleryPage.
So I load the list of Urls, display the images to the browser, now how do I save an image into the assets folder with the necessary GalleryPage database links?
class ImportGalleryTask extends BuildTask {
public function writeImage($data) {
//$data->Title
//$data->Filename
//$data->Url
//this is the external url that I can output as an image to the browser
//
// folder to save image is 'assets/images/gallery'
//
// ? save into folder and database and associate to PageImageBelongsToID ?
}
}
You can use copy to copy a remote file to your local filesystem. PHP must be configured to support allow_url_fopen though.
So, your resulting function might look like this:
/**
* #param $data
* #return null|Image return written Image object or `null` if failed
*/
public function writeImage($data)
{
// The target folder for the image
$folder = Folder::find_or_make('images/gallery');
// assuming that $data->Filename contains just the file-name without path
$targetPath = $folder->getFullPath() . $data->Filename;
// Check if an image with this name already exists
// ATTENTION: This will overwrite existing images!
// If you don't want this, you need to implement this differently
if(
file_exists($targetPath) &&
$image = Image::get()->where(array(
'"Name" = ?' => $data->Filename,
'"ParentID" = ?' => $folder->ID
))->first()
){
// just copy the new file over…
copy($data->Url, $targetPath);
// … and delete all cached images
$image->deleteFormattedImages();
// and we're done
return $image;
}
// Try to copy the file
if (!copy($data->Url, $targetPath)) {
return null;
}
// Write the file to the DB
$image = Image::create(array(
'Name' => $data->Filename,
'ParentID' => $folder->ID,
'Filename' => $folder->getRelativePath() . $data->Filename
));
$image->write();
return $image;
}

Sonata media bundle - get pdf file by name or change filename on update

I currently use SonataAdminBundle and SonataMediaBundle.
I have a problem with the media bundle files because my pdf file is not saved with its name but with md5 or another format.
For example:
media table
id : 1
name : iphone.pdf
provider_reference : 9a0b7a35131e23f91666324562c52f08b7cb6604.pdf
I don't want to get my pdf by this:
9a0b7a35131e23f91666324562c52f08b7cb6604.pdf
but with its name ( iphone.pdf ).
I want to know if it's possible to:
get the pdf file by name?
or
save my pdf file with a particular name?
use this in your Twig so you can download it with its name:
{{ path('sonata_media_download', {'id': (your media object here|sonata_urlsafeid)}) }}
To see it without download, I'm searching for that , I'll be back if I find something.
Good luck!
If you want get public URL for file in PHP-code, you can use something like this (code from my Application\Sonata\MediaBundle\Helper\MediaHelper)
public function getPublicUrl(Media $media, $format = 'reference')
{
if (!$media) {
return '';
}
/** #var ImageProvider $provider */
$provider = $this->container->get($media->getProviderName());
$format = $provider->getFormatName($media, $format);
return $provider->generatePublicUrl($media, $format);
}
If you need link in twig, you can find special helper in SonataMedia official docs (I forgot name of helper).

Inserting file content into MySQL database via FormBuilder in Symfony2

In my Symfony2 app I have a need to provide an option to upload a text file. I've already achieved this by using the FormBuilderInterface to create a field with the 'file' type. The file gets uploaded properly but all I really need is to fetch the text from the file and insert it into the proper db table column. Is there a way to fetch the text from an uploaded file on POST? Thanks.
There are at least two ways.
Using Form Events
Using lifecycle callbacks
In both cases the main point is to open uploaded and fill its content to the entity property (after form posted but before data persisted to db). So you need to have 2 entity properties for this: uploaded file handler (not mapped to the db) and file text itself (mapped to the db).
Here is an example with the lifecycle callbacks:
Entity:
/**
* #ORM\Entity()
* #ORM\HasLifecycleCallbacks
*/
class SomeEntity {
/**
* Virtual field used for handling the file
*
* #Assert\File()
*/
private $fileHandler;
/**
* #var string
*
* #ORM\Column(type="text")
*/
private $file;
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function saveFileContent()
{
$tmpName = md5(uniqid(mt_rand(), true)) . '.' . $this->fileHandler->guessExtension();
try
{
$this->fileHandler->move(
'../../../tmp/',
$tmpName
);
} catch (\Exception $e) {}
$this->setFile(file_get_contents('../../../tmp/' . $tmpName));
unlink('../../../tmp/' . $tmpName);
}
}
This also might be helpfull: How to handle File Uploads with Doctrine

Resources