Wrong URL when using wp_insert_attachment - wordpress

I created a plugin as 3rd party to acomodate system with wordpress website on main site. So the scenario is:
when user hit submit on the system it will also added to wordpress website, it's working perfect, no problem at all. but when i try to set the featured image through wp_insert_attachment it keep me give a URL like
http://xxxxx.com/wp-content/uploads/http://xxxxx.com/system/media/.../xx.jpg
what i want to be is only http://xxxxx.com/system/media/.../xx.jpg saved as featured image, is it possible to do so?
here is my current script
if($pt == "pictures"){
$filename_url = $_GET["dml_file"];
$mime = wp_check_filetype($filename_url, null);
$data = array(
'post_mime_type' => $mime['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($_GET["dml_file"])),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment($data, $filename_url, $pid);
update_post_meta($pid, $custom_field, $attachment_id);
}else{
update_post_meta($pid, $custom_field, $_GET["dml_file"]);
}
I have tried to use file_get_contents and file_put_contents to create image in WP installation, but I don't want that way.
The system is submitting this:
http://user:pass!#localhost/wp-content/plugins/dml3rdparty/dmlsubmit.php?dml_sa‌ve=save&dml_file=http://xxx.xxx.xxx.xxx/dml/assets/media/Accreditation/download.d‌15bdf4e9e.jpg&dml_type=Print Quality Photos&dml_description=test|download.jpg&dml_status=publish

From wp_insert_attachment documentation (my emphasis in bold):
$filename
(string) (optional) Location of the file on the server. Use absolute path and not the URI of the file. The file MUST be on the uploads directory. See wp_upload_dir()
Default: false
Much probably, you can solve this with media_handle_sideload().

This function gets the file content using cURL:
function my_file_get_contents($url){
$options = array(
CURLOPT_AUTOREFERER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10
);
$ch = curl_init($url);
curl_setopt_array($ch,$options);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
This function uses the above to get the image, saves it to the uploads folder, and sets it as a featured image for a post:
function my_featured_image($image_url,$post_id){
$upload_dir = wp_upload_dir();
$image_data = my_file_get_contents($image_url);
$filename = strtok($image_url, '?');
$filename = basename($filename);
if(wp_mkdir_p($upload_dir["path"])){
$file = $upload_dir["path"]."/".$filename;
}else{
$file = $upload_dir["basedir"]."/".$filename;
}
file_put_contents($file, $image_data);
$wp_filetype = wp_check_filetype($filename,null);
$post_author = get_post_field("post_author",$post_id);
$attachment = array(
"post_author" => $post_author,
"post_mime_type" => $wp_filetype["type"],
"post_title" => sanitize_file_name($filename),
"post_content" => "",
"post_status" => "inherit"
);
$attach_id = wp_insert_attachment($attachment,$file,$post_id);
require_once(ABSPATH."wp-admin/includes/image.php");
$attach_data = wp_generate_attachment_metadata($attach_id,$file);
$res1 = wp_update_attachment_metadata($attach_id,$attach_data);
$res2 = set_post_thumbnail($post_id, $attach_id);
}
Call with:
my_featured_image($image_url,$post_id);

Related

upload image on page using wordpress rest api

I want upload image using api on my page so any tell me how i do it?
Now i work with this api
http://localhost/test_project/wp-json/wp/v2/media
but it's doesn't help me for upload image on page or post.
I use wordpress json api plugin.
You can do using following code. Here I have use wp_handle_upload.
$param = array('search' => 'XXXXXXXX');
$imagetype = array(
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'tif' => 'image/tiff',
'tiff' => 'image/tiff'
);
$override = array(
'mimes' => $imagetype,
'test_form' => false
);
$upload_file = wp_handle_upload( $_FILES['YOUR_UPLOAD_FILE_NAME'], $override );
remove_filter( 'upload_dir', array($this, 'change_upload_dir') );
if ( isset( $upload['error'] ) ){
// DO ACTION ACCORDINGLY
} else {
// File is uploaded successfully.
$uploaded_file_url = $upload_file['url'];
$uploaded_file_name = basename($upload_file['url']);
}

drupal preview not working - previewing node edit displays previous saved node instead

Preview only works for new nodes before saving, but after I saved the node, edit and click preview:
Preview trimmed & Preview full version both show the last saved state instead.
Any advise how I can check what might prevent it or whether it's set up correctly?
FYI /modules/node/node.pages.inc:
function theme_node_preview($variables) {
$node = $variables['node'];
$output = '<div class="preview">';
$preview_trimmed_version = FALSE;
$elements = node_view(clone $node, 'teaser');
$trimmed = drupal_render($elements);
$elements = node_view($node, 'full');
$full = drupal_render($elements);
...
$enter code hereform['actions']['preview'] = array(
'#access' => variable_get('node_preview_' . $node->type, DRUPAL_OPTIONAL) != DRUPAL_DISABLED,
'#type' => 'submit',
'#value' => t('Preview'),
'#weight' => 10,
'#submit' => array('node_form_build_preview'),

How can I put these codes into function.php in WordPress?

I want to upload file with Chinese character to a WordPress website. However, the name of the file is gibberish. I have searched the question and found some solutions. One is to modify the //wp-admin/includes/file.php
function wp_handle_upload( &$file, $overrides = false, $time = null ) {
//….
// Move the file to the uploads dir
//$new_file = $uploads['path'] . “/$filename”;
$new_file = $uploads['path'] . “/” . iconv(“UTF-8″,”GB2312″,$filename);
//…
//return apply_filters( ‘wp_handle_upload’, array( ‘file’ => $new_file, ‘url’ => $url, ‘type’ => $type ), ‘upload’ );
return apply_filters( ‘wp_handle_upload’, array( ‘file’ => $uploads['path'] . “/$filename”, ‘url’ => $url, ‘type’ => $type ) , ‘upload’);
}
As I know, it changes the encoding of the filename. But I want to put it in the function.php in the theme folder. What can I do ?

Uploading and saving a file programmatically to Drupal nodes

I am trying to create a node based on a custom form submission. Everything works great except for the images that get uploaded.
I can capture them fine and set them in the form object cache. When I pass the data into the function to create the node, I get this error:
"The specified file could not be copied, because no file by that name exists. Please check that you supplied the correct filename."
I also receive the error multiple times, despite only submitting one or two images at a time.
Here is the code I am using. $uploads is passed in and is an array of file objects returned from file_save_upload() in a previous step:
if (isset($uploads)) {
foreach ($uploads as $upload) {
if (isset($upload)) {
$file = new stdClass;
$file->uid = 1;
$file->uri = $upload->filepath;
$file->filemime = file_get_mimetype($upload->uri);
$file->status = 1;
$file = file_copy($file, 'public://images');
$node->field_image[$node->language][] = (array) $file;
}
}
}
node_save($node);
I also tried this:
if (isset($uploads)) {
foreach ($uploads as $upload) {
$upload->status = 1;
file_save($upload);
$node->field_image[$node->language][] = (array) $upload;
}
}
}
node_save($node);
The second causes a duplicate key error in MySQL on the URI field. Both of these examples I saw in tutorials, but neither are working?
For Drupal 7, I played around with this quite a bit and found the best way (and only way that I've got working) was to use Entity metadata wrappers
I used a managed file form element like so:
// Add file upload widget
// Use the #managed_file FAPI element to upload a document.
$form['response_document'] = array(
'#title' => t('Attach a response document'),
'#type' => 'managed_file',
'#description' => t('Please use the Choose file button to attach a response document<br><strong>Allowed extensions: pdf doc docx</strong>.'),
'#upload_validators' => array('file_validate_extensions' => array('pdf doc docx')),
'#upload_location' => 'public://my_destination/response_documents/',
);
I also pass along the $node object in my form as a value
$form['node'] = array('#type' => 'value', '#value' => $node);
Then in my submission handler I simply do the following:
$values = $form_state['values'];
$node = $values['node'];
// Load the file and save it as a permanent file, attach it to our $node.
$file = file_load($values['response_document']);
if ($file) {
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
// Attach the file to the node.
$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->field_response_files[] = array(
'fid' => $file->fid,
'display' => TRUE,
'description' => $file->filename,
);
node_save($node);
}
i used your code to upload a file in the file field to a content("document" in my case) and it's worked. Just had to add a value for field_document_file 'display' in the code.
here is the exact script i used:
<?php
// Bootstrap Drupal
define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
require_once './includes/file.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// Construct the new node object.
$path = 'Documents/document1.doc';
$filetitle = 'test';
$filename = 'document1.doc';
$node = new StdClass();
$file_temp = file_get_contents($path);
//Saves a file to the specified destination and creates a database entry.
$file_temp = file_save_data($file_temp, 'public://' . $filename, FILE_EXISTS_RENAME);
$node->title = $filetitle;
$node->body[LANGUAGE_NONE][0]['value'] = "The body of test upload document.\n\nAdditional Information";
$node->uid = 1;
$node->status = 1;
$node->type = 'document';
$node->language = 'und';
$node->field_document_files = array(
'und' => array(
0 => array(
'fid' => $file_temp->fid,
'filename' => $file_temp->filename,
'filemime' => $file_temp->filemime,
'uid' => 1,
'uri' => $file_temp->uri,
'status' => 1,
'display' => 1
)
)
);
$node->field_taxonomy = array('und' => array(
0 => array(
'tid' => 76
)
));
node_save($node);
?>
Kevin, that's what I found in the Drupal doc's under http://drupal.org/node/201594 below in the comments. But I am not sure at all. I try the same, so please let me know what you found out.
$path = './sites/default/files/test.jpg';
$filetitle = 'test';
$filename = 'test.jpg';
$node = new StdClass();
$file_temp = file_get_contents($path);
$file_temp = file_save_data($file_temp, 'public://' . $filename, FILE_EXISTS_RENAME);
$node->title = $filetitle;
$node->uid = 1;
$node->status = 1;
$node->type = '[content_type]';
$node->language = 'und';
$node->field_images = array(
'und' => array(
0 => array(
'fid' => $file_temp->fid,
'filename' => $file_temp->filename,
'filemime' => $file_temp->filemime,
'uid' => 1,
'uri' => $file_temp->uri,
'status' => 1
)
)
);
$node->field_taxonomy = array('und' => array(
0 => array(
'tid' => 76
)
));
node_save($node);

Attaching image files to nodes programmatically in Drupal 7

Is it possible to add an image to a node programmatically?
Here is an example code using which you can use with node_save
$filepath = drupal_realpath('misc/druplicon.png');
// Create managed File object and associate with Image field.
$file = (object) array(
'uid' => 1,
'uri' => $filepath,
'filemime' => file_get_mimetype($filepath),
'status' => 1,
);
// We save the file to the root of the files directory.
$file = file_copy($file, 'public://');
$node->field_image[LANGUAGE_NONE][0] = (array)$file;
`
An easier way:
$filename = 'image.txt';
$image = file_get_contents('http://www.ibiblio.org/wm/paint/auth/gogh/gogh.white-house.jpg');
$file = file_save_data($image, 'public://' . $filename, FILE_EXISTS_RENAME);
$node->field_image = array(LANGUAGE_NONE => array('0' => (array)$file));
This is what worked for me:
$file_temp = file_get_contents('public://someimage.jpg');
// Saves a file to the specified destination and creates a database entry.
$file_temp = file_save_data($file_temp, 'public://' . 'someimage.jpg', FILE_EXISTS_RENAME);
$node->field_page_image = array(
'und' => array(
0 => array(
'fid' => $file_temp->fid,
'filename' => $file_temp->filename,
'filemime' => $file_temp->filemime,
'uid' => 1,
'uri' => $file_temp->uri,
'status' => 1,
'display' => 1
)
)
);
Here's one extra bit that tripped me up for a while: this will attach the image to the node, and if you're adding the image then you're okay. However, if you're updating an image, and you care about displaying it on a page, then one extra step is needed before calling node_save():
image_path_flush($node->field_image['und'][0]['uri']);
This will regenerate all of that image's styles.
$node->field_image[LANGUAGE_NONE][0] = (array)$file;
I tried this with a multilingual site. It failed fairly... but horribly.
I had to specify the language in question. Simply put, this worked instead:
$node->field_image['en'][0] = (array)$file;
Without it, the attached file was viewable in the 'view' screen but not in the 'edit' screen.
Yes, make it part of the $node object when you save it. Save it using node_save().
This works for me:
define('DRUPAL_ROOT', $_SERVER['DOCUMENT_ROOT']);
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$node = node_load(99);
$filename = 'image.txt';
chdir(DRUPAL_ROOT);
$image = file_get_contents('http://www.ibiblio.org/wm/paint/auth/gogh/gogh.white-house.jpg');
$file = file_save_data($image, 'public://' . $filename, FILE_EXISTS_RENAME);
$node->field_imagen_producto = array(LANGUAGE_NONE => array('0' => (array)$file));
node_save($node);
Just going to paste my solution here as well, I needed to create a new node, and upload an image programmatically.
$filepath = variable_get('file_public_path') . '/xmas_banner.jpg';
$file_temp = file_get_contents($filepath);
$file_temp = file_save_data($file_temp, file_default_scheme() . '://' .'xmas_banner_nl.jpg', FILE_EXISTS_RENAME);
$node = new stdClass();
$node->type = 'carousel'; // custom content type
$node->title = 'XMAS NL';
$node->field_banner_image[LANGUAGE_NONE][0] = (array) $file_temp;
$node->uid = 1;
$node->status = 0;
$node->active = 0;
$node->promote = 0;
node_save($node);

Resources