Help - Search - Member List - Calendar
Full Version: Modification/amélioration du SDK via Héritage
IPBR-FR > Entraide > Forums dédiés aux mods majeures > IPB SDK
LLaumgui
Tout d’abord, ce post est réservé au développeurs confirmés possédant des notions d'objet, d'héritage et polymorphisme.

Au cours des posts, j’ai souvent dit avoir optimisé/sécurisé mon SDK, mais que cela était au pris d'une mise à jour de ce dernier difficile. C'est là qu’intervient l'héritage.

Mon idée est de ne plus utiliser IPBSDK, mais une classe héritant du SDK.
Je développe donc cette idée sur mon blog.

Au programme : Héritage du ipbSDK - Part1 (La théorie).
Héritage du ipbSDK - Part2 (Premier pas).
Héritage du ipbSDK - Part3 (De nouvelles variables).
Rubrique SDK de mon blog


Les postes qui suivent comportent des fonctions qui sont la redéfinitions de fonctions déjà présentent dans le SDK ou de nouvelle fonction que j'ai incorporé dans MySDK smile.gif.
LLaumgui
get_board_stats() -> -1 requêtes :

Bon, après une étude approfondie des données dans le cache IPBSDK et de celle dans le cache de IPB, je me rend compte qu'elle sont différentes.

J'ai modifié ma fonction get_board_stats() pour qu'elle puise dans le cache IPB et non pas IPBSDK --> 1 requête de moins smile.gif.

CODE
/**
 * Obtenir les statistiques de mon forums.
 * Modification : Liaison avec le cache IPB au lieu de celui du SDK.
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @author Pita (conversion to 2.0) <peter@randomnity.com>
 * @author Cow <khlo@global-centre.com>
 * @return array Board Statistics
 */
function get_board_stats() {

 // 1 : Je cherche dans le cache IPB :
 if ( !empty($GLOBALS['ibforums']->cache['stats']) && is_array($GLOBALS['ibforums']->cache['stats']) )
  { return $GLOBALS['ibforums']->cache['stats']; }  
 else
  {
   $this->DB->query ('SELECT cs_value FROM ibf_cache_store WHERE cs_key = "stats"');
   $row          = $this->DB->fetch_row();
   $stats         = unserialize(stripslashes($row['cs_value']));
   $GLOBALS['ibforums']->cache['stats']  =  $stats;
   return $stats;
  }
}


Plus d'infos sur mon blogs.
LLaumgui
get_advinfo() -> -5 requêtes !!!

Attention, je me sert beaucoup de cette fonction d'où les 5 requêtes. Vous pouvez en gagner moins smile.gif mais plus.

Cette dernière fonctions ne tiens pas compte des guests. En effet un guest à une mid = 0. La fonction effectue donc la requêtes :
SQL
SELECT m.*, me.signature, me.avatar_size, me.avatar_location, me.avatar_type, me.vdirs,
me.location, me.msnname, me.interests, me.yahoo, me.website, me.aim_name, me.icq_number,
g.*, cf.*
FROM ibf_members m
LEFT JOIN ibf_groups g ON (m.mgroup=g.g_id)
LEFT JOIN ibf_pfields_content cf ON (cf.member_id=m.id)
LEFT JOIN ibf_member_extra me ON (me.id=m.id)
WHERE m.id='0'

Cette requête ne retournant rien, n'alimente pas le cache. On interoge x fois la fonction on a toujours pas de cache, donc on refait la requête !!!

La solution :

CODE
/**
* Grabs detailed information on a member.
* Modification : Gestion des guest.
* @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
* @author Pita (conversion to 2.0) <peter@randomnity.com>
* @author Cow <khlo@global-centre.com>
* @param integer $memberid
* @return array Member Information, or FALSE on failure
* @see get_info(),get_avatar(),get_raw_sig(),get_photo(),get_member_pips(),get_member_i
con(),get_num_new_posts(),get_skin_id()
*/
function get_advinfo($memberid = '') {

if (!$memberid)
{ $memberid = $GLOBALS['ibforums']->member['id']; }

// Gestion des guests non présentes de base ! :
if ( empty($memberid) || $memberid == 0 )
{ return false; }
else if ($cache = $this->get_cache('get_advinfo', $memberid))
{ return $cache; }
else
{
$this->DB->query ("SELECT m.*, me.signature, me.avatar_size, me.avatar_location, me.avatar_type, me.vdirs,
me.location, me.msnname, me.interests, me.yahoo,
me.website, me.aim_name, me.icq_number,
g.*, cf.*
FROM ibf_members m
LEFT JOIN ibf_groups g ON (m.mgroup=g.g_id)
LEFT JOIN ibf_pfields_content cf ON (cf.member_id=m.id)
LEFT JOIN ibf_member_extra me ON (me.id=m.id)
WHERE m.id='" . intval($memberid) . "'");
if ($this->DB->get_num_rows())
{
$info = $this->DB->fetch_row();
$this->save_cache('get_advinfo', $memberid, $info);
return $info;
}
else
{ return FALSE; }
}
}
LLaumgui
get_num_new_posts() -> Améliorations :

get_num_new_posts() retourne de base le nombre de posts depuis la dernière visite... Le miens retourne le nombre de posts et le nombre de topics (x nouveaux posts dans y topics).

CODE
/**
 * Redéfinition de la fonction du SDK. Permet de retourner le nombre de nouveaux messages depuis
 * la dernier visite et le nombre de topic concerné par ces nouveaux messages.
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @author Pita (conversion to 2.0) <peter@randomnity.com>
 * @author CTiga <crouchintiga@comcast.net>
 * @since 4.0
 * @see IPBSDK::get_num_new_posts()
 * @return array Tableau avec mon nombre de nouveaux messages et de message totaux
 */
function get_num_new_posts() {
 
 if (!$this->is_loggedin())
  {
   $this->sdkerror($this->lang['sdk_membersonly']);
   return false;
  }
 // Retourne le résultats dans un tableau nb post dans nb topics :
 $new_post = array (  'post'   => 0,
       'topics'  => 0);
     
 // Détermine si on prend la dernière visite ou la dernière activité comme référence :
 if ( $GLOBALS['ibforums']->member['last_visit'] < $GLOBALS['ibforums']->member['last_activity'] )
  { $last_activity = $GLOBALS['ibforums']->member['last_activity']; }
 else
  { $last_activity = $GLOBALS['ibforums']->member['last_visit']; }
 
 $this->DB->query("SELECT COUNT(DISTINCT topic_id) AS topic, COUNT(pid) AS new
       FROM ibf_posts
       WHERE post_date > '".$last_activity."'");
 if ($post = $this->DB->fetch_row())
  {
   $new_post['post']  = $post['new'];
   $new_post['topic']  = $post['topic'];
   return $new_post;    
  }
 else
  { return false; }
}
LLaumgui
list_online_members() -> -1 requêtes :

Pas exactement -1 requêtes, mais j'ai fusionnais 2 fonctions qui faisaient chacune une requête et elle en font plus qu'une toutes les 2 smile.gif.
Ca retourne le nombre de membre en ligne avec la liste.

CODE
/**
 * Redéfinition de la fonction du SDK. Permet de retourner le nombre de membre en ligne ainsi que la liste.
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @author Pita (conversion to 2.0) <peter@randomnity.com>
 * @author Cow <khlo@global-centre.com>* @since 4.0
 * @see IPBSDK::list_online_members(), IPBSDK::get_active_count
 * @param $option
 * @return array Tableau avec mon nombre de nouveaux messages et de message totaux
 */
function list_online_members($options=array('order_by'=>'running_time','order'=>'DESC')) {
 
 $cutoff   = $GLOBALS['ibforums']->vars['au_cutoff'] ? $GLOBALS['ibforums']->vars['au_cutoff'] : "15";
 $timecutoff  = time() - ($cutoff * 60);

 foreach (array_keys($options) as $k)
  { $options[$k] = $this->makesafe($options[$k]); }
 
 $fields = array('member_name'=>'ASC', 'member_id'=>'ASC', 'running_time'=>'DESC', 'location'=>'ASC');

 if ( in_array($options['order_by'], array_keys($fields)) )
  {
   $order_by = sprintf('s.%s %s', $options['order_by'], $fields[$options['order_by']]);
   // second sort order
   if ($options['order_by'] == 'location')
    { $order_by .= ', s.running_time DESC'; }
  }
 else
  { $order_by = 's.running_time DESC'; }

 if ( $cache = $this->get_cache('list_online_members', 'detail'.$order_by) )
  { return $cache; }
 else
  {
   // Requête light :
   $this->DB->query (" SELECT s.*, g.prefix, g.suffix
        FROM ibf_sessions s
         LEFT JOIN ibf_groups g ON (s.member_group = g.g_id)
        WHERE s.running_time > '" . $timecutoff . "'
        ORDER BY ".$order_by);
       
   // Retourne un tableau de tableau pour n'utiliser qu'une seule requête...
   $online = array(  'online' => array (),
        'count'  => array ( 'total'  => 0,
             'anon'   => 0,
             'guests' => 0,
             'members' => 0) );

   while ($row = $this->DB->fetch_row())
    {
     // Liste :
     if ( $row['member_id'] != 0 ) { $online['online'][] = $row; } // si pas guest.
     // Compteur:
     if ( $row['login_type'] == '1' )
      { ++$online['count']['anon']; }
     else
      {
       if ($row['member_id'] == '0')
        { ++$online['count']['guests']; }
       else
        { ++$online['count']['members']; }
      }
    }

   $online['count']['total'] = $online['count']['anon'] + $online['count']['guests'] + $online['count']['members'];
   $this->save_cache('list_online_members', 'detail'.$order_by, $online);
   
   return $online;
  }
}
LLaumgui
edit_topic() -> Fonction non présente de base :

Bon, là c'est tout con, mais c'est pas de base dans le SDK...

CODE
/**
 * Edition d'un topic :
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @since 4.03
 * @param int $topicid Identifiant du topic.
 * @param int $title Titre du topic.
 * @param String $desc Description du topic.
 * @return
 */
function edit_topic ($topicid, $title, $desc ) {
 
 $title  = $this->makesafe($title);
 $desc  = $this->makesafe($desc);
 
 return $this->DB->query (" UPDATE ibf_topics
        SET title   = '$title',
         description = '$desc'
        WHERE tid = $topicid
        LIMIT 1");
}
LLaumgui
get_post_info() -> Sécurité :

Pour celle là, j'ai viré plein de choses inutiles... Mais je vous conseil juste de rajouter la partie :
CODE
    /*
      * Protection à la LLaumgui !!! Je n'autorise l'affichage que des post
      * où le visiteur à le droit de lecture.
      */
    if ( $this->is_forum_readable( intval($row['forum_id']) ) )
     { return $row; }
    else
     { return false; }
   }





CODE
/**
 * Récupérer les informations d'un post.
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @author Pita (conversion to 2.0) <peter@randomnity.com>
 * @author Cow <khlo@global-centre.com>
 * @param integer $postid Identidiant du post
 * @return array Post Information
 */
 function get_post_info ($postid) {
 
 // Check for Post Cache
 if ($cache = $this->get_cache('get_post_info', $postid))
  { return $cache; }
 else
  {
   $this->DB->query (" SELECT p.post post, p.author_id author_id, p.author_name author_name, p.topic_id topic_id, p.post_date post_date,
          t.forum_id, t.title AS topic_name, t.posts comment, g.g_dohtml AS usedohtml
        FROM ibf_posts p
          LEFT JOIN ibf_topics t ON (p.topic_id=t.tid)
          LEFT JOIN ibf_members m ON (p.author_id=m.id)
          LEFT JOIN ibf_groups g ON (m.mgroup=g.g_id)
        WHERE p.pid='" . $postid . "'");
  if ( $row = $this->DB->fetch_row() )
   {
    $row['post'] = $GLOBALS['parser']->post_db_parse($row['post'], $row['usedohtml']);
    $row['post'] = str_replace("<#EMO_DIR#>",$GLOBALS['ibforums']->skin['_emodir'],$row['post']);
    $row['post'] = str_replace("<img src='style_emoticons","<img src='".$this->_options['board_url']."/style_emoticons",$row['post']);
    $this->save_cache('get_post_info', $postid, $row);
   
    /*
      * Protection à la LLaumgui !!! Je n'autorise l'affichage que des post
      * où le visiteur à le droit de lecture.
      */
    if ( $this->is_forum_readable( intval($row['forum_id']) ) )
     { return $row; }
    else
     { return false; }
   }
  else
   { return false; }
  }
}
LLaumgui
html2bbcode() -> Gestion de Word :

Là c'est une redéfinition faisant appel à la super classe (le ipbSDK)... Donc si vous passez pas par l'héritage, faut rajouter ma ligne directement dans le SDK.
Pour comprendre, j'écrit mes news avec Word et je copie/colle via IE... Des caractères Microsoft non w3c se retrouvent donc dans mes posts... J'ai donc fait cette fonction pour transformer l'apostrophe Word en apostrophe w3c.

CODE
/**
 * Résoud le problème des copie/coller issus de Word
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @return string HTML version of input
 * @see html2bbcode(), parse_dohtml()
 */
function html2bbcode($input) {
 
 $input   = str_replace ( "’"       , "'" ,  $input );
 $input  = IPBSDK::html2bbcode($input);

 return $input;
}
LLaumgui
get_birthday_members() -> 0 requête MySQL grace au cache IPB :

CODE
/**
 * Retourne les membres dont c'est l'anniversaire.
 * Modification : Liaison avec le cache IPB.
 * @author Guillaume Kulakowski <llaumgui_AT_xperience-fr.net>
 * @author Pita (conversion to 2.0) <peter@randomnity.com>
 * @author Cow <khlo@global-centre.com>
 * @param integer $day Optional. Current day is used if left as an empty string or zero.
 * @param integer $month Optional. Current month is used if left as an empty string or zero.
 * @return array Birthday Members
 * @see list_members(), list_online_members()
 */
function get_birthday_members($day = 0, $month = 0) {
 
 if ( empty($GLOBALS['ibforums']->cache['birthdays']) && $day == 0 && $month == 0 )
  {
   if ((int)$day<=0)  { $day = date('j'); }
   if ((int)$month<=0)  { $month = date ('n'); }
   $this->DB->query("SELECT m.*, me.signature, me.avatar_size, me.avatar_location, me.avatar_type, me.vdirs, me.location, me.msnname, me.interests, me.yahoo, me.website, me.aim_name, me.icq_number, g.*, cf.* FROM ibf_members m LEFT JOIN ibf_groups g ON (m.mgroup=g.g_id) LEFT JOIN ibf_pfields_content cf ON (cf.member_id=m.id) LEFT JOIN ibf_member_extra me ON (m.id=me.id) WHERE m.bday_day='" . intval($day) . "' AND m.bday_month='" . intval($month) . "'");
 
   $return = array();
   $thisyear = date ('Y');
   while ($row = $this->DB->fetch_row())
    {
     $row['age'] = $thisyear - $row['bday_year'];
     $return[] = $row;
    }
   return $return;
  }
 else
  { return $GLOBALS['ibforums']->cache['birthdays']; }
}
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2012 Invision Power Services, Inc.