Wordpress - Copy media library or categorize? - wordpress

I have a plugin in mind for Wordpress (that I'm aiming to create) that bascially are going to use the same features of the media - library (uploading / viewing / setting descriptions etc on images).
Is there a way of "copying" the media library and then use it/modifiy it as you wish?
Background:
I want to categories these photos for different customers (that the owner of the site uploads). I believe the built-in media library should be used for site-specific photos (like logos, product photos etc). I don't want mix built-in "media-library" with specific customers photos.
Guidelines
Maybe there's a better approach. (Is it better to create categories in the media-categories for each customer?) If there is, please tell me. I'm looking for guidelines - not a solution.

Solution 1:
First query posts, and then for each one of them use something like this code:
$images = get_children( array(
'post_parent' => get_the_ID(),
'post_type' => 'attachment',
'post_mime_type' => 'image',
'numberposts' => -1
) );
foreach ( (array) $images as $image ) {
print wp_get_attachment_url( $image->ID );
}
I don't like this solution because it will generate many SQL queries.
Solution 2:
Write your own SQL query which will select all images at once. It should look something like this:
// change this to your custom post type, attachment in your case.
$post_type = 'attachment';
global $wpdb;
$where = get_posts_by_author_sql( $post_type );
$query = "SELECT * FROM $wpdb->posts p where p.post_type = 'attachment' AND (p.post_mime_type LIKE 'image/%') AND (p.post_status = 'inherit') AND p.post_parent IN (SELECT $wpdb->posts.ID FROM $wpdb->posts {$where} ) ORDER BY p.post_date DESC";
$results = $wpdb->get_results( $query );
if ( $results ) {
foreach ( (array) $results as $image ) {
print wp_get_attachment_url( $image->ID );
}
}
The way I would build that plugin, is creating a custom post type, similar to the media upload type, and then modify it as you wish (adding a category for example).
I like the idea of the plugin, so let me you know then you finish, Good luck.
Edit: If you are actually want to copy all the image files to another directory you could do something like this using :
$source = wp_upload_dir(); // get WordPress upload directory
$dest= "wp-content/My-new-Directory"; // where you would like to copy
mkdir($dest, 0755);
foreach (
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST) as $item
) {
if ($item->isDir()) {
mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
} else {
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
}

Theoretically, you could copy the whole media gallery.
Media gallery (in admin panel) is basically a post type archive. Post type in question being attachment.
By defining your custom post type, you could add all the action, display and functionality hooks needed to replicate the attachment functionality.
If you want to categorize your attachment either by using a hierarchical or non hiearchical taxonomy you could register a custom taxonomy for the attachment post type.
Both ways are semi-complex, and are perhaps unneeded. Would you be so kind to describe your usage scenario in more detail, so I could help you better.

Related

Wordpress get_posts() shows only partially correct data of custom post inside user profile

I have a wordpress-based website where I'm trying to move some custom functionality that used to be just plain mysql table and some code to insert/update/show stuff from it. I'm trying to merge it in WP as custom posts so I can use filters, tags, pagination and such.
It supposed to show a few custom items inside the user profile (Ultimate Member). Like, user info, then 10 of user's top items of this kind, then on next tab 10 items of some other kind, etc.
But seems like things aren't as simple in WP, and you can't just toss things on top of each other and expect it to not overlap. >_> So when I'm trying to add a block with custom post type data, it returns only some of the data mixed with profile data mixed with nothingness.
Yeah, I get it, there's probably a profile loop and some data already inside variables, as far as I could understand from manuals. What I can't understand is how to fix it. Here's how it looks:
$args = array(
'author' => $uid,
'numberposts' => 10,
'post_type' => 'ff',
);
$ff = get_posts($args);
if($ff){
foreach($ff as $f){
setup_postdata($f);
the_content(); //shows what's needed, as well as ID, the_time() and some more
the_title(); //shows author's name instead of post title
the_tags(); //shows nothing, as well as excerpt, etc
get_the_excerpt(); //still nothing
$f->post_excerpt; //but this shows the excerpt, as well as print_r($f)
}
wp_reset_postdata();
}
Maybe someone could give a hint what am I missing? Thanks in advance!
Try using the post ID to get your data and echo it. A little more code but may work better.
// Set the global post up here
global $post;
$args = array(
'author' => $uid,
'numberposts' => 10,
'post_type' => 'ff',
);
$ff = get_posts($args);
if($ff){
foreach($ff as $f){
setup_postdata($f);
$id = $f->ID; // get post ID
$content = get_the_content($id); // get the content to echo later
$tags = get_the_tags($id); // use to get tags, these are not part of the get_posts return object
echo $content; // show the content
echo $f->post_title; // show the returned post title. can use get_the_title($id) and echo it if this does not work
// Display the tags after getting them above
foreach ($tags as $tag) {
echo $tag->name . ', ';
}
// You can get the excerpt this way too but you said your other worked okay
$excerpt = get_the_excerpt($id);
echo $excerpt;
}
wp_reset_postdata();
}
(Original) To elaborate. This sets up the global post object. Which is generally a requirement for your functions to work in the loop. Not always the case as I've found over the years, but a good practice if you're not using the post ID in the loop to get your data.

WORDPRESS User specific access via ID to specific contact forms CFDB7

I'm trying to implement in the code a way to show specific contact forms data to a particular user via ID but I'm having difficulty finding which part of the code to add it to.
$user_ID = get_current_user_id();
if ( $user_ID == ('2') ) {
I'm currently inside the admin-mainpage.php within the plugin files.
It's not as simple as I thought as it doesn't store the form names via db.
Any help would be appreciated.
Forms-list
It looks like Contact Forms 7 is your plugin for the forms portion while CFDB7 is an accompanying plugin that writes the form submissions to the WP database.
Get the Form ID
There are a couple ways to get the form ID. It looks like the easiest path is to look at the shortcode that the CF7 creates. You can see it in their documentation here. The code is something like [contact-form-7 id="4" title="Foo"] with id being the form ID (4 in this case).
Show the Right Form to the Right Person
Assuming you know the user ids and the related form ids you want to show them, you could write a very simple shortcode plugin to display the right forms for the right people. It'd be something like this untested code below.
//[user-form-display]
function user_form_display( $atts ){
$user_id = get_current_user_id();
if ($user_id == 2){
echo do_shortcode('[contact-form-7 id="4" title="Foo"]');
} else if ($user_id == 4){
echo do_shortcode('[contact-form-7 id="88" title="Bar"]');
}
}
add_shortcode( 'user-form-display', 'user_form_display' );
You could then put the shortcode in the regular post field and not edit either the CF7 plugin nor mess with the theme files.
You could also make the shortcode fancier and tie user ids to form ids directly in the shortcode arguments. That would take a bit more effort but is probably worth it.
Getting the Form Data
You could modify the $args to include form ids based on an association with a user id or multiple user ids. The form ids should be a field in that table. That's the example indicated below.
Alternately you could modify how the information is returned based on the same relationships by setting up the if/then statements in the $data_value lines. This is easier probably but messier in the long run.
function specfic_table_data()
{
global $wpdb;
$user_id = get_current_user_id();
if($user_id == 1){
$form_ids = array(4,6);//only returns forms with id 4 and 6 when it's user w id 1
}
$cfdb = apply_filters( 'cfdb7_database', $wpdb );
$data = array();
$table_name = $cfdb->prefix.'db7_forms';
$args = array(
'post_type'=> 'wpcf7_contact_form',
'order' => 'ASC',
'posts_per_page' => 10,
'post__in' => $form_ids,
);
$the_query = new WP_Query( $args );
while ( $the_query->have_posts() ) : $the_query->the_post();
$form_post_id = get_the_id();
$totalItems = $cfdb->get_var("SELECT COUNT(*) FROM $table_name WHERE form_post_id = $form_post_id");
$title = get_the_title();
$link = "<a class='row-title' href=admin.php?page=cfdb7-list.php&fid=$form_post_id>%s</a>";
$data_value['name'] = sprintf( $link, $title );
$data_value['count'] = sprintf( $link, $totalItems );
$data[] = $data_value;
endwhile;
var_dump($data);
}

Custom Fields/Values displaying out of order

I'm using the Types Wordpress plugin to enable custom fields. The plugin allows you to rearrange the order of the images in the admin page editor. Here's my code in my single.php to display multiple images in the custom field and have a link to itself to also use Fancybox:
<?php
$mykey_values_img = get_post_custom_values('wpcf-image');
if ($mykey_values_img != null) {
foreach ( $mykey_values_img as $key => $value ) {
?>
<img src="<?php echo $value; ?>" />
<?php
} //foreach
} //if
?>
Problem:
Right now this code works perfectly on my local copy running on MAMP. However, when I put it online hosted on iPage, the images are out of order. I don't know what's causing this discrepancy. When I use the shortcode from Types to display the images instead of the php above they are in order, but I don't have the option of using Fancybox. I was also wondering if there is a better way to display an image from Wordpress that will insert the alt tag for the image.
I just encountered this problem too, and your first answer led me to a tighter solution.
I also used types_render_field(), but if you include a 'raw' parameter, you can avoid the string manipulation.
$images_raw = types_render_field('image', array('raw'=>'true','separator'=>';'));
$images = explode(';', $images_raw);
foreach ($images as $link) {
echo '' . $link . '">"';
}
Then, if you're nasty, you can get the ID of the attachment from its SRC. Using that ID, you can get all the info you need about that attachment, like a caption, or whatnot.
I figured out a work around to get it working. Its not ideal but it works.
The Types plugin came with its own php function to display the custom field called types_render_field. It displayed my images in order. To get fancybox working I had to do sort of a hack on the string. Here's the code:
$images = ( types_render_field( "image", array( 'size' => 'full', 'alt' => get_the_title(), 'title' => get_the_title() ) ) );
$imgArray = explode(">", $images);
foreach ( $imgArray as $value ) {
$pos1 = strpos($value, 'src="', 0)+5;
$pos2 = strpos($value, '" ', $pos1);
$link = substr($value, $pos1, $pos2 - $pos1);
echo ''.$value.">";
}

Wordpress get_post_meta does not return when using variable

I'm trying to get a plugin to read the post metadata of an attachment, and use it to update the content of the post it is attached to. I'm using the following in my themes function.php:
add_action( 'afip_created_post', 'get_desc', 10, 2 );
function get_desc( $post_id, $attachment_id ) {
$postmeta = get_post_meta ($attachment_id, '_wp_attachment_metadata', true);
$meta = $postmeta['image_meta'];
$mmwwdesc = $meta['description'];
wp_update_post( array( 'ID' => $post_id, 'post_content' => $mmwwdesc ) );
}
and then using this line in the plugin to hook the function
do_action( 'afip_created_post', $new_post_id, $post_id );
If I fill in the varibale "$attachment_id" with a number from another post i.e "15," I get the description inserted into the published post. If I change the output to wp_update_post( array( 'ID' => $post_id, 'post_content' => $attachment_id ) ); I get the id number echoed in the body of the published post. I'm don't understand why the original code does not work, since $attachment_id seems to be properly defined. I'm just a beginner with php. Is there something obvious that I'm doing wrong? Is the variable $attachment_id being echoed when it should be returned, or something technical like that?
Background: I'm using two wordpress plugins, one called Media Metadata Workflow Wizard (MMWW), and the other called Automatic Featured Image Post (AFIP). MMWW extracts the image metadata and writes it to the database as post meta. AFIP creates new posts using uploaded media, and attaches each image to a post, setting it as the post thumbnail. I don't think its an issue of the metadata not being ready when the function is called, because AFIP creates the post after the media has been uploaded, and had its meta written to the database. I'm also hooking my function as an update to the post, after it has already been created.
I've done extensive searching, and trial and error with no success. Can anybody help me out?
Thanks!
I think your issue here is that the get_post_meta function is returning blank in functions.php. The way to deal with this issue is to use a MYSQL query with wordpress to return the data in your psot meta.
First you need the global $wpdb object so at the start of your function write: global $wpdb;
Then you need to do the get_post_meta action using mysql and the $wpdb object:
$postmeta = $wpdb->get_var("SELECT meta_value FROM $wpdb->postmeta" WHERE meta_key = '_wp_attachment_metadata' AND post_id = $attachment_id");
Replace your get_post_meta line with the wpdb query and you should be fine.

Add & Separate Custom Post Types in Taxonomy.php / Taxonomy Page

I have a taxonomy.php file to display taxonomy terms. I added a filter in functions.php to include post types for the taxonomy page query. This filter:
add_filter( 'pre_get_posts' , 'ucc_include_custom_post_types' );
function ucc_include_custom_post_types( $query ) {
global $wp_query;
/* Don't break admin or preview pages. */
if ( !is_preview() && !is_admin() && !is_page() && !is_single() ) {
$args = array(
'public' => true ,
'_builtin' => false
);
$output = 'names';
$operator = 'and';
$post_types = get_post_types( $args , $output , $operator );
$post_types = array_merge( $post_types , array( 'post' ) );
if ($query->is_feed) {
// Do feed processing here.
} else {
$my_post_type = get_query_var( 'post_type' );
if ( empty( $my_post_type ) )
$query->set( 'post_type' , $post_types );
}
}
return $query;
}
Returns any and all post types you want. But I am trying to find a way to separate them. I tried to use a normal loop but I don't know how to fetch the current taxonomy tag from the page.
I have 2 questions which are all related but seeing what is the best way to go about this. Pretend I have 3 posts types ('post' 'post2' 'post3')
Is there a loop that can be used in taxonomy.php that will display a particular post type? So it can be possible to have one loop for each post type? So when I click on a taxonomy term, the taxonomy.php will return:
--Taxonomy Page --
Loop for custom type post 1 (show post with current taxonomy tag in this specific post type)
Loop for custom type post 2
Loop for custom type post 3
If there are multiple loops, will this affect the pagination? Or will pagination only work for posts?
I have used many single loops in the taxonomy.php page to no avail. I feel I have to echo the current taxonomy term variable to a new variable:
$term = $wp_taxonomies??
Any way for multiple loops in the taxonomy.php pages?
Probably the easiest way to do this is ignore the existing $wp_query and create three new queries in your taxonomy template. So don't start "The Loop" in your template, just create a new query and loop with that one. Repeat this for the other post types. This also means you don't need to hook into the pre_get_posts filter, you create a custom query just for you.
You will have to think about the UI for the next pages, indeed. This depends on the reason you want the post types separated. If it is enough that you see the three together on the first page, you could go with three separate "next page" links, so one per post type.

Resources