Hi i'm new in Laravel and i've this simple problem. I have app where user can create some article and also can to upload main image for that article and it works perfect. I also want to give possibility to user to upload more images for his article. I already create model (ArticleImage) and add relationship between Article and ArticleImage. And i created form field for uploading multiple file inside the article form. But i don't know now how to tell laravel to save all names of these paths into database and store image inside the public/images folder, than later in views i can use these images. Do i need now to create ArticleImage controller and inside controller to write that function or i should do that inside Article controller inside store function. Tnx in advance for every help.
Here is link to github-repo(https://github.com/Dabizlja/Laravel-blog)
If form sends input as array.
<input name="picures[]" />
In your ArticleController on save you can use a json type
$files=[];
$pictures = $request['pictures'];
if (count($pictures) > 0 && $pictures[0] != null) {
foreach ($pictures as $picture) {
$validator = Validator::make([$picture], ['mimes:jpeg,jpg,bmp,png']);
if ($validator->fails()) {
return $validator->messages()->all();
}
$picture->move(public_path() . '/images/', $picture->getClientOriginalName());
array_push($files, $picture->getClientOriginalName());
}
}
$article->images = json_encode($files);
To get it back in the view
<?php
foreach ( $images as $file) {
echo '<img src="'asset('/images/' . $file)'"/>';
}
?>
In your controller on edit remember to decode the json
$files = json_decode($article->images);
To delete a picture you would have to go through the array and remove it the same way.
Hope this works for you.
May be
$article->articleImages()->saveMany($images);
Hopefully this will solve your problem
Related
I'm created a new script with php. I manipulate the picture uploaded by the user with 40 different models and show them in the page.
The user has to wait until all 40 pictures are prepared with my current code.
$file = $this->post['uploaded_image'];
$models = $this->post['models'];
/*
User selected models, etc:
['model-1', 'model-2', 'model-8', 'model-14', 'model-22', 'model-34', 'model-35', 'model-40']
*/
foreach ($models as $model) {
$resize_image = $this->resize($file, $model);
$final_image = $this->crop($resize_image, $model, $file);
return $final_image;
}
I want to do is to use each image that return from the loop in order. While I use the first image and the loop continues to render in the 2nd, 3rd...
I hope I explained my problem correctly. How can I solve this problem with php or javascript?
I have created view that displays on page 10 newest article. I have in row two fields: image and content. In settings of image field I chose image style (for example: medium). How can I change image style to another (example: large) only in first row?
I have tried it in preprocess but i don't know where is stored information about image style:
function theme_preprocess_views_view_unformatted__lista_depesz_default(&$variables) {
$view = $variables['view'];
$rows = $variables['rows'];
$style = $view->style_plugin;
$options = $style->options;
$variables['default_row_class'] = !empty($options['default_row_class']);
foreach ($rows as $id => $row) { $variables['rows'][$id] = array();
$variables['rows'][$id]['content'] = $row;
$variables['rows'][$id]['attributes'] = new Attribute();
if ($row_class = $view->style_plugin->getRowClass($id)) {
$variables['rows'][$id]['attributes']->addClass($row_class);
}
if ($id == 0 && $row['content']['#row']->_entity->field_image[0] != NULL) {
//some php code to change image style
}
}
}
Regards
You can create view with original images, and set style inside your twig files, using for example twig tweak:
https://www.drupal.org/project/twig_tweak
Inside twig file you can set any style with conditioning
{{ 'public://images/ocean.jpg' | image_style('thumbnail') }}
Regarding your code and your explanations, I'm not sure to understand what you are trying to achieve.
1/ you try to add a CSS class to the 1st image of your view. Why not using the following CSS path .my_view .first img {}
2/ if you try to call another image style, can you create a view with only the 1st item, or a promoted? Then a second view with the rest of the items ?
3/ if you try to call another image style, you can do it without any code.
You install the module http://drupal.org/project/views_conditional then you add 2 images with 2 different image style, and you apply your condition inside the condition fieldset.
I really prefer the solution 3 because it's pure Drupal build.
I hope it helps.
Cheers
hi i've got a gallery page. this gallery page has a gallery image object with an has_many relation.
private static $has_many = array(
'GalleryImages' => 'GalleryObject'
);
my gallery object has an image upload field. I want to set the upload folder to the title of the gallery page
i tried this with no result
$visual->setFolderName('Galerie/'.$this->Gallery()->Title);
and this (what i would prefer)
public function getGalleryTitle() {
$galleryTitle = $this->Gallery()->Title->First();
$uploadFolder = str_replace(' ', '-', $this->$galleryTitle);
return $uploadFolder;
}
$visual->setFolderName('Galerie/'.$this->$uploadFolder);
the second returns and error (undefined variable uploadFolder ?!) and my upload folder is now set to "Galerie/DataList"
can someone tell me how to convert the output of $uploadFolder so that i get back the title?
EDIT:
GalleryHolder: http://www.sspaste.com/paste/show/5267dea3579a6
GalleryPage: http://www.sspaste.com/paste/show/5267dee4c9752
GalleryObject: http://www.sspaste.com/paste/show/5267df0af1a65
you where almost there..
Here is your edited getGalleryTitle() function.
It is basically checking if the GalleryObject has a parent Gallery via $this->GalleryID. Since it is a has_one relation the column will be named GalleryID.
Then we get the Gallery object with $this->Gallery() and get it's title with $gallery->Title.
I've also replaced your str_replace with SilverStripe's URLSegmentFilter class. Which will removed spaces and other special characters non welcome in URL, a better solution.
public function getGalleryTitle()
{
if ( $this->GalleryID )
{
$gallery = $this->Gallery();
$filter = new URLSegmentFilter();
return $filter->filter( $gallery->Title );
}
else{
return 'default';
}
}
Then in the getCMSFields() function, when creating your UploadField we just call the getGalleryTitle() function that returns the string for the folder name.
$visual = new UploadField('Visual', _t('Dict.IMAGE', 'Image'));
$visual->setFolderName('Galerie/'.$this->getGalleryTitle());
A few notes..
$this references the current Object instance, so you can't use $this->$galleryTitle to access a variable you just created in your function, $galleryTitle by itself is enough.
You were calling $this->$uploadFolder in setFolderName, this doesn't work for the same reason, and also, using $uploadFolder by itself wouldn't work since this variable was created in the scope of another function. So we just call the function we defined on our Object with $this->getGalleryTitle() since it returns the value we want.
This should work fine, but keep in mind that if the Title of the Gallery changes at some point, the folder name will change too. So you might end up with images uploaded in many different folders for the same gallery... I personally wouldn't advise it, unless you implement some kind of "Title locking system" or some way to keep the "correct" or first "valid/acceptable" Gallery title in a separate object property that can't be edited and use this in the folder name.
I usually only use the ID in those case ($gallery->ID), as this will not change.
edit
Another version of getGalleryTitle() that should work even if the GalleryObject isn't saved yet.
public function getGalleryTitle()
{
$parentID = Session::get('CMSMain')['currentPage'];
if ( $parentID )
{
$gallery = Page::get()->byID( $parentID );
$filter = new URLSegmentFilter();
return $filter->filter( $gallery->Title );
}
else{
return 'default';
}
}
First, I check to see whether we're on the CMSSettingsPage or in a ModelAdmin page (Should you be using them). You want to get all the information about which class the controller is managing as it's data record. (If you have firebug, FB($this) in getCMSFields() on the related DataObject (DO) will show you the page managed under DataRecord)
Controller::curr()->currentPage() will get you the current page the DO is being managed on, and ->URLSegment will get the page url name, though you could use Title or MenuTitle also.
Here is an example which will set up a folder underneath assets/Headers to save images in. Running this on the HomePage (ie URL Segment 'home') will create and save objects into the folder /assets/Headers/home.
if (Controller::curr()->class == 'CMSSettingsController' || Controller::curr() instanceof Modeladmin) {
$uploadField->setFolderName('Headers');
}
else
{
$uploadField->setFolderName('Headers/' . Controller::curr()->currentPage()->URLSegment);
}
Does anyone know how I can get the just uploaded images ids and access the array of them from my controller?
My model: http://pastebin.com/aJW0vq22 (do_upload())
And here's the relevant part of my controller:
class Site extends CI_Controller {
function index() {
//enable profiler
//$this->output->enable_profiler(TRUE);
$data = array();
$this->load->model('Site_model');
if($this->input->post('upload')) {
$data['upload'] = $this->Site_model->do_upload();
//echo '<hr />' . $this->Site_model->total_uploads;
//set the users edit session for their image
$uploaded_image_id = $this->Site_model->get_last();
$values = array(
'image_id' => $uploaded_image_id,
'session_id' => $this->session->set_userdata('session_id')
);
$this->session->set_userdata('edit', $values);
//var_dump($values);
//show uploaded image
redirect($uploaded_image_id . '?links');
}
Currently I've just been using 'get_last()' to just get the last thing added to the database, but now I've added the ability to upload multiple things at once I doubt I can still, any ideas?
edit:
basically the end result i'm trying to get is
redirect('id1, id2, id3' . '?links');
You could save the file names of the just uploaded images into a session array and then query your database for the ids of those file names. This will reliably return the desierd ids.
I see that for your get_last you use a query that returns the last image added to the table. But what if you have 500 users uploading an image at the same time?
This code for extract files dir and title. The user download when clicked the file link. I need to count then number of downloads. How to do this with cakephp or php?
downloads_controller.php:
function index() {
$this->set('downloads', $this->paginate());
}
downloads/index.ctp:
<?php
$title = $download['Download']['title'];
// output filetitle
$filename = '/files/'.$download['Download']['filename'];
// output http://localhost/tet/files/un5titled0.rar
echo $this->Html->link($title, $filename,array('escape' => false));
?>
not this way i am afraid.
you either need to redirect from an action (which counts before redirecting) or use Media view to pass it through.
thats how I do it.
In the action you can then raise the count prior to sending the file.
If you want to count downloads, you should create a function that serves those downloads and create a field in your database that increments downloads each time this function is called.. For example
Call the following function from your view passing the $filename and the $id
To try out at first use, taking ID=4 as one of the downloads ID in your DB
http://www.yourdomain.com/downloads/download/4
And Then your controller would be...
Class DownloadsController extends AppController{
// All your other functions here
function download($id = null){
$this->Article->updateAll(
array('Download.count' => 'Download.count+1'),
array('Download.id' => $id)
);
$download = $this->Download->findById($id);
$this->set('filename', $download['Download']['filename']);
//$filename is an array that can then be used in your view to pass the file for download. to find out what is has you can use debug($filename) in your view
}
}
Then you need to create a special layout so the browser knows that the request file is a download and you will also need to create a view for download.ctp. Basically when you click the file link on your page, it will call this function which will use its view to serve the file.
You can access the following which will provide some insight on what needs to be done..
TUTORIAL LINK
There are lots of techniques, though in the simplest way, you can use a text file to do this.
Create a txt file and write 0 (zero) into it.
In your index function, read the content of your file.
$counter = file_read_contents('counter.txt');
Increase the read value by 1.
$counter++;
Write new value into file again.
file_put_contents('counter.txt', $counter);
So, it counts downloads and keep number in that file.
function download($id = null) {
$download = $this->Download->findById($id);
$this->set(compact('download'));
if(!empty($id)) {
// increment the number of items downloads
$this->Download->save(array(
'Download' => array(
'id' => $id,
'counts' => ($download['Download']['counts'] + 1)
)
));
}
header('Location: http://localhost/tet/files/'.$download['Download']['filename']);
exit();
}