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

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;
}

Related

How to handle file upload in symfony?

im trying to upload diffrent types of files in symfony
$uploadedFile = $request->files->get('image');
Works good for handling with images, However i cannot use it with diffrent files than
$uploadedFile = $request->files->get('file');
dd($uploadedFile);
Whatever i send using this, dd method shows me null.
How can I upload files for example pdfs, docx etc. (diffrent than images)
I use vue on the frontend.
You should use createForm.
https://symfony.com/doc/current/controller/upload_file.html
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** #var UploadedFile $brochureFile */
$brochureFile = $form->get('brochure')->getData();
// this condition is needed because the 'brochure' field is not required
// so the PDF file must be processed only when a file is uploaded
if ($brochureFile) {
$originalFilename = pathinfo($brochureFile->getClientOriginalName(), PATHINFO_FILENAME);
// this is needed to safely include the file name as part of the URL
$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
$newFilename = $safeFilename.'-'.uniqid().'.'.$brochureFile->guessExtension();
// Move the file to the directory where brochures are stored
try {
$brochureFile->move(
$this->getParameter('brochures_directory'),
$newFilename
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
// updates the 'brochureFilename' property to store the PDF file name
// instead of its contents
$product->setBrochureFilename($newFilename);
}

How to remove query string from static resource?

I've tried it with
https://www.drupal.org/project/remove_querystring_from_static_resource
But it doesn't work well for me .
How can I achieve that programmatically?
The following is the test result:
This trouble is usually encountered when static resources (eg. images, css & javascript files) are accessed using a query string.
Eg: http://example.com/image.png?something=test
Those query strings are used for avoiding browser caching. Their values are changed, so the browser should do a new request instead of getting cached resource.
You should remove those query strings (?something=test in my example) and use some suitable Cache-Control headers.
Edit:
Try this code.
Replace THEMENAME with your theme name.
/**
* Implements template_process_html().
* Remove Query Strings from CSS & JS filenames
*/
function THEMENAME_process_html( &$variables) {
$variables['styles'] = preg_replace('/\.css\?[^"]+/', '.css', $variables['styles']);
$variables['scripts'] = preg_replace('/\.js\?[^"]+/', '.js', $variables['scripts']);
}
/**
* Implement hook_image_style
* Override theme image style to remove query string.
* #param $variables
*/
function THEMENAME_image_style($variables) {
// Determine the dimensions of the styled image.
$dimensions = array(
'width' => $variables['width'],
'height' => $variables['height'],
);
image_style_transform_dimensions($variables['style_name'], $dimensions);
$variables['width'] = $dimensions['width'];
$variables['height'] = $dimensions['height'];
// Determine the URL for the styled image.
$variables['path'] = image_style_url($variables['style_name'], $variables['path']);
// Remove query string for image.
$variables['path'] = preg_replace('/\?.*/', '', $variables['path']);
return theme('image', $variables);
}
Finally I solved the issue with this code:
use Drupal\Core\Asset\AttachedAssetsInterface;
/**
* Implements hook_css_alter().
*/
function bootstrap_css_alter(&$css, AttachedAssetsInterface $assets){
foreach ($css as &$file) {
if ($file['type'] != 'external') {
$file['type'] = 'external';
$file['data'] = '/' . $file['data'];
}
}
}
/**
* Implements hook_js_alter().
*/
function bootstrap_js_alter(&$javascript, AttachedAssetsInterface $assets){
foreach ($javascript as &$file) {
if ($file['type'] != 'external') {
$file['type'] = 'external';
$file['data'] = '/' . $file['data'];
}
}
}
Put this code to your yourthemename.theme file.
it works perfect on drupal 8
Hope this help you guys.

Concrete5 - CMS :: Get all file inside a file manager folder programmatically

I have a folder structure likes this:
folder1
subfolder1
file1.pdf
file2.pdf
subfolder2
file3.pdf
file4.pdf
is there any way to retrieve all the pdf file's(programmatically) using the "folder1" id?
There is but make sure you don't go insanely deep with your folder structure, you don't want to go through hundreds of folders, hundreds of levels deep.
Here's the code
<?php
use Concrete\Core\Tree\Node\Type\FileFolder;
use Concrete\Core\File\FolderItemList;
// First grab the folder object
$folder = FileFolder::getNodeByName('Testing Folder');
if (is_object($folder)) {
$files = [];
// if we have a folder we need to grab everything inside and then
// recursively go through the folder's content
// if what we get is a file we list it
// otherwise if it's another folder we go through it as well
$walk = function ($folder) use (&$files, &$walk) {
$list = new FolderItemList();
$list->filterByParentFolder($folder);
$list->sortByNodeName();
$nodes = $list->getResults();
foreach ($nodes as $node) {
if ($node->getTreeNodeTypeHandle() === 'file'){
$files[] = $node->getTreeNodeFileObject();
} elseif ($node->getTreeNodeTypeHandle() === 'file_folder'){
$walk($node);
}
}
};
$walk($folder);
// we are done going through all the folders, we now have our file nodes
foreach ($files as $file) {
echo sprintf('%sfile name is %s and URL is %s%s', '<p>', $file->getTitle(), $file->getURL(), '</p>');
}
}

Adding views programmatically to custom module in drupal 7

I am a newbie and have started writing modules. I need to add multiple views in 1 module. I have added 1 view using hook_views_api() and hook_views_data(). Please can anybody help in adding more views in single module?
This topic has been dormant for a number of years but has had no proper answer. So allow me.
The problem above is that you are listing your views in the same file, which is messy and unorganized. Below is a more appropriate and straightforward way of doing things.
Firstly i suggest creating a folder in your module directory, for example "YOUR_MODULE/views/".
Then for each view you would like to import you will create a new file such as "my_view.inc" with one file being one view. This makes it easier to find the view your looking for if you need to make changes later on.
Then is to declare which api you will use for your imports.
/**
* Implements hook_views_api().
*/
function YOUR_MODULE_views_api() {
return array(
'api' => '3.0',
);
}
Once you have declared the api version you will need the following below.
/**
* Implements hook_views_default_views().
*/
function YOUR_MODULE_views_default_views() {
$views = array();
$path = drupal_get_path('module', 'YOUR_MODULE') . '/views/*.inc';
foreach(glob($path) as $file) {
require_once $file;
$views[$view->name] = $view;
unset($view);
}
return $views;
}
What this does is look for all the "my_view.inc" files inside the subdirectory and will load them all automatically after a Clear Cache.
Hope this helps those who are still stuck.
Be sure to declare hook_views_api() or this hook won't get fired.
But you do this via hook_views_default_views()
In Views, you create the View you would like to include in the module. Then you use function hook_views_default_views() and attach the export code (from views) like so:
function yourmodulename_views_default_views() {
// Begin copy and paste of output from the Export tab of a view.
$view = new view;
// ..yadda yadda yadda
// Add view to list of views to provide.
$views[$view->name] = $view;
// Begin copy and paste of output for another view
$view = new view;
// ..yadda yadda yadda
// Add view to list of views to provide.
$views[$view->name] = $view;
return $views
}
The return $views at the end of the function will return all of the views for you.

Drupal 7 user picture link

I just need the link of the profile picture of the current logged-in user in Drupal 7. I tried this:
global $user;
print $user->picture;
output: 2
And this:
global $user;
print theme('user_picture', array('account' => $user));
Output: the image as a < img >-element
The picture is stored as a reference to a file in the files table, you can load the file and extract the path like this:
global $user;
$fid = $user->picture;
$file = file_load($fid);
$uri = $file->uri; // URI path, e.g. public://image.jpg
$path = file_create_url($uri); // Web accessible path, e.g. /sites/default/files/image.jpg

Resources