I am trying to download images from new RETS CRMLS
$photos = $rets->SearchQuery("Media","Media",$lid, array('Limit' => 'none', 'Select' => "MediaOrder,MediaURL"));
foreach ($photos as $photo)
{
if ($photo['Success'] == true)
{
file_put_contents("../images/{$photo['Content-ID']}-{$photo['Object-ID']}.jpg", $photo['Data']);
$count++;
}
}
this is not working
If you want to download the images from the Property class, you can use this rets function
$rets->GetObject("Property", "Photo", $listingId, "*", 1);
This will return the array of images associated with the particular listingId as image url.
If you want to download as binary image files then you can use the last parameter as '0', instead of '1'. [ '1' is for getting public image Urls]
If the image is to be downloaded from the Media class then you can use the same function with Media as the class. And you should first get the listing Id from the Property class.
Your "file_put_contents" function appears to be attempting to parse the info headers within a multipart/mime response from a GetObject query. Rather, you'd want to do a straight http download of the MediaUrls. I'm not a php wizard, but you'd do something more like:
$photoUrls = $rets->SearchQuery("Media","Media",$lid, array('Limit' => 'none', 'Select' => "MediaOrder,MediaURL"));
while ($photo = $rets->FetchRow($photoUrls)) {
file_put_contents("../images/{$lid}-{$photo['MediaOrder']}.jpg", file_get_contents($photo['MediaURL']));
}
$rets->FreeResult($photoUrls);
Also, you probably want to limit your search to MediaTypes of "Image" so you don't get other binary data or documents, like virtual tour URLs or PDFs (see google group for this MLS that you also posted within).
Related
I am currently saving some images in shopify via File API:
mutation fileCreate($files: [FileCreateInput!]!) {
fileCreate(files: $files) {
files {
alt
}
userErrors {
field
message
}
}
}',
[
'files' => [
'alt' => $alt_text,
'contentType' => 'IMAGE',
'originalSource' => $from_url,
]
]
It works, but unfortunately I am not able to get the url in return. It returns null as if it's still processing.
Is there any way to do it? I am saving the image name locally, but I wouldn't consider querying the api again for each single one a valid solution (too many files, huge overhead)
Thanks in advance
I have tried above code on my project and it works but i didn't get any return url but get the following response object.
[
{
alt: 'pexels-albina-white-11780519.jpg',
createdAt: '2022-07-12T06:07:59Z',
fileErrors: [],
fileStatus: 'UPLOADED',
__typename: 'GenericFile',
preview: { image: null }
}
]
Shopify didn't provide the reading files from admin file not from any api for public apps.If any idea to read file from the api admin file then Please answer for this Query.
Using Google API v3 I try to move a file from one folder to another. I am using a wrapper class in Laravel, the file and parent IDs are correct. Developing from the documentation, I have tried code as:
public function moveFileFromTo($fileID, $toParentID) {
$fromFile = $this->service->files->get($fileID, ['fields' => '*']);
$fromParentID = $fromFile->getParents();
$blankFile = new Google_Service_Drive_DriveFile();
$this->service->files->update($fileID, $blankFile, [
"removeParents" => $fromParentID,
"addParents" => $toParentID
]);
}
However, this seems to move the file but strips out all the meta data.
I have also tried
public function moveFileFromTo($fileID, $toParentID) {
$fromFile = $this->service->files->get($fileID, ['fields' => '*']);
$fromParentID = $fromFile->getParents();
$fromFile->setParents($fromParentID);
$this->service->files->update($fileID, $fromFile);
}
However, this gives the error:
Google\Service\Exception
{ "error": { "errors": [ { "domain": "global", "reason":
"fieldNotWritable", "message": "The resource body includes fields
which are not directly writable." } ], "code": 403, "message": "The
resource body includes fields which are not directly writable." } }
I wish to simply move the file and retain all its metadata. From the documentation, it seems either a new empty file is required in update (really weird) or I must somehow strip out the fields of the object used in the second argument ($fromFile) it does not like to be written to (even though I am simply updating the files parents - which is writable).
See also https://issuetracker.google.com/issues/199921300
Problems with Answers so far:
but grateful for responses
$fromFile = $this->service->files->get($fileID, ['fields' => 'parents, id']);
returns all ~75 attributes a lot of which are not writeable.
Instead of the expected 2 as per PHPStorm debug (note the break is at the statement immediately following the GET request so irrelevant at this point
using
unset($fromFile->shared);
still leaves other writable attributes
and indeed the file is not actually shared
UPDATE TO MY CODING
public function moveFileFromTo($fileID, $toParentID) {
$fromFile = $this->service->files->get($fileID, ["fields" => "id,parents"]);
$fromFile = $this->getParsedWritableFile($fromFile);
$fromFile->setParents($toParentID);
$this->service->files->update($fileID, $fromFile, ['addParents' => $toParentID]);
}
getParsedWritableFile is trying to just set writable attributes on a new Google Drive file object:
public function getParsedWritableFile($gdrivefile) {
$gdrivefile = new \Google_Service_Drive_DriveFile();//comment or delete, just here to check auto complete function names
$parsedFile = new \Google_Service_Drive_DriveFile();
//$parsedFile=$gdrivefile;
// currently only allow these according to https://developers.google.com/drive/api/v3/reference/files#resource-representations
$parsedFile->setName($gdrivefile->getName());//name
$parsedFile->setMimeType($gdrivefile->getMimeType());//mimeType
$parsedFile->setDescription($gdrivefile->getDescription());//description
$parsedFile->setStarred($gdrivefile->getStarred());//starred
$parsedFile->setTrashed($gdrivefile->getTrashed());//trashed
$parsedFile->setParents($gdrivefile->getParents());//parents
$parsedFile->setProperties($gdrivefile->getProperties());//properties [object]
$parsedFile->setAppProperties($gdrivefile->getAppProperties());//appProperties [object]
$parsedFile->setCreatedTime($gdrivefile->getCreatedTime());//createdTime
$parsedFile->setModifiedTime($gdrivefile->getModifiedTime());//modifiedTime
$parsedFile->setWritersCanShare($gdrivefile->getWritersCanShare());//writersCanShare
$parsedFile->setViewedByMeTime($gdrivefile->getViewedByMeTime());//viewedByMeTime
$parsedFile->setFolderColorRgb($gdrivefile->getFolderColorRgb());//folderColorRgb
$parsedFile->setOriginalFilename($gdrivefile->getOriginalFilename());//originalFilename
$parsedFile->setCopyRequiresWriterPermission($gdrivefile->getCopyRequiresWriterPermission());//copyRequiresWriterPermission
/*complex permissions*/
/*
contentHints.thumbnail.image
contentHints.thumbnail.mimeType
contentHints.indexableText
*/
$contenthints=$gdrivefile->getContentHints();//could be null meaning further functions eg getThumbnail cause exception
if($contenthints){
$parsedFile->setContentHints($contenthints->getThumbnail()->getImage());
$parsedFile->setContentHints($contenthints->getThumbnail()->getMimeType());
$parsedFile->setContentHints($contenthints->getIndexableText());
}
/*no function to get indiviual attributes*/
/*
contentRestrictions[].readOnly
ccontentRestrictions[].reason
*/
$parsedFile->setContentRestrictions($gdrivefile->getContentRestrictions());
//</ end>
return $parsedFile;
}
This is proving a bit successful but this is original meta
the above code does move it, with seemingly proper meta data, created time and EXIF data is now intact
The problem is that you are using file.update which uses HTTP PATCH methodology. By using a PATCH its going to try to update all of the properties in the file object that you send.
You did a file.get and you included fileds *
$fromFile = $this->service->files->get($fileID, ['fields' => '*']);
By including 'fields' => '*' you told the API to return to you all of the properties that the file has. A file resource has a lot of properties and they are not all writeable.
By sending the file.update method all of the fields you are telling it you want to update everything including some of the properties that you are not allowed to update. To which the api responds with fieldNotWritable
The soultion would be to do the following
$fromFile = $this->service->files->get($fileID, ['fields' => 'parents, id']);
Which will cause the method to only return the two parameters that you actual need. The id and the parents parameter. (TBH you may just need the parents part, I would need to test that.)
{
"id": "1x8-vD-XiA5Spf3qp8x2wltablGF22Lpwup8VtxNY",
"parents": ["0B1bbSFgVLpoXcVDRFRF8tTkU"
]
}
You should then be allowed to update the parent and move your file.
I don't know how to do in laravel but the problem might be
I have also faced the same problem some time and after searching internet for over months found nothing and one day Referring to documentation, seen that shared
isn't a writable field.
That's it, if you are sharing the File and trying to move the file it wouldn't move. Try to un-share the File and then try to move the File it would be done.
I ended up creating a custom function to only include writeable attributes as specified in the Google Documentation:
public function getParsedWritableFile($gdrivefile) {
$gdrivefile = new \Google_Service_Drive_DriveFile();//comment or delete, just here to check auto complete function names
$parsedFile = new \Google_Service_Drive_DriveFile();
// currently only allow these according to https://developers.google.com/drive/api/v3/reference/files#resource-representations
$parsedFile->setName($gdrivefile->getName());//name
$parsedFile->setMimeType($gdrivefile->getMimeType());//mimeType
$parsedFile->setDescription($gdrivefile->getDescription());//description
$parsedFile->setStarred($gdrivefile->getStarred());//starred
$parsedFile->setTrashed($gdrivefile->getTrashed());//trashed
$parsedFile->setParents($gdrivefile->getParents());//parents
$parsedFile->setProperties($gdrivefile->getProperties());//properties [object]
$parsedFile->setAppProperties($gdrivefile->getAppProperties());//appProperties [object]
$parsedFile->setCreatedTime($gdrivefile->getCreatedTime());//createdTime
$parsedFile->setModifiedTime($gdrivefile->getModifiedTime());//modifiedTime
$parsedFile->setWritersCanShare($gdrivefile->getWritersCanShare());//writersCanShare
$parsedFile->setViewedByMeTime($gdrivefile->getViewedByMeTime());//viewedByMeTime
$parsedFile->setFolderColorRgb($gdrivefile->getFolderColorRgb());//folderColorRgb
$parsedFile->setOriginalFilename($gdrivefile->getOriginalFilename());//originalFilename
$parsedFile->setCopyRequiresWriterPermission($gdrivefile->getCopyRequiresWriterPermission());//copyRequiresWriterPermission
/*complex permissions*/
/*
contentHints.thumbnail.image
contentHints.thumbnail.mimeType
contentHints.indexableText
*/
$contenthints=$gdrivefile->getContentHints();//could be null meaning further functions eg getThumbnail cause exception
if($contenthints){
$parsedFile->setContentHints($contenthints->getThumbnail()->getImage());
$parsedFile->setContentHints($contenthints->getThumbnail()->getMimeType());
$parsedFile->setContentHints($contenthints->getIndexableText());
}
/*no function to get indiviual attributes*/
/*
contentRestrictions[].readOnly
ccontentRestrictions[].reason
*/
$parsedFile->setContentRestrictions($gdrivefile->getContentRestrictions());
return $parsedFile;
}
and called with
public function moveFileFromTo($fileID, $toParentID) {
$fromFile = $this->service->files->get($fileID, ["fields" => "id,parents"]);
$fromFile = $this->getParsedWritableFile($fromFile);
$fromFile->setParents($toParentID);
$this->service->files->update($fileID, $fromFile, ['addParents' => $toParentID]);
}
I have a page on my website that filters content from a separate page using the entityFieldQuery method. The problem is that the images I am filtering on to the new page need a different image style applied to them so that they load into smaller images. I have picture mapping set up on the site but I have only applied it via the Drupal workbench in the image fields where you can choose an image style from a dropdown.
The code below is my entityfieldquery and the conditional statement that creates the content that is being filtered from another page on to the current page. Is there any way I can revise this code to apply a different image style to the images that are being generated?
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->propertyCondition('status', NODE_PUBLISHED)
->propertyCondition('type', 'Blog')
->propertyCondition('created', array($old_date, $current_date),'BETWEEN')
->propertyOrderBy('created', 'DESC')
->fieldCondition('field_blog_categories', 'tid', $term_id)
->fieldCondition('field_blog_categories', 'tid', array('55', '26'))
->range(0, 9);
$result = $query->execute();
}
if(isset($result['node'])) {
$blog_items_nids = array_keys($result['node']);
$blog_items = entity_load('node', $blog_items_nids);
if (count($blog_items)>2){
$data = array();
foreach ($blog_items as $blg) {
$field_blog_header_image = field_view_field('node', $blg, 'field_blog_header_image', 'picture');
$temp_blog_cat = field_view_field('node', $blg, 'field_blog_categories');
$data[$temp_blog_cat['#items'][0]['tid']][] = array(
'blog' => $temp_blog_cat["#object"]->title,
'img' => isset($field_blog_header_image) ? render($field_blog_header_image) : '',
'link' => $temp_blog_cat['#object']->path['alias'],
);
}
?>
Yes, you can use function image_style_url():
https://api.drupal.org/api/drupal/modules!image!image.module/function/image_style_url/7
That function will give you path to image in any style you pass to it as long as you can acquire and pass image URI to it as parameter.
So, check the values you get from your view, find how to get image URI and call it like:
$image_path = image_style_url('style_name', $uri);
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();
}