Fixing Mismatched Image Class in Existing Posts - php

After migrating my wordpress site, I found out that the image class of some of my images in the existing posts are mismatched. However, I am not able to figure out any automated method to fix the issue.
As we all know, when an image is inserted in a post, wordpress would assign an image class and generate some markups automatically like this:
<img class=" size-full wp-image-YYYYY aligncenter" src="https://......XXXXX.jpg">
which the YYYYY in the “wp-image-” code is exactly the ID of the image.
However, in my site, probably due to some errors occurred during migration, the image ID of some of my images are off by a bit. For example, the original image ID 10000 is now 10002 in my new site. However, in the post content, the markup of the image is still wp-image-10000. This creates a problem that the image class associated is mismatched from the correct image id, and the images are such not responsive.
The obvious fix of this problem is to update the wp-image-YYYYY code to the correct image ID in the posts (i.e. changing wp-image-10000 to wp-image-10002). Or else, I could just reinsert the image into the post and wordpress would reassign a correct image class accordingly. However, given that I have hundreds of existing posts and thousands of existing images, it is not possible for me to check if the image class of each image is correct manually.
While I don't know anything about coding, I have tried to run the code in the below website, and tried to twist the code from if ( !$has_class ) to if ( $has_class ) to fit my scenario, which it does not work at all:
https://letswp.io/add-attachment-id-to-the-class-of-wordpress-images/
I would be very grateful if someone could provide an automated solution to my problem. Thank you very much.

From the code mentioned in the link, you can make more tweaks that my fix your issue, since you do not need to append but rather replace the class.
function lwp_attachment_id_class( $attr, $attachment ) {
$class_attr = isset( $attr['class'] ) ? $attr['class'] : '';
$has_class = preg_match(
'/wp\-image\-[0-9]+/',
$class_attr,
$matches
);
// Check if the image is missing the class
if ( $has_class ) {
$new_class = sprintf( ' wp-image-%d', $attachment->ID );
foreach($matches as $match)
$attr['class'] = str_replace($match, $new_class, $attr['class']);
}
return $attr;
}
add_filter(
'wp_get_attachment_image_attributes', 'lwp_attachment_id_class', 10, 2
);

Related

Displaying every image from a WordPress post

The goal is to have wordpress spit out or echo all of the images from a custom post format I've created. I'm new to PHP and I am not looking to use any 3rd party plugins, maybe a fix to the code provided below please.
All of the solutions I've came across from here (stackoverflow) or from google does not work or spits out ALL of the images I've ever uploaded from the media library, which I do not want. Most solutions provided are for "display the first image" which I know of and works, but I would like all of the images from a post.
Here's the closest code that sort of worked a couple of times but it deforms my layout, then goes back to displaying one image:
function displayPostImg() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
$first_img = $matches[0][0];
return $first_img;
}
And the call I use to paste into my custom post php:
<?php echo displayPostImg(); ?>
As stated above, existing solutions do not work. Any help with a clear explination of what I am doing wrong will be a massive help.
EDIT
#corvidism Thanks for the further explanations man. I did have a look in the dev tools and the "return implode" seems to be taking it OUT of the loop, causing the layout issue. Your solution does show the post images/attachments I am after but I can't seem to fix this unfortuntaly. There seems to be this go to solution that's meant to do the same thing. This sadly echoes every image from the media library. Combining your code with this one below has gotten me close but if I come across a solution, I'll post it here for others:
$args = array(
'post_type' => 'attachment',
'posts_per_page' => -1,
'post_status' =>'any',
'post_parent' => $post->ID );
$attachments = get_posts( $args );
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
echo apply_filters( 'the_title' , $attachment->post_title );
the_attachment_link( $attachment->ID , false );
}
}
EDIT #2: Solution
After messing around with various solutions, I found something that works. Try it out:
function grab_those_images( $post ) {
$content_post = $post->post_content;
$search_post = '~src="[^"]*"~';
preg_match_all( $search_post, $content_post, $imgs );
$no_of_pics = count($imgs[0]);
if ( $no_of_pics > 0 ) {
for ( $i=0; $i < $no_of_pics ; $i++ ) {
$string=$imgs[0][$i];
$string=trim( $string );
$length=strlen( $string );
$image_path=substr_replace( substr( $string, 5, $length ),"",-1 );
echo '<img src="';
echo $image_path;
echo '" />';
}
}
}
The function you're using contains buffer manipulation functions (ob_start() and ob_end_clean()), which and are most likely conflicting with something else in your template (probably something that's also using them, usually plugins).
Unless you're also searching for images inserted as post meta (which I assume you're not), you will find all images in a post inside the $post->post_content property. You can use preg_match_all on it to find the images.
You should pass the post content to your function as a parameter instead of accessing the global $post object. This will make things more reliable and easier to debug. (Global objects are generally frowned upon in PHP development, which is something to keep in mind if you plan to use PHP more generally than just for WordPress.)
This is how your function could look:
function getAllImagesInPost($postContent) {
preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $postContent, $matches);
// This regex function searches for <img> tags and uses a capture group
// for the image source url. It will search the whole supplied string,
// in this case post content. It returns results into the $matches variable.
$image_tags = $matches[0];
// This is an array containing all the regex matches.
$image_urls = $matches[1];
// This is an array containing all the capture group matches.
return implode('',$image_tags);
// implode() creates a string from an array of strings/numbers.
}
In your template file, the usage depends on whether or not you're in the loop. In the loop you can work with the $post object and use either $post->post_content or get_the_content() (both will get you the post content as a string):
echo getAllImagesInPost(get_the_content());
Outside of the loop you will first need to get the post (e.g. get_post($somePostID);).
Addition 1:
You must pass a variable to the function, so you can't use WordPress template functions such as the_content(). These echo directly to the page and return true or something else useless (in this case, anyway). General WP rule is that if it starts with the_ it echoes, if it starts get_the_ it returns.
Addition 2:
To display only the images from your post and no other content, you simply don't use any other content template tag in your template file. (E.g. no the_content()).
Addition 3:
I suspect your problem isn't caused by the function itself but by how/where you're calling it. But if this function does cause changes in your layout, it's 99% the regex returning broken HTML (not likely but possible, depending on your input).
The way to debug this is to inspect the page with browser dev tools and look for broken tags or other weirdness. If you see that, you need to find what exactly happens by testing the function on various input. Feed it a hard-coded string, make a test post with just text/image/anything else, until you know what's happening. If you determine that the regex is the culprit, you can try fixing it yourself or search the internet for a better one (no judgement, regex is pain).

Wordpress - Get User's image ID from Pods field

I am currently working with the Pods plugin.
I extended the user pod and I added a corporate image field.
On the administration everything is fine, I can change the image of each user.
AND :
My problem is that I can not display this image on a front office page..
If i do this : var_dump($pod->field('image_societe'));
It return false, while the field name is correct, and for plain text fields, it works.
But i can do this :
var_dump($pod->fields('image_societe'));
This will return me full of information, but I do not have access to the id of the image, it is not present in the information.
I would like to finally be able to do this:
the_attachment_link( 11923 );
Where 11923 is the image's ID.
To be dynamic according to the user, the documentation says that it must be done like this:
the_attachment_link($pod->field('image_societe.ID'));
But as pods return me false, it does not work.
Does someone have an idea ?
Thank you !
Usually you can get the image url by querying $pod->field('image_societe.guid'). E.g. :
$items = pods('your_pod', array("limit" => -1));
while($items->fetch()) {
echo $items->field('image_societe.guid');
}
If $pod->field('image_societe'); doesn't return anything, then something might be wrong with your pod query, or caching kicking in. So more code would be needed to review this.

Wordpress - Create link to separate author archive inside blog post

We're developing a blog in Wordpress and have come across some functionality that we're having some difficulty implementing.
Our client wants to be able to mention blog users in a blog post, this will then take the end user to the mentioned authors profile. Example below:
"We recently spoke to our newest team member Pete Smith" or "We recently spoke to our newest team member #PeteSmith"
If you were to click on Pete's name it would take you to website.com/authors/petesmith
I know that Wordpress has mentioning functionality built into the comments section, but is there a way to achieve this inside actual blog posts?
Apologies that I can't include any code on this question, there simply is nothing to show you guys.
You can use something like this inside your functions.php:
add_filter('the_content', 'the_content_func');
function the_content_func($content) {
$ret = preg_replace_callback ( "/(#[A-Za-z]+)/",
function ($match) {
$authorName = mb_substr($match[0], 1);
$author = get_user_by('slug', $authorName);
if ( ! empty( $author ) )
return '' . $author->display_name . '';
else
return $authorName;
},
$content);
return $ret;
}
I assume that the text after # symbol is the author's slug, so inside the filter I search for the given author and if he's found, output the corresponding author profile link with the display name. Otherwise I just output the string without # symbol & URL.
If I misunderstood your goals, feel free to modify the inner function of preg_replace_callback keeping in mid that $match[0] contains found user slug with # symbol from the post content.
Here is code for author archive page
<?php the_author(); ?>

Why does WordPress add a duplicate numeric slug upon post/page view?

This is my first post here, so I apologize in advance for any mishaps.
I've been searching for hours trying to figure this one out, but I simply can't seem to understand why this is happening.
The site I'm setting up is a child site (not in a multisite sense, but as a separate site/domain with the same branding). Some of the posts on my site will originate from the parent/main site (but will be made as new posts through copy-paste), and I want the original article ID as part of the permalinks.
E.g. http://www.example.com/hello-world/12345/, where 12345 is the article ID of the article on the parent/main site.
To accomplish this, I've added a custom field to my posts where I can add the article ID of the original article with external_article_id as Field Name. I've then tried to manipulate the permalinks with the following code:
add_filter('post_link', 'append_custom_permalink', 10, 2);
function append_custom_permalink($url, $post) {
$newurl = $url;
if ($post->post_type == 'post') {
$custom = get_post_custom_values('external_article_id', $post->ID);
if (!empty($custom))
$newurl = $url . $custom[0] . '/';
}
return $newurl;
}
Whenever I output the permalink to the posts it appears exactly as I want it, both in the editor and on the site. However, when I either click a link or enter the address manually, I get redirected automatically to http://www.example.com/hello-world/12345/12345/. It duplicates the additional numerical slug, and also happens when I replace $custom[0] with a hard-coded numeric value. This applies to all posts, and my permalink structure (in the settings) is set to /%postname%/.
I even tried setting the permalink structure to /%postname%/%ext_article_id%/ and replace %ext_article_id% with $custom[0], but with the exact same outcome. I also tried using the same code on another WordPress site, except this time with pages instead of posts, also with the exact same outcome.
Ideally I would like to use something like add_query_arg($custom[0], '', get_permalink($post->ID));, but omit the question mark that comes along with it.
Could someone please explain to me why this is happening, and how I can circumvent this? Do I need to use some other filter, or how can I approach this?
Thank you in advance!
In order to make this work you also need to make WordPress aware of the rewrite_tag and specify an additional permalink structure via add_permastruct. The following code should do the trick:
function append_custom_permalink( $post_link, $post ) {
if( $post->post_type == 'post' ) {
$custom = get_post_custom_values( 'external_article_id', $post->ID );
if( ! empty($custom) ) {
$post_link = $post_link.$custom[0].'/';
}
}
return $post_link;
}
add_filter('post_link', 'append_custom_permalink', 10, 2);
function sof_30058470_posts_rewrite() {
add_rewrite_tag('%external_article_id%', '([^/]+)', 'external_article_id=');
add_permastruct('external_article_id', '/%year%/%monthnum%/%day%/%postname%/%external_article_id%/', false);
}
add_action('init', 'sof_30058470_posts_rewrite', 10, 0);
Make sure to re-save your permalink structure at Settings->Permalinks once you added the code. You may also need to refresh/clear your browser cache.

Wordpress: retrive an array with all post galleries images inside attachment.php

I'm building a custom gallery slider for a Wordpress theme and I have an architecture problem:
While I'm in the post template (single.php) I can easily retrieve an array with all post's galleries images via this code
$galleries = get_post_galleries( $post, false);
(BTW: False parameter is to have theirs url instead of the images themselves)
but when I click on a specific gallery's image, and I'm redirected to the attachment template (attachment.php), then it's impossible to have that same array.
I tried with:
$galleries = get_post_galleries( $post->post_parent, false);
but this doesn't work properly. Indeed if I build a gallery with some pictures which were originally attached to another post (a older one, for example), the post_parent parameter will refer to that old post, instead of the one which redirected me to the attachment template.
Well, this is a problem because my slider script is loaded in the attachement.php and it can't handle the right array of pictures.
I can't trigger it while in single.php because the slideshow start after clicking on a gallery image.
(For the moment I discard the idea of making a more complex script that avoid the loading of attachment.php tempalte).
I'm looking for a workaround to retrive in PHP the right array while in attachment template.
I managed to accomplish that in this way, inside the loop, in attachment.php:
// switch to the parent post, the one holding the [gallery] shortcode(s)
$post = get_post( wp_get_post_parent_id( get_the_ID( ) ), OBJECT );
setup_postdata( $post );
// get the galleries
$galleries = get_post_galleries( $post, false );
// VERY IMPORTANT: restore the original post (the attachment)
wp_reset_postdata( );
Personal note: I think the bug resides in the chain of calls:
get_post_galleries, do_shortcode_tag, gallery_shortcode
not transmitting the post ID parameter correctly so that at a certain point, the attachment ID is used instead of the one supplied by the user in the first get_post_galleries call.

Categories