I've been following the Build a CMS in an Afternoon tutorial at http://www.elated.com/articles/cms-in-an-afternoon-php-mysql/ .
The CMS works great but the only thing it's lacking is pagination. The article archive displays the list of all of the articles that are in the database, but I want to be able to separate these into pages. I've attempted it a few times but can never seem to get it to work. Clicking on a next page link usually brings me back to the homepage.
I will apreciate your help
Code:
config.php
<?php ini_set( "display_errors", true );
date_default_timezone_set("europe/lisbon" );
define( "DB_DSN", "mysql:host=localhost;dbname=cms" );
define( "DB_USERNAME", "username" );
define( "DB_PASSWORD", "password" );
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );
define( "HOMEPAGE_NUM_ARTICLES", 5 );
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", "mypass" );
require( CLASS_PATH . "/Article.php" );
function handleException( $exception ) {
echo "Sorry, a problem occurred. Please try later.";
error_log( $exception->getMessage() ); }
set_exception_handler( 'handleException' ); ?>
archive.php
<?php include "templates/include/header.php" ?>
<h1>Article Archive</h1>
<ul id="headlines" class="archive">
<?php foreach ( $results['articles'] as $article ) { ?>
<li>
<h2>
<span class="pubDate"><?php echo date('j F Y', $article->publicationDate)?></span><?php echo htmlspecialchars( $article->title )?>
</h2>
<p class="summary"><?php echo htmlspecialchars( $article->summary )?></p>
</li>
<?php } ?>
</ul>
<p><?php echo $results['totalRows']?> article<?php echo ( $results['totalRows'] != 1 ) ? 's' : '' ?> in total.</p>
<p>Return to Homepage</p>
<?php include "templates/include/footer.php" ?>
article.php
<?php
/**
* Class to handle articles
*/
class Article
{
public $id = null;
public $publicationDate = null;
public $title = null;
public $summary = null;
public $content = null;
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['publicationDate'] ) ) $this->publicationDate = (int) $data['publicationDate'];
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
if ( isset( $data['content'] ) ) $this->content = $data['content'];
}
public function storeFormValues ( $params ) {
// Store all the parameters
$this->__construct( $params );
// Parse and store the publication date
if ( isset($params['publicationDate']) ) {
$publicationDate = explode ( '-', $params['publicationDate'] );
if ( count($publicationDate) == 3 ) {
list ( $y, $m, $d ) = $publicationDate;
$this->publicationDate = mktime ( 0, 0, 0, $m, $d, $y );
}
}
}
public static function getById( $id ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id";
$st = $conn->prepare( $sql );
$st->bindValue( ":id", $id, PDO::PARAM_INT );
$st->execute();
$row = $st->fetch();
$conn = null;
if ( $row ) return new Article( $row );
}
public static function getList( $numRows=1000000, $order="publicationDate DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$article = new Article( $row );
$list[] = $article;
}
// Now get the total number of articles that matched the criteria
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
?>
You need to modify your code to $_GET the page number and use limit and offset in the query
you can see this example
http://www.tutorialspoint.com/php/mysql_paging_php.htm
Related
So basically I've started working with OOP and the script I've wrote based on a tutorial is giving me 2 problems:
When i try to convert an object into a variable i'm getting this error:
Notice: Trying to get property of non-object in /home/stream/V2/templates/homepage.php on line 14
The code on line 14 is:
<?php echo htmlspecialchars( $series->id ) ?>
Second instead of turning the object into a variable and trying to access data directly from it i'm getting nothing.
I basically have 3 pages to help get data from a table:
Homepage.php
<?php include( "templates/include/header.php" ); ?>
<ul id="headlines">
<?php
echo $results['totalRows'];
foreach( $results['series'] as $series ){ ?>
<li>
<h2>
<!-- remember to add htmlspecialchars -->
<span class="title"><?php echo $results['series']->description ?></span>
<?php echo htmlspecialchars( $series->id ) ?>
</h2>
</li>
<?php
} ?>
</ul>
<p>Series Archive</p>
<?php include( "templates/include/footer.php" ); ?>
index.php
<?php
require( "core/config.php" );
$action = isset ( $_GET['action'] ) ? $_GET['action'] : "";
switch ( $action ){
case 'series':
series();
break;
case 'viewSeries':
viewSeries();
break;
default:
homepage();
}
function series(){
$results = array();
$data = Series::getList();
$results['series'] = $data['results'];
$results['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "Series Title";
require( TEMPLATE_PATH . "/series.php" );
}
function viewSeries(){
if( !isset( $_GET['seriesId'] ) || !$_GET['seriesId'] ){
homepage();
return;
}
$results = array();
$results['series'] = Series::getBydId( (int)$_GET['seriesId'] );
$results['pageTitle'] = $results['series']->title . "| Sub title";
require( TEMPLATE_PATH . "/viewSeries.php" );
}
function homepage(){
$results = array();
$data = Series::getList( HOMEPAGE_NUM_SERIES );
$results['series'] = $data['results'];
$results['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "Streamaton Homepage";
require( TEMPLATE_PATH . "/homepage.php");
}
And this is the piece of code from the Series.php class:
//Return all (or range of) Series objects in the db
public static function getList( $numRows=100000, $order="id DESC" ){
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT id, description FROM series ORDER BY :order LIMIT :numRows";
//SQL_CALC_FOUND_ROWS *
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->bindValue( ":order", $order, PDO::PARAM_STR );
$st->execute();
$list = array();
while( $row = $st->fetch() ){
$series = new Series( $row );
$list = $series;
}
//Now get the total number of series that match the criteria
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
The whole series.php code looks like this: http://pastebin.com/f95A8NPr
This loop is wrong:
while( $row = $st->fetch() ){
$series = new Series( $row );
$list = $series;
}
The last line should be:
$list[] = $series;
so that it pushes each series onto the array. Your code is replacing the array with a series each time through the loop.
I have sat 3 days trying to figure out Smarty, but I don't feel very much smartyer :)
Here is my php code:
somefile.php
include('libs/Smarty.class.php');
require( "configs/config.php" );
// create object
$smarty = new Smarty;
function homepage($params, $smarty, $numRows=1000000, $order="publicationDate DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$article = new Article( $row );
$list[] = $article;
}
// Now get the total number of articles that matched the criteria
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['publicationDate'] ) ) $this->publicationDate = (int) $data['publicationDate'];
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
if ( isset( $data['content'] ) ) $this->content = $data['content'];
$results = array();
$results['articles'] = $data['articles'];
$results['totalRows'] = $data['totalRows'];
$smarty->assign("articles", $data['articles']);
$smarty->assign("totalRows", $data['totalRows']);
$smarty->assign("id", $data['id']);
$smarty->assign("publicationDate", $data['publicationDate']);
$smarty->assign("title", 'kkkkkkkkkkkkkkkkkkkkk');
$smarty->assign("summary", 'lllllllllllllllllllllll');
$smarty->assign("content", 'øøøøøøøøøøøøøøøøøøøøøøøøøøøøøø');
}
// display it
$smarty->display('index2.tpl');
index2.tpl
{include file="header.tpl"}
{debug}
<h1>Article Archive</h1>
{assign var=results value={cycle values="totalRows,articles,title,publicationDate,id"}}
<ul id="headlines" class="archive">
{foreach $articles['articles'] as $article}
<li>
<h2>
<span class="pubDate">{$publicationDate}</span>{$title}
</h2>
<p class="summary">{$summary}</p>
</li>
{/foreach}
</ul>
<p>Articles Archive</p>
{include file="footer.tpl"}
The errors I get are:
Notice: Undefined index: articles in /var/www/www.mypage.com/htdocs/smarty/templates_c/cd9ff0835daf703adc0ed3991c1d26021d9fcc09.file.index2.tpl.php on line 42
Notice: Trying to get property of non-object in /var/www/www.mypage.com/htdocs/smarty/templates_c/cd9ff0835daf703adc0ed3991c1d26021d9fcc09.file.index2.tpl.php on line 42
I think that the problem is that, for some reason, you assume that when you do
$smarty->assign("articles", $data['articles']);
they key 'articles' is included, wich is not, only the contents of it. So there is no such $articles['articles'] passed to the template, in he same way there is no $id['id'], only $id. Try to do the foreach with just $articles:
{foreach $articles as $article}
I'm having an issue displaying the results of query. The weird thing is, all of the results are being obtained and only one is not. I'm at a complete loss.
I'm going to describe, to the best of my knowledge, how this code is supposed to work. I built it from a tutorial.
In "listProducts.php" all the products in the database are listed in a table.
<table id="productTable">
<tr>
<th>UPC</th>
<th>Title</th>
<th>Thumb</th>
<th>Price</th>
<th>Stock</th>
<th>Lead Time</th>
<th></th>
</tr>
<?php foreach ( $results['products'] as $product ) {
list($week, $day) = explode("|", $product->lead);
echo htmlspecialchars($product->lead);
?>
<tr onclick="location='products.php?action=editProduct&productId=<?php echo $product->id?>'">
<td><img src="../<?php echo $product->thumb ?>"/></td>
<td><?php echo htmlspecialchars($product->upc)?></td>
<td><?php echo htmlspecialchars($product->title)?></td>
<td style="text-align:right;">$<?php echo number_format($product->price, 2 )?></td>
<td style="text-align:right;"><?php echo number_format($product->stock, 0)?></td>
<td style="text-align:right;"><? echo $week.'|'.$day;?></td>
<td><button >Edit</button></td>
</tr>
<? } ?>
</table>
The problem is lead, which exists in the database as lead, is not being or has not been fetched and therefore not being exploded and is therefore not being echoed as week and day.
Even if, for testing purposes, I echo just lead, i get nothing.
<? echo htmlspecialchars($products->lead)?>
There is a listProducts() function and some class junk that i did not come up with, but I have thoroughly manipulated to my own ends so I'm fairly confident that they should work. But, I'll post them anyway.
function listProducts() {
$results = array();
$data = Product::getList();
$results['products'] = $data['results'];
$results['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "All Products";
if ( isset( $_GET['error'] ) ) {
if ( $_GET['error'] == "productNotFound" ) $results['errorMessage'] = "Error: Product not found.";
}
if ( isset( $_GET['status'] ) ) {
if ( $_GET['status'] == "changesSaved" ) $results['statusMessage'] = "Your changes have been saved.";
if ( $_GET['status'] == "productDeleted" ) $results['statusMessage'] = "Product deleted.";
}
require( TEMPLATE_PATH . "/admin/listProducts.php" );
}
And here is the parts of the product class that i think deal with displaying the list... cus it says get list.
public static function getList( $numRows=100, $order="title DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT SQL_CALC_FOUND_ROWS *, id FROM products
ORDER BY " . $order . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$product = new Product( $row );
$list[] = $product;
}
// Now get the total number of products that matched the criteria
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
and some constructors and variables. I don't know if they are necessary or not
public $id = null;
public $upc = null;
public $title = null;
public $thumb = null;
public $description = null;
public $price = null;
public $stock = null;
public $lead = null;
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['upc'] ) ) $this->upc = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['upc'] );
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\#\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
if ( isset( $data['thumb'] ) ) $this->thumb = $data['thumb'];
if ( isset( $data['description'] ) ) $this->description = $data['description'];
if ( isset( $data['price'] ) ) $this->price = $data['price'];
if ( isset( $data['stock'] ) ) $this->stock = (int) $data['stock'];
if ( isset( $data['week'] ) && isset( $data['day'] ) ) $this->lead = $data['week']."|".$data['day'];
}
It is an external group blogs plugin
It gives group creators and administrators on your BuddyPress install the ability to attach external blog RSS feeds to groups.
Blog posts will appear within the activity stream for the group.
New posts will automatically be pulled every hour, or every 30 minutes if someone specifically visits a group page.
There are so many bugs that I found.
1) it is not fetching feeds automatically
2) if I try to manually updates feeds it is reposting the same entries, I mean it is not fetching new feeds.
3) WordPress admin bar is also not working properly with this plugin.
This plugin contains 2 webpages.
First and the main page is loader.php
<?php
/*
Plugin Name: External Group Blogs
Plugin URI: http://wordpress.org/extend/plugins/external-group-blogs/
Description: Allow group creators to supply external blog RSS feeds that will attach future posts on blogs to a group.
*/
/* Only load the plugin functions if BuddyPress is loaded and initialized. */
function bp_groupblogs_init() {
require( dirname( __FILE__ ) . '/bp-groups-externalblogs.php' );
}
add_action( 'bp_init', 'bp_groupblogs_init' );
/* On activation register the cron to refresh external blog posts. */
function bp_groupblogs_activate() {
wp_schedule_event( time(), 'hourly', 'bp_groupblogs_cron' );
}
register_activation_hook( __FILE__, 'bp_groupblogs_activate' );
/* On deacativation, clear the cron. */
function bp_groupblogs_deactivate() {
wp_clear_scheduled_hook( 'bp_groupblogs_cron' );
/* Remove all external blog activity */
if ( function_exists( 'bp_activity_delete' ) )
bp_activity_delete( array( 'type' => 'exb' ) );
}
register_deactivation_hook( __FILE__, 'bp_groupblogs_deactivate' );
?>
And the 2nd file is bp-groups-externalblogs.php
<?php
/* Group blog extension using the BuddyPress group extension API */
if ( class_exists('BP_Group_Extension' ) ) {
class Group_External_Blogs extends BP_Group_Extension {
function __construct() {
global $bp;
$this->name = __( 'External Blogs', 'bp-groups-externalblogs' );
$this->slug = 'external-blog-feeds';
$this->create_step_position = 21;
$this->enable_nav_item = false;
}
function create_screen() {
global $bp;
if ( !bp_is_group_creation_step( $this->slug ) )
return false;
?>
<p><?php _e(
"Add RSS feeds of blogs you'd like to attach to this group in the box below.
Any future posts on these blogs will show up on the group page and be recorded
in activity streams.", 'bp-groups-externalblogs' ) ?>
</p>
<p class="desc"><?php _e( "Seperate URL's with commas.", 'bp-groups-externalblogs' ) ?></span>
<p>
<label for="blogfeeds"><?php _e( "Feed URL's:", 'bp-groups-externalblogs' ) ?></label>
<textarea name="blogfeeds" id="blogfeeds"><?php echo attribute_escape( implode( ', ', (array)groups_get_groupmeta( $bp->groups->current_group->id, 'blogfeeds' ) ) ) ?></textarea>
</p>
<?php
wp_nonce_field( 'groups_create_save_' . $this->slug );
}
function create_screen_save() {
global $bp;
check_admin_referer( 'groups_create_save_' . $this->slug );
$unfiltered_feeds = explode( ',', $_POST['blogfeeds'] );
foreach( (array) $unfiltered_feeds as $blog_feed ) {
if ( !empty( $blog_feed ) )
$blog_feeds[] = trim( $blog_feed );
}
groups_update_groupmeta( $bp->groups->current_group->id, 'blogfeeds', $blog_feeds );
groups_update_groupmeta( $bp->groups->current_group->id, 'bp_groupblogs_lastupdate', gmdate( "Y-m-d H:i:s" ) );
/* Fetch */
bp_groupblogs_fetch_group_feeds( $bp->groups->current_group->id );
}
function edit_screen() {
global $bp;
if ( !bp_is_group_admin_screen( $this->slug ) )
return false; ?>
<p class="desc"><?php _e( "Enter RSS feed URL's for blogs you would like to attach to this group. Any future posts on these blogs will show on the group activity stream. Seperate URL's with commas.", 'bp-groups-externalblogs' ) ?></span>
<p>
<label for="blogfeeds"><?php _e( "Feed URL's:", 'bp-groups-externalblogs' ) ?></label>
<textarea name="blogfeeds" id="blogfeeds"><?php echo attribute_escape( implode( ', ', (array)groups_get_groupmeta( $bp->groups->current_group->id, 'blogfeeds' ) ) ) ?></textarea>
</p>
<input type="submit" name="save" value="<?php _e( "Update Feed URL's", 'bp-groups-externalblogs' ) ?>" />
<?php
wp_nonce_field( 'groups_edit_save_' . $this->slug );
}
function edit_screen_save() {
global $bp;
if ( !isset( $_POST['save'] ) )
return false;
check_admin_referer( 'groups_edit_save_' . $this->slug );
$existing_feeds = (array)groups_get_groupmeta( $bp->groups->current_group->id, 'blogfeeds' );
$unfiltered_feeds = explode( ',', $_POST['blogfeeds'] );
foreach( (array) $unfiltered_feeds as $blog_feed ) {
if ( !empty( $blog_feed ) )
$blog_feeds[] = trim( $blog_feed );
}
/* Loop and find any feeds that have been removed, so we can delete activity stream items */
if ( !empty( $existing_feeds ) ) {
foreach( (array) $existing_feeds as $feed ) {
if ( !in_array( $feed, (array) $blog_feeds ) )
$removed[] = $feed;
}
}
if ( $removed ) {
/* Remove activity stream items for this feed */
include_once( ABSPATH . WPINC . '/rss.php' );
foreach( (array) $removed as $feed ) {
$rss = fetch_rss( trim( $feed ) );
if ( function_exists( 'bp_activity_delete' ) ) {
bp_activity_delete( array(
'item_id' => $bp->groups->current_group->id,
'secondary_item_id' => wp_hash( $rss->channel['link'] ),
'component' => $bp->groups->id,
'type' => 'exb'
) );
}
}
}
groups_update_groupmeta( $bp->groups->current_group->id, 'blogfeeds', $blog_feeds );
groups_update_groupmeta( $bp->groups->current_group->id, 'bp_groupblogs_lastupdate', gmdate( "Y-m-d H:i:s" ) );
/* Re-fetch */
bp_groupblogs_fetch_group_feeds( $bp->groups->current_group->id );
bp_core_add_message( __( 'External blog feeds updated successfully!', 'bp-groups-externalblogs' ) );
bp_core_redirect( bp_get_group_permalink( $bp->groups->current_group ) . '/admin/' . $this->slug );
}
/* We don't need display functions since the group activity stream handles it all. */
function display() {}
function widget_display() {}
}
bp_register_group_extension( 'Group_External_Blogs' );
function bp_groupblogs_fetch_group_feeds( $group_id = false ) {
global $bp;
include_once( ABSPATH . 'wp-includes/rss.php' );
if ( empty( $group_id ) )
$group_id = $bp->groups->current_group->id;
if ( $group_id == $bp->groups->current_group->id )
$group = $bp->groups->current_group;
else
$group = new BP_Groups_Group( $group_id );
if ( !$group )
return false;
$group_blogs = groups_get_groupmeta( $group_id, 'blogfeeds' );
$group_blogs = explode(";",$group_blogs[0]);
/* Set the visibility */
$hide_sitewide = ( 'public' != $group->status ) ? true : false;
foreach ( (array) $group_blogs as $feed_url ) {
$rss = fetch_feed( trim( $feed_url ) );
if (!is_wp_error($rss) ) {
foreach ( $rss->get_items(0,10) as $item ) {;
$key = $item->get_date( 'U' );
$items[$key]['title'] = $item->get_title();
$items[$key]['subtitle'] = $item->get_title();
//$items[$key]['author'] = $item->get_author()->get_name();
$items[$key]['blogname'] = $item->get_feed()->get_title();
$items[$key]['link'] = $item->get_permalink();
$items[$key]['blogurl'] = $item->get_feed()->get_link();
$items[$key]['description'] = $item->get_description();
$items[$key]['source'] = $item->get_source();
$items[$key]['copyright'] = $item->get_copyright();
}
}
}
if ( $items ) {
ksort($items);
$items = array_reverse($items, true);
} else {
return false;
}
/* Record found blog posts in activity streams */
foreach ( (array) $items as $post_date => $post ) {
//var_dump($post);
if (substr($post['blogname'],0,7) == "Twitter") {
$activity_action = sprintf( __( '%s from %s in the group %s', 'bp-groups-externalblogs' ), '<a class="feed-link" href="' . esc_attr( $post['link'] ) . '">Tweet</a>', '<a class="feed-author" href="' . esc_attr( $post['blogurl'] ) . '">' . attribute_escape( $post['blogname'] ) . '</a>', '' . attribute_escape( $group->name ) . '' );
} else {
$activity_action = sprintf( __( 'Blog: %s from %s in the group %s', 'bp-groups-externalblogs' ), '<a class="feed-link" href="' . esc_attr( $post['link'] ) . '">' . esc_attr( $post['title'] ) . '</a>', '<a class="feed-author" href="' . esc_attr( $post['blogurl'] ) . '">' . attribute_escape( $post['blogname'] ) . '</a>', '' . attribute_escape( $group->name ) . '' );
}
$activity_content = '<div>' . strip_tags( bp_create_excerpt( $post['description'], 175 ) ) . '</div>';
$activity_content = apply_filters( 'bp_groupblogs_activity_content', $activity_content, $post, $group );
/* Fetch an existing activity_id if one exists. */
if ( function_exists( 'bp_activity_get_activity_id' ) )
$id = bp_activity_get_activity_id( array( 'user_id' => false, 'action' => $activity_action, 'component' => $bp->groups->id, 'type' => 'exb', 'item_id' => $group_id, 'secondary_item_id' => wp_hash( $post['blogurl'] ) ) );
/* Record or update in activity streams. */
groups_record_activity( array(
'id' => $id,
'user_id' => false,
'action' => $activity_action,
'content' => $activity_content,
'primary_link' => $item->get_link(),
'type' => 'exb',
'item_id' => $group_id,
'secondary_item_id' => wp_hash( $post['blogurl'] ),
'recorded_time' => gmdate( "Y-m-d H:i:s", $post_date ),
'hide_sitewide' => $hide_sitewide
) );
}
return $items;
}
/* Add a filter option to the filter select box on group activity pages */
function bp_groupblogs_add_filter() { ?>
<option value="exb"><?php _e( 'External Blogs', 'bp-groups-externalblogs' ) ?></option><?php
}
add_action( 'bp_group_activity_filter_options', 'bp_groupblogs_add_filter' );
add_action( 'bp_activity_filter_options', 'bp_groupblogs_add_filter' );
/* Add a filter option groups avatar */
/* Fetch group twitter posts after 30 mins expires and someone hits the group page */
function bp_groupblogs_refetch() {
global $bp;
$last_refetch = groups_get_groupmeta( $bp->groups->current_group->id, 'bp_groupblogs_lastupdate' );
if ( strtotime( gmdate( "Y-m-d H:i:s" ) ) >= strtotime( '+30 minutes', strtotime( $last_refetch ) ) )
add_action( 'wp_footer', 'bp_groupblogs_refetch' );
/* Refetch the latest group twitter posts via AJAX so we don't stall a page load. */
function _bp_groupblogs_refetch() {
global $bp; ?>
<script type="text/javascript">
jQuery(document).ready( function() {
jQuery.post( ajaxurl, {
action: 'refetch_groupblogs',
'cookie': encodeURIComponent(document.cookie),
'group_id': <?php echo $bp->groups->current_group->id ?>
});
});
</script><?php
groups_update_groupmeta( $bp->groups->current_group->id, 'bp_groupblogs_lastupdate', gmdate( "Y-m-d H:i:s" ) );
}
}
add_action( 'groups_screen_group_home', 'bp_groupblogs_refetch' );
/* Refresh via an AJAX post for the group */
function bp_groupblogs_ajax_refresh() {
bp_groupblogs_fetch_group_feeds( $_POST['group_id'] );
}
add_action( 'wp_ajax_refetch_groupblogs', 'bp_groupblogs_ajax_refresh' );
function bp_groupblogs_cron_refresh() {
global $bp, $wpdb;
$group_ids = $wpdb->get_col( $wpdb->prepare( "SELECT group_id FROM " . $bp->groups->table_name_groupmeta . " WHERE meta_key = 'blogfeeds'" ) );
foreach( $group_ids as $group_id )
bp_groupblogs_fetch_group_feeds( $group_id );
}
add_action( 'bp_groupblogs_cron', 'bp_groupblogs_cron_refresh' );
}
// Add a filter option groups avatar
function bp_groupblogs_avatar_type($var) {
global $activities_template, $bp;
if ( $activities_template->activity->type == "exb" ) {
return 'group';
} else {
return $var;
}
}
add_action( 'bp_get_activity_avatar_object_groups', 'bp_groupblogs_avatar_type');
add_action( 'bp_get_activity_avatar_object_activity', 'bp_groupblogs_avatar_type');
function bp_groupblogs_avatar_id($var) {
global $activities_template, $bp;
if ( $activities_template->activity->type == "exb" ) {
return $activities_template->activity->item_id;
}
return $var;
}
add_action( 'bp_get_activity_avatar_item_id', 'bp_groupblogs_avatar_id');
?>
I have a suggestion for stopping data repeating in activity stream. Maybe use wp-cron api and a current date xml feeds fetching system once in a day. So it will not repeat the same feeds in a group activity stream. We need a criteria by which we can stop data repetition in the bp group activity stream. It is a part of my project. Is there another way of fetching feeds and saving it to the mysql table (in the group activity stream) and then show it as a latest group updates?
Actually IT IS fetching automatically.
I see the cron usage in a plugin. WordPress Cron fires only when any user opens your site. So no users (no pageviews) - no cron activity. On every pageview WP-Cron check whether the time to fire any function came or not.
Perhaps this plugin will help you a bit - display a RSS feed in a separate group tab.
Wordpress ships with the wpdb class which handles CRUD operations. The two methods of this class that I'm interested in are the insert() (the C in CRUD) and update() (the U in CRUD).
A problem arises when I want to insert a NULL into a mysql database column - the wpdb class escapes PHP null variables to empty strings. How can I tell Wordpress to use an actual MySQL NULL instead of a MySQL string?
If you want it to compatible you would have to SHOW COLUMN and determine ahead if NULL is allowed. If it was allowed then if the value was empty($v) use val = NULL in the query.
$foo = null;
$metakey = "Harriet's Adages";
$metavalue = "WordPress' database interface is like Sunday Morning: Easy.";
if ($foo == null) {
$wpdb->query( $wpdb->prepare( "
INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value, field_with_null )
VALUES ( %d, %s, %s, NULL )",
10, $metakey, $metavalue ) );
} else {
$wpdb->query( $wpdb->prepare( "
INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value, field_with_null )
VALUES ( %d, %s, %s, %s)",
10, $metakey, $metavalue, $foo ) );
}
Here's a solution to your problem. In "wp-content" folder, create a file named "db.php" and put this code in it:
<?php
// setup a dummy wpdb to prevent the default one from being instanciated
$wpdb = new stdclass();
// include the base wpdb class to inherit from
//include ABSPATH . WPINC . "/wp-db.php";
class wpdbfixed extends wpdb
{
function insert($table, $data, $format = null) {
$formats = $format = (array) $format;
$fields = array_keys($data);
$formatted_fields = array();
$real_data = array();
foreach ( $fields as $field ) {
if ($data[$field]===null)
{
$formatted_fields[] = 'NULL';
continue;
}
if ( !empty($format) )
$form = ( $form = array_shift($formats) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$formatted_fields[] = "'".$form."'";
$real_data[] = $data[$field];
}
//$sql = "INSERT INTO <code>$table</code> (<code>" . implode( '</code>,<code>', $fields ) . "</code>) VALUES (" . implode( ",", $formatted_fields ) . ")";
$sql = "INSERT INTO $table (" . implode( ',', $fields ) . ") VALUES (" . implode( ",", $formatted_fields ) . ")";
return $this->query( $this->prepare( $sql, $real_data) );
}
function update($table, $data, $where, $format = null, $where_format = null)
{
if ( !is_array( $where ) )
return false;
$formats = $format = (array) $format;
$bits = $wheres = array();
$fields = (array) array_keys($data);
$real_data = array();
foreach ( $fields as $field ) {
if ($data[$field]===null)
{
$bits[] = "$field = NULL";
continue;
}
if ( !empty($format) )
$form = ( $form = array_shift($formats) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$bits[] = "$field = {$form}";
$real_data[] = $data[$field];
}
$where_formats = $where_format = (array) $where_format;
$fields = (array) array_keys($where);
foreach ( $fields as $field ) {
if ( !empty($where_format) )
$form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$wheres[] = "$field = {$form}";
}
$sql = "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
return $this->query( $this->prepare( $sql, array_merge($real_data, array_values($where))) );
}
}
$wpdb = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
?>
In this way you can use null values with wpdb!
I find this on Wordpress StackExchange forum and it works very well for me.
// Add a filter to replace the 'NULL' string with NULL
add_filter( 'query', 'wp_db_null_value' );
global $wpdb;
$wpdb->update(
'table',
array(
'status' => 'NULL',
),
array( 'id' => 1 )
);
// Remove the filter again:
remove_filter( 'query', 'wp_db_null_value' );
and the function wp_db_null_value is:
/**
* Replace the 'NULL' string with NULL
*
* #param string $query
* #return string $query
*/
function wp_db_null_value( $query )
{
return str_ireplace( "'NULL'", "NULL", $query );
}
Because in my case I cannot use $db->prepare() function...
wpdb insert() and update() works with NULL values, it was patched many years ago but never mentioned in the Codex.
In your case:
$wpdb->update(
'table',
array(
'status' => null,
),
array( 'id' => 1 ),
null,
'%d'
);
Ref: https://core.trac.wordpress.org/ticket/15158#no0
I tried to edit one of the other solutions listed here, because it resulted in the format array being misaligned with the data array, but failed.
Here is a solution that modifies the wpdb from the latest version of wordpress, in order to allow inserting and updating null values into SQL tables using insert() and update():
/*
* Fix wpdb to allow inserting/updating of null values into tables
*/
class wpdbfixed extends wpdb
{
function insert($table, $data, $format = null) {
$type = 'INSERT';
if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
return false;
$this->insert_id = 0;
$formats = $format = (array) $format;
$fields = array_keys( $data );
$formatted_fields = array();
foreach ( $fields as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
//***Steve Lee edit begin here***
if ($data[$field]===null) {
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$formatted_fields[] = 'NULL';
} else {
$formatted_fields[] = $form; //Original line of code
}
//***Steve Lee edit ends here***
}
$sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
return $this->query( $this->prepare( $sql, $data ) );
}
function update($table, $data, $where, $format = null, $where_format = null)
{
if ( ! is_array( $data ) || ! is_array( $where ) )
return false;
$formats = $format = (array) $format;
$bits = $wheres = array();
foreach ( (array) array_keys( $data ) as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
//***Steve Lee edit begin here***
if ($data[$field]===null)
{
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$bits[] = "`$field` = NULL";
} else {
$bits[] = "`$field` = {$form}"; //Original line of code
}
//***Steve Lee edit ends here***
}
$where_formats = $where_format = (array) $where_format;
foreach ( (array) array_keys( $where ) as $field ) {
if ( !empty( $where_format ) )
$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
$wheres[] = "`$field` = {$form}";
}
$sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
}
}
global $wpdb_allow_null;
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
Insert this code into somewhere that always gets run, like your functions.php, and then use your new global $wpdb_allowed_null->insert() and ->update() as normal.
I preferred this method vs. overriding the default $wpdb, in order to preserve the DB behavior that the rest of Wordpress and other plugins will expect.