Firstly, sorry if this has been dealt with before, I've spent quite a while searching posts to no avail.
I have a Wordpress blog and a Concrete5 site. I am trying to write out the three most recent Wordpress blog posts on the Concrete5 site. I cannot use RSS as both sites are on the same server and internal RSS is disabled (is there a way to get around this?).
I have written a block for concrete and have put this code in view.php ...
<?php
define('WP_USE_THEMES', false);
require('path-to-wordpress/wp-blog-header.php');
?>
... This results in "Error establishing a database connection".
If I run this outside of Concrete it works fine (I'm currently using this code elsewhere on the server, no probe).
I've also tried with wp_load.php, same result.
Sorry if this is really obvious, I've been working on it for a while now :(
Thanks in advance.
Sadly this simple approach to loading Wordpress does not work in concrete for whatever reason, some kind of conflicting definition or something. If you are trying to load Wordpress posts on a Concrete5 site on the same server you might well find that using RSS will not work for you as sometimes servers block internal requests to prevent looping.
This is the position I found myself in so I decided to access the Wordpress table myself building on code posted by 'jcrens8392' on the Concrete5 forums , so here it is for anyone who finds them self in the same position.
// posts and stuff
$category = 3
$items = 4
// wordpress db stuff
$dbUser = 'user';
$dbPass = 'password';
$dbHost = 'localhost';
$dbName = 'name';
// connect to wordpress database
$conn = mysql_connect($dbHost, $dbUser, $dbPass);
// handle connection errors
if(!$conn) {
$aDebug['Unable to connect to DB'] = mysql_error();
} elseif(!mysql_select_db($dbName, $conn)) {
$aDebug['Unable to select database'] = mysql_error();
}
// make SQL query
else {
$sQuery = "SELECT wp_posts.post_date, wp_posts.post_content , wp_posts.guid , wp_posts.post_title, wp_posts.post_excerpt, wp_posts.post_name FROM wp_posts , wp_term_relationships WHERE post_type = 'post' AND post_status = 'publish' AND wp_posts.ID = wp_term_relationships.object_id AND wp_term_relationships.term_taxonomy_id = ".$category." ORDER BY post_date DESC LIMIT ".$items;
$rPosts = mysql_query($sQuery, $conn);
}
// plonk posts into a convinient array
$posts = array();
while($row = mysql_fetch_array($rPosts)){
$excerpt = $controller->getExcerpt( utf8_encode( strip_tags( $row['post_content'] ) ) , 0 , 200 ) .' Read More →';
$date = $controller->simplifyDate( $row['post_date'] );
$temp = array ( 'post_title' => $row['post_title'] , 'post_excerpt' => $excerpt , 'post_date' => $date , 'post_link' => $row['guid'] );
array_push( $posts , $temp );
}
I put these functions in controller.php (excerpt function from phpsnaps)...
function getExcerpt($str, $startPos=0, $maxLength=100) {
if(strlen($str) > $maxLength) {
$excerpt = substr($str, $startPos, $maxLength-3);
$lastSpace = strrpos($excerpt, ' ');
$excerpt = substr($excerpt, 0, $lastSpace);
$excerpt .= '...';
} else {
$excerpt = $str;
}
return $excerpt;
}
function simplifyDate($str) {
$months = array("January","February","March","April","May","June","July","August","September","October","November","December");
$strs = split ( ' ' , $str );
$date = split ( '-' , $strs[0] );
$month = $months[ $date[1] - 1 ];
$day = $date[2];
$year = $date[0];
return $day . ' ' . $month . ' ' . $year;
}
This really isn't the ideal solution, it does, however, have the distinct advantage of working. Hope this helps someone.
Related
When I insert new images from Unsplash.com the image size "full" returns a scaled image with "-scaled.jpg" at the end of the name file and is always limited to 2560 pixels. So how can I retrieve the real "full" size of the image?
You have first to disable this "feature" introduced in WordPress 5.3 by adding this line of code in your functions.php:
add_filter( 'big_image_size_threshold', '__return_false' );
This will disable the scaling down for any FUTURE uploads. But for existing images you have to update the image sizes.
Unfortunately the WordPress team proves once more its incompetence - they dind't provide any functions to update the postmeta for existing attachments and obviously they don't give a single f... about this issue as you can see here, where dozens of people expressed there anger about this so called feature.
I have created today a site with several thousands of dummy posts with featured images from Unsplash.com and where I needed the full size of the images. It took a couple of hours to run the script which downloaded and created the blog posts and the attachments posts. So it wasn't an option to me to delete all the posts and run the dummy script again once I've found out about the new "feature" and how to disable it.
So I wrote another script which took me still a bunch of time...
You need to put the following code in a php file and run/call it from either the browser or terminal. Don't forget to replace the path to the wp-load.php file. On my local machine it took just a couple of seconds for several thousand attachment posts.
<?php
require_once( "/absolute/or/relative/path/to/wordpress/wp-load.php" );
ini_set( 'max_execution_time', 3600 );
set_time_limit( 3600 );
$pdo = new PDO( "mysql:dbname=" . DB_NAME . ";host=" . DB_HOST, DB_USER, DB_PASSWORD );
/**
* replace _wp_attached_file meta_key
**/
global $wpdb;
$wp_postmeta = $wpdb->prefix . "postmeta";
try {
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );//Error Handling
$sql = "UPDATE $wp_postmeta SET meta_value = REPLACE(meta_value,'-scaled.jpg','.jpg') WHERE meta_key='_wp_attached_file' AND meta_value LIKE '%-scaled.jpg%'";
$result = $pdo->exec( $sql );
print_r( $result );
} catch ( PDOException $e ) {
print_r( $e->getMessage() );
}
/**
* replace _wp_attachment_metadata meta_key
**/
$image_metas = [];
try {
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );//Error Handling
$sql = "SELECT * FROM $wp_postmeta WHERE meta_value LIKE '%-scaled.jpg%' AND meta_key='_wp_attachment_metadata'";
$statement = $pdo->query( $sql );
$image_metas = $statement->fetchAll();
foreach ( $image_metas as $meta ) {
$meta_value = unserialize( $meta["meta_value"] );
$file = $meta_value["file"];
$meta_value["file"] = str_replace( "-scaled.jpg", ".jpg", $file );
update_post_meta( $meta["post_id"], $meta["meta_key"], $meta_value );
$result = get_post_meta( $meta["post_id"], $meta["meta_key"] );
print_r( $result );
}
} catch ( PDOException $e ) {
print_r( $e->getMessage() );
}
I need some php request for get list of all sites in wp-network. Is it possible?
As of WP 4.6 there is a new function to query sites, get_sites($query_arg) which is a parallel to the familiar get_posts($query_args) used for retrieving posts,
$blogs = get_sites();
foreach( $blogs as $b ){
$b->blog_id
//Do stuff
}
NOTE: As pointed out by #guido-walter-pettinari in the comment below, get_sites() is a front for instantiating a new WP_Sites_query object which sets some default query parameters, including the 'number' of sites to return to 100!
You can use
<?php wp_get_sites( $args ); ?>
Examples ,for bellow v 3.0
<?php
$blog_list = get_blog_list( 0, 'all' );
foreach ($blog_list AS $blog) {
echo 'Blog '.$blog['blog_id'].': '.$blog['domain'].$blog['path'].'<br />';
}
?>
Using WordPress functions is a bit problematic, when you aim compatibility with all multisite versions:
get_blog_list is not only deprecated, but it does not return sites not flagged as public either. Strangely, the oficial documentation hasn't warned us about that (you discover only when your code fails).
get_sites, in contrast, works only in WP 4.6.0 or higher
I prefer using the following code, which is compatible with all WordPress versions (as of 3.0.0, of course), and returns all sites of the installation (even the archived ones, deactivated ones, etc.):
global $wpdb;
$blogs = $wpdb->get_results( "SELECT blog_id, domain, path FROM $wpdb->blogs ORDER BY blog_id" );
If you want to filter your results, not showing the archived ones, deactivated ones and spam sites, you have to indicate that in the query as follows:
global $wpdb;
$blogs = $wpdb->get_results( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE archived = '0' AND deleted = '0' AND spam = '0' ORDER BY blog_id" );
Note: $blogs array is an object collection; you will have to build your own site list with the informations that comes inside every object (id, path, domain) that is more appropriate for you, as exemplified in Firefog and Aurovrata answers.
In the usual way, you will be unable to get the blog name. To fetch blog names, you can use this little hack as follows.
$blog_list = get_blog_list(0, 'all');
foreach ($blog_list as $blog) {
switch_to_blog( $blog['blog_id'] );
$option = 'blogname';
$value = get_option( $option );
echo $value . '<br />';
restore_current_blog();
}
Also, you can use the following alternative method to get the same result by calling the database directly.
global $wpdb;
foreach ($wpdb->get_results("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE archived = '0' AND deleted = '0' AND spam = '0' ORDER BY blog_id") as $key => $blog) {
switch_to_blog( $blog->blog_id );
$option = 'blogname';
$value = get_option( $option );
echo $value . '<br />';
restore_current_blog();
}
I have next_posts_link setup on the single.php, and it generates the following URL:
http://mywebsite.com/news/article1/page/2
However, this url would be redirected to
http://mywebsite.com/news/article1
Any way to get to the second page?
It seems that it's an issue with Wordpress permalinks. I currently use a custom permalink structure
/%category%/%postname%/
Setting the permalinks as default fixes this issue, but this project needs to have the custom permalinks.
You should be using next_post_link() which is meant to navigate between single posts. next_posts_link naviugate between pages
If you however need to navigate a paged post (using <--nextpage-->), then you should make use of wp_link_pages
EDIT
I have recently did the same exact thing on WPSE. As I explain in that post, the structure you need is not available for any permalink structure outside the default permalink structure.
Just a note before I paste that answer, I have done that for the /%postname%/ permalink structure. Just change all instances of /%postname%/ to the appropriate structure
POST FROM WPSE
As I said, this whole setup you are after is not possible natively with pretty permalinks. Your setup probably works with default permalink structure as both queries (the main query and your custom query) read these permalinks in the same way. When you switch to pretty permalinks, the two queries on the single page interpret the URL differently causing one or the other to fail when you try to paginate your custom query
Single pages was never meant to be paginated in this manner, specially using pretty permalinks. I have gone and played around with a couple of ideas, and the best way to accomplish this is
To write your own pagination functions that can read the page number from the URL
Write your own function that can append the page number to the URL, something like adding /2/ to the URL of single pages.
I must stress, if you are paginating single post with <!--nextpage-->, your post will also paginate together with your custom query. Also, if your permalink structure is not set to /%postname%/, the code will fail and display an error message through wp_die()
THE CODE
Here is the code that will get the next/previous page and also add the pagenumber to the URL.
function get_single_pagination_link( $pagenum = 1 ) {
global $wp_rewrite;
if( is_singular() && $wp_rewrite->permalink_structure == '/%postname%/') {
$pagenum = (int) $pagenum;
$post_id = get_queried_object_id();
$request = get_permalink( $post_id );
if ( $pagenum > 1 ) {
$request = trailingslashit( $request ) . user_trailingslashit( $pagenum );
}
return esc_url( $request );
}else{
wp_die( '<strong>The function get_single_pagination_link() requires that your permalinks are set to /%postname%/</strong>' );
}
}
You can use this function as follow to get the link for any page in the single page when paginating your custom query
get_single_pagination_link( 'pagenumber_of_previous_or_next_page' );
Again, as I said, there is no pagination function that will be able to paginate your custom query or read pagenumbers from the URL, so you have to write your own.
Here is my idea of creating links to the next and previous pages in your custom query. If you look closely, you will see how I have used the previous declared function get_single_pagination_link() to get the links to the next and previous pages
function get_next_single_page_link ( $label = null, $max_page = 0 ) {
global $wp_query;
if ( !$max_page ) {
$max_page = $wp_query->max_num_pages;
}
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
if( is_singular() ) {
$next_page = intval($paged) + 1;
if ( null === $label ) {
$label = __( 'Next Page »' );
}
if ( ( $next_page <= $max_page ) ) {
return '' . $label . '';
}
}
}
function get_previous_single_page_link( $label = null ) {
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
if( is_singular() ) {
$prev_page = intval($paged) - 1;
if ( null === $label ) {
$label = __( '« Previous Page' );
}
if ( ( $prev_page > 0 ) ) {
return '' . $label . '';
}
}
}
You can now use this two functions in your code to paginate your custom query. Both functions work exactly the same as get_next_posts_link() and get_previous_posts_link() and uses the same exact parameters, so you'll need to keep in mind that you need to pass the $max_page parameter for your custom query
Here is your custom query with these functions.
function get_related_author_posts() {
global $authordata, $post;
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$args = array(
'posts_per_page' => 2,
'paged' => $paged
);
$authors_posts = new WP_Query( $args );
$output = '';
if( $authors_posts->have_posts() ) {
$output = '<ul>';
while( $authors_posts->have_posts() ) {
$authors_posts->the_post();
$output .= '<li>' . get_the_title() . '' . get_the_excerpt() . '</li>';
}
$output .= '</ul>';
$output .= get_previous_single_page_link();
$output .= get_next_single_page_link( null , $authors_posts->max_num_pages );
wp_reset_postdata();
}
return $output;
}
If you want your long post to be shown 2 or 3 pages . You just have to add <!--nextpage--> in your post . The content after it will be shown in the next page . Reference
Thanks for support!
I need to custom user url in my page using WordPress and BuddyPress.
This is example:
From: (current)
http://example.com/user/pum_su411
To
http://example.com/user/548234
With 548234 is ID of the user.
I want after completed the custom, all users will have url like above automatically.
Thanks for all solutions!
add this code to your theme functions.php file.
function _bp_core_get_user_domain($domain, $user_id, $user_nicename = false, $user_login = false) {
if ( empty( $user_id ) ){
return;
}
if( isset($user_nicename) ){
$user_nicename = bp_core_get_username($user_id);
}
$after_domain = bp_get_members_root_slug() . '/' . $user_id;
$domain = trailingslashit( bp_get_root_domain() . '/' . $after_domain );
$domain = apply_filters( 'bp_core_get_user_domain_pre_cache', $domain, $user_id, $user_nicename, $user_login );
if ( !empty( $domain ) ) {
wp_cache_set( 'bp_user_domain_' . $user_id, $domain, 'bp' );
}
return $domain;
}
add_filter('bp_core_get_user_domain', '_bp_core_get_user_domain', 10, 4);
function _bp_core_get_userid($userid, $username){
if(is_numeric($username)){
$aux = get_userdata( $username );
if( get_userdata( $username ) )
$userid = $username;
}
return $userid;
}
add_filter('bp_core_get_userid', '_bp_core_get_userid', 10, 2);
function _bp_get_activity_parent_content($content){
global $bp;
$user = get_user_by('slug', $bp->displayed_user->fullname); // 'slug' - user_nicename
return preg_replace('/href=\"(.*?)\"/is', 'href="'.bp_core_get_user_domain($user->ID, $bp->displayed_user->fullname).'"', $content);
}
add_filter( 'bp_get_activity_parent_content','_bp_get_activity_parent_content', 10, 1 );
function _bp_get_activity_action_pre_meta($content){
global $bp;
$fullname = $bp->displayed_user->fullname; // 'slug' - user_nicename
$user = get_user_by('slug', $fullname);
if(!is_numeric($user->ID) || empty($fullname)){
$args = explode(' ', trim(strip_tags($content)));
$fullname = trim($args[0]);
$user = get_user_by('slug', $fullname);
}
return preg_replace('/href=\"(.*?)\"/is', 'href="'.bp_core_get_user_domain($user->ID, $fullname).'"', $content);
}
add_action('bp_get_activity_action_pre_meta', '_bp_get_activity_action_pre_meta');
add_filter('bp_core_get_userid_from_nicename', '_bp_core_get_userid', 10, 2);
Just spent a bit of time going over the documentation, codex and files of BuddyPress and i can find ways of changing the /user/ part of the url but sadly not the /username side of it.
Reading through, it is controlled within the core of BuddyPress and any changes to the core can cause crashes and more than likely to cause problems or overwrites further down the line.
This isn't to say it's not possible though, it is most certainly possible, but it will require a great deal of editing to many many different files, an edit to a number of BuddyPress functions and there are no guarantee's on it working straight out or even working further down the line when files get update.
I would recommend going onto the BuddyPress Trac and putting in a ticket to have the feature added to change user url structure. It would be a cool feature to be able to swap between a username, full name, ID or any other unique identifiable string.
You can access it here: https://buddypress.trac.wordpress.org/
Alternatively, you can try what aSeptik has done above, but make sure to update that file with any changes when BuddyPress updates as well.
I have a wordpress site that connects to a soap server. The problem is every time I run the script the wp_insert_post is using the same result again.
I would like to check if existing post_title matches the value from $title then if they match, prevent wp_insert_post from using the same value again.
Here's the code:
try {
$client = new SoapClient($wsdl, array('login' => $username, 'password' => $password));
} catch(Exception $e) {
die('Couldn\'t establish connection to weblink service.');
}
$publications = $client->GetPublicationSummaries();
foreach ($publications->GetPublicationSummariesResult->PublicationSummaries->PublicationSummary as $publication_summary) {
// get the complete publication from the webservice
$publication = $client->getPublication(array('PublicationId' => $publication_summary->ID))->GetPublicationResult->Publication;
// get all properties and put them in an array
$properties = array();
foreach ($publication->Property as $attribute => $value) {
$properties[$attribute] = $value;
}
// Assemble basic title from properties
$title = $properties['Address']->Street . ' ' . $properties['Address']->HouseNumber . $properties['Address']->HouseNumberExtension . ', ' . $properties['Address']->City->_;
}
$my_post = array(
'post_title'=>$title,
'post_content'=>'my contents',
'post_status'=>'draft',
'post_type'=>'skarabeepublication',
'post_author'=>1,
);
wp_insert_post($my_post);
Thank you for any help.
You can use get_page_by_title() as it supports custom post types now.
if (!get_page_by_title($title, OBJECT, 'skarabeepublication')) :
$my_post = array(
'post_title'=>$title,
'post_content'=>'my contents',
'post_status'=>'draft',
'post_type'=>'skarabeepublication',
'post_author'=>1,
);
wp_insert_post($my_post);
endif;
Codex information here
Surprised not to see mention of post_exists function in wp-includes/post.php. See entry on wpseek. There is no entry in the codex. At it's simplest it works like get_page_by_title but returns a post id (or 0 if not found) instead of the object (or null).
$post_id = post_exists( $my_title );
if (!$post_id) {
// code here
}
Sorry for the late response. I used what Robot says in the comment and this solved my problem. Thanks
$post_if = $wpdb->get_var("SELECT count(post_title) FROM $wpdb->posts WHERE post_title like '$title_from_soap'");
if($post_if < 1){
//code here
}
sampler:
if( !get_page_by_path('mypageslug',OBJECT,'post') ){
//your codes
}