Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/tools/model/_tool.funcs.php
<?php
/**
 * This file implements functions to work with tools.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
 *
 * @package evocore
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );


/**
 * Create sample collections and display a process of creating
 *
 * @param integer Number of collections
 * @param array Kind of setting "Permission management": 'simple', 'advanced'
 * @param array Kind of setting "Allow access to": 'public', 'users', 'members'
 */
function tool_create_sample_collections( $num_collections, $perm_management, $allow_access )
{
    global
$DB, $Debuglog, $Plugins, $Messages;

    echo
T_('Creating of the sample collections...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
$count = 1;
   
$perm_management_max_index = count( $perm_management ) - 1;
   
$allow_access_max_index = count( $allow_access ) - 1;
    for(
$i = 0; $i < $num_collections; $i++ )
    {
       
// Create and save a new collection:
       
$new_Blog = new Blog( NULL );
       
$shortname = generate_random_passwd();
       
$new_Blog->set( 'owner_user_ID', 1 );
       
$new_Blog->set( 'shortname', $shortname );
       
$new_Blog->set( 'name', $shortname );
       
$new_Blog->set( 'urlname', urltitle_validate( strtolower( $shortname ), $shortname, $new_Blog->ID, false, 'blog_urlname', 'blog_ID', 'T_blogs' ) );
       
// Set random of "Permission management" from the selected options:
       
$new_Blog->set( 'advanced_perms', $perm_management[ rand( 0, $perm_management_max_index ) ] == 'advanced' ? 1 : 0 );
       
// Set random of "Allow access to" from the selected options:
       
$new_Blog->set_setting( 'allow_access', $allow_access[ rand( 0, $allow_access_max_index ) ] );;

       
// Define collection settings by its kind:
       
$Plugins->trigger_event( 'InitCollectionKinds', array(
               
'Blog' => & $new_Blog,
               
'kind' => 'std',
            ) );

       
// Do a creating new collection:
       
$new_Blog->create();

       
// Don't show a sample collection on top menu in back-office:
        // TODO: In another branch Erwin has implemented a rule similar to "only enable first 10 collections". This will be merged here at some point.
       
$new_Blog->favorite( NULL, 0 );

       
// Clear the messages because we have at least 4 messages after each $new_Blog->create() which are the same:
       
$Messages->clear();

       
$count++;

        if(
$count % 100 == 0 )
        {    
// Display a process of creating by one dot for 100 comments:
           
echo ' .';
           
evo_flush();
        }

       
// Clear all debug messages, To avoid an error about full memory:
       
$Debuglog->clear( 'all' );
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d collections.'), $count - 1 ), 'success' );
}


/**
 * Create sample comments and display a process of creating
 *
 * @param integer Blog ID
 * @param integer Number of comments
 * @param integer Number of posts
 */
function tool_create_sample_comments( $blog_ID, $num_comments, $num_posts )
{
    global
$DB, $localtimenow, $Hit, $Messages, $Debuglog;

   
$BlogCache = & get_BlogCache();
   
$selected_Blog = $BlogCache->get_by_ID( $blog_ID, false, false );
    if(
$selected_Blog == NULL )
    {
// Incorrect blog ID, Exit here
       
return;
    }

    echo
T_('Creating of the sample comments...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
$curr_orderby = $selected_Blog->get_setting('orderby');
    if(
$curr_orderby == 'RAND' )
    {
       
$curr_orderby .= '()';
    }
    else
    {
       
$curr_orderby = 'post_'.$curr_orderby;
    }
   
$curr_orderdir = $selected_Blog->get_setting('orderdir');

   
// find the $num_posts latest posts in blog
   
$SQL = new SQL( 'Find the '.$num_posts.' latest posts in collection #'.$blog_ID );
   
$SQL->SELECT( 'post_ID' );
   
$SQL->FROM( 'T_items__item' );
   
$SQL->FROM_add( 'INNER JOIN T_categories ON post_main_cat_ID = cat_ID' );
   
$SQL->FROM_add( 'LEFT JOIN T_items__type ON post_ityp_ID = ityp_ID' );
   
$SQL->WHERE( 'cat_blog_ID = '.$DB->quote( $blog_ID ) );
   
$SQL->WHERE_and( 'post_status = '.$DB->quote( 'published' ) );
   
// Set condition to not create sample comments for special posts
   
$SQL->WHERE_and( 'post_ityp_ID IS NULL OR ityp_usage = "post"' );
   
$SQL->ORDER_BY( $curr_orderby.' '.$curr_orderdir.', post_ID '.$curr_orderdir );
   
$SQL->LIMIT( $num_posts );
   
$items_result = $DB->get_results( $SQL, ARRAY_A );

   
$count = 1;
   
$fix_content = 'This is an auto generated comment for testing the moderation features.
                    http://www.test.com/test_comment_'
;
   
// go through on selected items
   
foreach( $items_result as $row )
    {
       
$item_ID = $row['post_ID'];

       
$ItemCache = & get_ItemCache();
       
$commented_Item = & $ItemCache->get_by_ID( $item_ID );

       
// create $num_comments comments for each item
       
for( $i = 0; $i < $num_comments; $i++ )
        {
           
$author = 'Test '.$count;
           
$email = 'test_'.$count.'@test.com';
           
$url = 'http://www.test-'.rand(1,3).'.com/test_comment_'.$count;

           
$content = $fix_content.$count;
            for(
$j = 0; $j < 50; $j++ )
            {
// create 50 random word
               
$length = rand(1, 15);
               
$word = generate_random_key( $length, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' );
               
$content = $content.' '.$word;
            }

           
// create and save a new comment
           
$Comment = new Comment();
           
$Comment->set_Item( $commented_Item );
           
$Comment->set( 'status', 'draft' );
           
$Comment->set( 'author', $author );
           
$Comment->set( 'author_email', $email );
           
$Comment->set( 'author_url', $url );
           
$Comment->set( 'content', $content );
           
$Comment->set( 'date', date( 'Y-m-d H:i:s', $localtimenow ) );
           
$Comment->set( 'author_IP', $Hit->IP );
           
$Comment->dbsave();
           
$count++;

            if(
$count % 100 == 0 )
            {
// Display a process of creating by one dot for 100 comments
               
echo ' .';
               
evo_flush();
            }

           
// Clear all debug messages, To avoid an error about full memory
           
$Debuglog->clear( 'all' );
        }
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d comments.'), $count - 1 ), 'success' );
}


/**
 * Create sample posts and display a process of creating
 *
 * @param integer Blog ID
 * @param integer Number of posts
 */
function tool_create_sample_posts( $blog_ID, $num_posts )
{
    global
$Messages, $DB, $Debuglog;

   
$BlogCache = & get_BlogCache();
   
$selected_Blog = $BlogCache->get_by_ID( $blog_ID, false, false );
    if(
$selected_Blog == NULL )
    {
// Incorrect blog ID, Exit here
       
return;
    }

    echo
T_('Creating of the sample posts...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
$count = 1;
   
$num_posts_created = 0;
   
$content = T_( 'This is an auto generated post for testing moderation.' );
    for(
$i = 1; $i <= $num_posts; $i++ )
    {
       
// Spaces and line breaks make generated string look like real text
       
$length = rand(300, 500);
       
$word = generate_random_key( $length, "\n     abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
       
$post_content = $content.' '.$word;
       
$urltitle = strtolower( str_replace( array("\n", ' ', '-'), '', substr($word, 50, 20) ) );
       
$urltitle = trim( $urltitle, '-' );

       
$Item = new Item();
       
$Item->set( 'title', 'Generated post '.$i );
       
$Item->set( 'content', $post_content );
       
$Item->set( 'status', 'published' );
       
$Item->set( 'dateset', 1 );
       
// Set post main cat ID, from selected blog
       
$Item->set( 'main_cat_ID', $selected_Blog->get_default_cat_ID() );
       
// Random post url slug
       
$Item->set( 'urltitle', $urltitle );
        if(
$Item->dbinsert_test() )
        {
           
$num_posts_created++;
        }
       
$count++;

        if(
$count % 100 == 0 )
        {
// Display a process of creating by one dot for 100 posts
           
echo ' .';
           
//pre_dump( memory_get_usage() );
           
evo_flush();
        }

       
// Clear all debug messages, To avoid an error about full memory
       
$Debuglog->clear( 'all' );
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d posts.'), $num_posts_created ), 'success' );
    if(
$num_posts > $num_posts_created )
    {
// Some post creation failed because of concurtent modification error
        // Note: This message should not appear offten, so it doesn't need translation
       
$Messages->add( sprintf( 'Creation of %d post(s) failed becuase of concurrent modification error.', $num_posts - $num_posts_created ), 'note' );
    }
}


/**
 * Create random number of sample revisions of existing posts and display a process of creating
 *
 * @param integer Blog ID
 * @param integer Minimum number of revision per post
 * @param integer Maximum number of revision per post
 */
function tool_create_sample_revisions( $blog_ID, $min_revisions = 1, $max_revisions = 3 )
{
    global
$Messages, $DB, $Debuglog;

   
$BlogCache = & get_BlogCache();
   
$selected_Blog = & $BlogCache->get_by_ID( $blog_ID );
    if(
$selected_Blog == NULL )
    {
// Incorrect blog ID, Exit here
       
return;
    }

    echo
T_('Creating of the sample revisions...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
load_class( 'users/model/_userlist.class.php', 'UserList' );
   
$UserList = new UserList( '', 1000 );
   
$UserList->query();

   
// Get users who can edit posts in the selected collection
   
$editor_Users = array();
    while(
$loop_User = & $UserList->get_next() )
    {
        if(
$loop_User->check_perm( 'blog_edit', 'edit', false, $selected_Blog ) )
        {
           
$editor_Users[] = $loop_User->ID;
        }
    }

   
$ItemList = new ItemList2( $selected_Blog, NULL, NULL, 0 );
   
$ItemList->query();

   
$revisions_created = 0;
   
$editors_count = count( $editor_Users );

   
$count = 1;
    while(
$Item = & $ItemList->get_item() )
    {
       
// Get next version ID
       
$iver_SQL = new SQL();
       
$iver_SQL->SELECT( 'MAX( iver_ID )' );
       
$iver_SQL->FROM( 'T_items__version' );
       
$iver_SQL->WHERE( 'iver_itm_ID = '.$Item->ID );
       
$iver_ID = ( int ) $DB->get_var( $iver_SQL->get() ) + 1;

       
$num_revisions = rand( $min_revisions, $max_revisions );
        for(
$i = 0; $i < $num_revisions; $i++ )
        {
            if(
$i === 0 )
            {
// Original author
               
$editor_user_id = 'post_lastedit_user_ID';
            }
            else
            {
               
$editor_user_id = $editor_Users[rand( 0, $editors_count - 1 )];
            }

           
$sql = 'INSERT INTO T_items__version( iver_ID, iver_itm_ID, iver_edit_user_ID, iver_edit_last_touched_ts, iver_status, iver_title, iver_content )
                SELECT "'
.$iver_ID.'" AS iver_ID, post_ID, '.$editor_user_id.', post_datemodified, post_status, CONCAT( post_title, " - revision '.$iver_ID.'" ), post_content
                    FROM T_items__item
                WHERE post_ID = '
.$Item->ID;

           
$revisions_created++;
           
$result = $DB->query( $sql, 'Save a version of the Item' ) !== false;

           
$iver_ID += 1;
        }

        if(
$count % 100 == 0 )
        {
            echo
' .';
           
//pre_dump( memory_get_usage() );
           
evo_flush();
        }
       
$count++;

       
// Clear all debug messages, To avoid an error about full memory
       
$Debuglog->clear( 'all' );
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d revisions.'), $revisions_created ), 'success' );
}


/**
 * Create sample users and display a process of creating
 *
 * @param array Group IDs
 * @param integer Number of users per group
 * @param array Kind of advanced user perms
 */
function tool_create_sample_users( $user_groups, $num_users, $advanced_user_perms )
{
    global
$Messages, $DB, $Debuglog;

    echo
T_('Creating of the sample users...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
// Check if we should assign at least one advanced permission:
   
$array_intersect = array_intersect( $advanced_user_perms, array( 'member', 'moderator', 'admin' ) );
   
$assign_adv_user_perms = ! empty( $array_intersect );

    if(
$assign_adv_user_perms )
    {
// Get all collections with advanced perms:
       
$coll_SQL = new SQL( 'Get all collections with advanced perms for tool "Create sample users"' );
       
$coll_SQL->SELECT( 'blog_ID' );
       
$coll_SQL->FROM( 'T_blogs' );
       
$coll_SQL->WHERE( 'blog_advanced_perms = 1' );
       
$adv_perm_coll_IDs = $DB->get_col( $coll_SQL );
    }

   
// Load all selected groups in cache:
   
$GroupCache = & get_GroupCache();
   
$GroupCache->load_list( $user_groups );

   
$count = 1;
   
$user_groups_max_index = count( $user_groups ) - 1;
   
$advanced_user_perms_max_index = count( $advanced_user_perms ) - 1;
    for(
$i = 1; $i <= $num_users; $i++ )
    {
       
$login = generate_random_passwd();
        while(
user_exists( $login ) )
        {
// Generate new unique login
           
$login = generate_random_passwd();
        }

       
$User = new User();
       
// Create out of range hashes for better security
       
$User->set( 'pass', generate_random_passwd() );
       
$User->set( 'login', $login );
       
$User->set( 'email', 'test_'.$i.'@test.com' );
       
$User->set( 'firstname', 'Test user '.$i );
       
$User->set( 'url', 'http://www.test-'.rand(1,3).'.com/test_user_'.$i );
        if(
$rand_Group = & $GroupCache->get_by_ID( $user_groups[ rand( 0, $user_groups_max_index) ], false, false ) )
        {    
// Set a random group from checked options if a group really exists in DB:
           
$User->set_Group( $rand_Group );
        }

        if(
$User->dbinsert() )
        {    
// If user has been created successfully
           
$count++;

            if(
$assign_adv_user_perms && ! empty( $adv_perm_coll_IDs ) )
            {    
// Grant advanced user perms on existing collections with advanced perms:
               
$adv_perm_coll_insert_values = array();
                foreach(
$adv_perm_coll_IDs as $adv_perm_coll_ID )
                {    
// Select random kind of advanced permissions:
                   
switch( $advanced_user_perms[ rand( 0, $advanced_user_perms_max_index ) ] )
                    {
                        case
'member':
                           
// Set member permissions:
                           
$adv_perm_coll_insert_values[] = implode( ',', array(
                                   
'blog_ID'              => $adv_perm_coll_ID,
                                   
'user_ID'              => $User->ID,
                                   
'ismember'             => 1,
                                   
'can_be_assignee'      => 0,
                                   
'workflow_status'      => 0,
                                   
'workflow_user'        => 0,
                                   
'workflow_priority'    => 0,
                                   
'perm_item_propose'    => 0,
                                   
'perm_poststatuses'    => '""',
                                   
'perm_item_type'       => '"standard"',
                                   
'perm_edit'            => '"no"',
                                   
'perm_delpost'         => 0,
                                   
'perm_edit_ts'         => 0,
                                   
'perm_delcmts'         => 0,
                                   
'perm_recycle_owncmts' => 0,
                                   
'perm_vote_spam_cmts'  => 0,
                                   
'perm_cmtstatuses'     => '""',
                                   
'perm_edit_cmt'        => '"no"',
                                   
'perm_cats'            => 0,
                                   
'perm_properties'      => 0,
                                   
'perm_admin'           => 0,
                                   
'perm_media_upload'    => 0,
                                   
'perm_media_browse'    => 0,
                                   
'perm_media_change'    => 0,
                                   
'perm_analytics'       => 0,
                                ) );
                            break;

                        case
'moderator':
                           
// Set moderator permissions:
                           
$adv_perm_coll_insert_values[] = implode( ',', array(
                                   
'blog_ID'              => $adv_perm_coll_ID,
                                   
'user_ID'              => $User->ID,
                                   
'ismember'             => 1,
                                   
'can_be_assignee'      => 1,
                                   
'workflow_status'      => 1,
                                   
'workflow_user'        => 1,
                                   
'workflow_priority'    => 1,
                                   
'perm_item_propose'    => 1,
                                   
'perm_poststatuses'    => '"published,community,protected,review,private,draft,deprecated"',
                                   
'perm_item_type'       => '"restricted"',
                                   
'perm_edit'            => '"le"',
                                   
'perm_delpost'         => 1,
                                   
'perm_edit_ts'         => 1,
                                   
'perm_delcmts'         => 1,
                                   
'perm_recycle_owncmts' => 1,
                                   
'perm_vote_spam_cmts'  => 1,
                                   
'perm_cmtstatuses'     => '"published,community,protected,review,private,draft,deprecated"',
                                   
'perm_edit_cmt'        => '"le"',
                                   
'perm_cats'            => 0,
                                   
'perm_properties'      => 0,
                                   
'perm_admin'           => 0,
                                   
'perm_media_upload'    => 1,
                                   
'perm_media_browse'    => 1,
                                   
'perm_media_change'    => 1,
                                   
'perm_analytics'       => 0,
                                ) );
                            break;

                        case
'admin':
                           
// Set administrator permissions:
                           
$adv_perm_coll_insert_values[] = implode( ',', array(
                                   
'blog_ID'              => $adv_perm_coll_ID,
                                   
'user_ID'              => $User->ID,
                                   
'ismember'             => 1,
                                   
'can_be_assignee'      => 1,
                                   
'workflow_status'      => 1,
                                   
'workflow_user'        => 1,
                                   
'workflow_priority'    => 1,
                                   
'perm_item_propose'    => 1,
                                   
'perm_poststatuses'    => '"published,community,protected,review,private,draft,deprecated,redirected"',
                                   
'perm_item_type'       => '"admin"',
                                   
'perm_edit'            => '"all"',
                                   
'perm_delpost'         => 1,
                                   
'perm_edit_ts'         => 1,
                                   
'perm_delcmts'         => 1,
                                   
'perm_recycle_owncmts' => 1,
                                   
'perm_vote_spam_cmts'  => 1,
                                   
'perm_cmtstatuses'     => '"published,community,protected,review,private,draft,deprecated"',
                                   
'perm_edit_cmt'        => '"all"',
                                   
'perm_cats'            => 1,
                                   
'perm_properties'      => 1,
                                   
'perm_admin'           => 1,
                                   
'perm_media_upload'    => 1,
                                   
'perm_media_browse'    => 1,
                                   
'perm_media_change'    => 1,
                                   
'perm_analytics'       => 1,
                                ) );
                            break;
                    }
                }
                if( ! empty(
$adv_perm_coll_insert_values ) )
                {    
// Insert advanced user perms for new created user in single query for all collections with advanced perms:
                   
$DB->query( 'INSERT INTO T_coll_user_perms ( bloguser_blog_ID, bloguser_user_ID, bloguser_ismember,
                            bloguser_can_be_assignee, bloguser_workflow_status, bloguser_workflow_user, bloguser_workflow_priority,
                            bloguser_perm_item_propose, bloguser_perm_poststatuses, bloguser_perm_item_type, bloguser_perm_edit, bloguser_perm_delpost, bloguser_perm_edit_ts,
                            bloguser_perm_delcmts, bloguser_perm_recycle_owncmts, bloguser_perm_vote_spam_cmts, bloguser_perm_cmtstatuses,
                            bloguser_perm_edit_cmt, bloguser_perm_cats, bloguser_perm_properties, bloguser_perm_admin, bloguser_perm_media_upload,
                            bloguser_perm_media_browse, bloguser_perm_media_change, bloguser_perm_analytics )
                        VALUES ( '
.implode( '), (', $adv_perm_coll_insert_values ).' )' );
                }
            }
        }

       
// Clear the messages because we have at least 4 messages after each $new_Blog->create() on user creating with group that has an appropriate setting:
        // (Those messages are the duplicated, so they fill a screen very large)
       
$Messages->clear();

        if(
$count % 20 == 0 )
        {    
// Display a process of creating by one dot for 20 users:
           
echo ' .';
           
evo_flush();
        }

       
// Clear all debug messages, To avoid an error about full memory:
       
$Debuglog->clear( 'all' );
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d users.'), $count - 1 ), 'success' );
}


/**
 * Create sample hits and display a process of creating
 *
 * @param integer Days of stats to generate
 * @param integer Minimal interval between 2 consecutive hits (sec)
 * @param integer Maximal interval between 2 consecutive hits (sec)
 */
function tool_create_sample_hits( $days, $min_interval, $max_interval )
{
    global
$Messages, $DB;

   
load_funcs('sessions/model/_hitlog.funcs.php');

    echo
T_('Creating of the sample hits...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
$insert_data_count = generate_hit_stat( $days, $min_interval, $max_interval, true );

    echo
' OK.';

   
$Messages->add( sprintf( '%d test data hits are added.', $insert_data_count ), 'success' );
}


/**
 * Create sample base domains and display a process of creating
 *
 * @param integer Number of base domains
 */
function tool_create_sample_basedomains( $num_basedomains )
{
    global
$Messages, $DB;

    echo
T_('Creating of the sample base domains...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
$DB->begin();

   
$SQL = new SQL( 'Get all unique base domains before create sample sample base domains' );
   
$SQL->SELECT( 'dom_name' );
   
$SQL->FROM( 'T_basedomains' );
   
$SQL->WHERE( 'dom_type = "unknown"' );
   
$basedomains = $DB->get_col( $SQL );

   
$basedomains_sql_data;
    for(
$i = 0; $i < $num_basedomains; $i++ )
    {
        do
        {    
// Generate new unique domain:
           
$domain_name = generate_random_key( 8, 'abcdefghijklmnopqrstuvwxyz0123456789-' ).'.com';
        } while(
in_array( $domain_name, $basedomains ) );

       
$basedomains[] = $domain_name;
       
$basedomains_sql_data[] = '( '.$DB->quote( $domain_name ).' )';

        if(
$i % 100 == 0 )
        {    
// Display a process of creating by one dot for 100 base domains:
           
echo ' .';
           
evo_flush();
        }
    }

   
$DB->query( 'INSERT INTO T_basedomains ( dom_name )
        VALUES '
.implode( ', ', $basedomains_sql_data ) );

   
$DB->commit();

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d base domains.'), $num_basedomains ), 'success' );
}


/**
 * Create sample messages and display a process of creating
 *
 * @param integer Number of loops
 * @param integer Number of messages in each conversation
 * @param integer Number of words in each message
 * @param integer Max # of participants in a conversation
 */
function tool_create_sample_messages( $num_loops, $num_messages, $num_words, $max_users )
{
    global
$Messages, $DB;

    echo
T_('Creating sample messages...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
// Get all users
   
$SQL = new SQL( 'Get all users' );
   
$SQL->SELECT( 'user_ID' );
   
$SQL->FROM( 'T_users' );
   
$users = $DB->get_col( $SQL );

    if(
count( $users ) < 2 )
    {    
// No users
       
$Messages->add( T_('At least two users must exist in DB to create the messages'), 'error' );
        return;
    }

   
$count_threads = 0;
   
$count_messages = 0;
    for(
$l = 0; $l < $num_loops; $l++ )
    {
       
$user_links = array();
        foreach(
$users as $from_user_ID )
        {
            foreach(
$users as $to_user_ID )
            {
                if(
$from_user_ID == $to_user_ID || isset( $user_links[ (string) $from_user_ID.'-'.$to_user_ID ] ) )
                {
                    continue;
                }

               
$user_links[ $from_user_ID.'-'.$to_user_ID ] = 1;
               
// Insert thread
               
$DB->query( 'INSERT INTO T_messaging__thread ( thrd_title, thrd_datemodified )
                    VALUES ( '
.$DB->quote( generate_random_key( 16 ) ).', '.$DB->quote( date( 'Y-m-d H:i:s' ) ).' )' );

               
$thread_ID = $DB->insert_id;
               
$count_threads++;

                for(
$m = 0; $m < $num_messages; $m++ )
                {
                   
$msg_text = '';
                    for(
$w = 0; $w < $num_words; $w++ )
                    {
                       
$msg_text .= generate_random_key( 8 ).' ';
                    }
                   
$message_user_ID = $m % 2 == 0 ? $from_user_ID : $to_user_ID;
                   
// Insert message
                   
$DB->query( 'INSERT INTO T_messaging__message ( msg_author_user_ID , msg_datetime, msg_thread_ID, msg_text, msg_renderers )
                        VALUES ( '
.$DB->quote( $message_user_ID ).', '.$DB->quote( date( 'Y-m-d H:i:s' ) ).', '.$DB->quote( $thread_ID ).', '.$DB->quote( $msg_text ).', \'default\' )' );
                   
$count_messages++;

                    if(
$count_messages % 100 == 0 )
                    {
// Display a process of creating by one dot for 100 users
                       
echo ' .';
                       
evo_flush();
                    }
                }

               
// Insert link for thread & user
               
$DB->query( 'INSERT INTO T_messaging__threadstatus ( tsta_thread_ID , tsta_user_ID, tsta_first_unread_msg_ID )
                    VALUES ( '
.$DB->quote( $thread_ID ).', '.$DB->quote( $from_user_ID ).', NULL ),
                                 ( '
.$DB->quote( $thread_ID ).', '.$DB->quote( $to_user_ID ).', NULL )' );
            }
        }

       
/** Create one conversation between all users ( limit by $max_users ) **/

        // Insert thread
       
$DB->query( 'INSERT INTO T_messaging__thread ( thrd_title, thrd_datemodified )
            VALUES ( '
.$DB->quote( generate_random_key( 16 ) ).', '.$DB->quote( date( 'Y-m-d H:i:s' ) ).' )' );

       
$thread_ID = $DB->insert_id;
       
$count_threads++;

       
$user_number = 0;
        for(
$m = 0; $m < $num_messages; $m++ )
        {
           
$msg_text = '';
            for(
$w = 0; $w < $num_words; $w++ )
            {
               
$msg_text .= generate_random_key( 8 ).' ';
            }
           
// Insert message
           
$DB->query( 'INSERT INTO T_messaging__message ( msg_author_user_ID , msg_datetime, msg_thread_ID, msg_text, msg_renderers )
                VALUES ( '
.$DB->quote( $users[ $user_number ] ).', '.$DB->quote( date( 'Y-m-d H:i:s' ) ).', '.$DB->quote( $thread_ID ).', '.$DB->quote( $msg_text ).', \'default\' )' );
           
$count_messages++;
           
$user_number++;
            if(
$user_number == count( $users ) || $user_number == $max_users - 1 )
            {    
// Reset user number to start of the list
               
$user_number = 0;
            }
        }

       
// Insert the links between thread & users
       
$threadstatuses = array();
        foreach(
$users as $u => $user_ID )
        {
           
$threadstatuses[] = '( '.$DB->quote( $thread_ID ).', '.$DB->quote( $user_ID ).', NULL )';
            if(
$u == $max_users - 1 )
            {    
// limit by max users in one thread
               
break;
            }
        }
       
$DB->query( 'INSERT INTO T_messaging__threadstatus ( tsta_thread_ID , tsta_user_ID, tsta_first_unread_msg_ID )
            VALUES '
.implode( ', ', $threadstatuses ) );
    }

    echo
' OK.';

   
$Messages->add( sprintf( T_('%d threads and %d messages have been created.'), $count_threads, $count_messages ), 'success' );
}


/**
 * Create sample email campaigns and display a process of creating
 *
 * @param integer Number of email campaigns
 * @param array Newsletter IDs
 */
function tool_create_sample_campaigns( $num_campaigns, $campaign_lists, $send_campaign_emails )
{
    global
$Messages, $DB, $Debuglog, $Settings, $UserSettings, $baseurl, $email_send_simulate_only;

   
load_class( 'email_campaigns/model/_emailcampaign.class.php', 'EmailCampaign' );

    echo
T_('Creating sample email campaigns...');
   
evo_flush();

   
/**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
   
$DB->log_queries = false;

   
// Load all users IDs:
   
$user_IDs = $DB->get_col( 'SELECT user_ID FROM T_users WHERE user_status IN ( "activated", "autoactivated", "manualactivated" )' );

   
// Load all selected lists in cache:
   
$NewsletterCache = & get_NewsletterCache();
   
$NewsletterCache->load_list( $campaign_lists );

   
$count = 1;
   
$campaign_lists_max_index = count( $campaign_lists ) - 1;

   
$DB->begin();

   
// Temporarily simulate email sending
   
$temp_email_send_simulate_only = $email_send_simulate_only;
   
$email_send_simulate_only = true;

   
// Temporarily increase email campaign limit settings:
   
$temp_email_campaign_chunk_size = $Settings->get( 'email_campaign_chunk_size' );
   
$Settings->set( 'email_campaign_chunk_size', 10000 );
   
$temp_email_campaign_max_domain = $Settings->get( 'email_campaign_max_domain' );
   
$Settings->set( 'email_campaign_max_domain', 10000 );
   
$Settings->dbupdate();

    for(
$i = 1; $i <= $num_campaigns; $i++ )
    {
       
$rand_list_ID = $campaign_lists[rand( 0, $campaign_lists_max_index )];
       
$EmailCampaign = new EmailCampaign();
       
$EmailCampaign->set( 'enlt_ID', $rand_list_ID );
       
$EmailCampaign->set( 'name', T_('Markdown Example').' '.$i );
       
$EmailCampaign->set( 'email_defaultdest', $baseurl );
       
$EmailCampaign->set( 'email_title', T_('Markdown Example').' '.$i );
       
$EmailCampaign->set( 'email_text', T_('Heading
=======

Sub-heading
-----------

### H3 header

#### H4 header ####

> Email-style angle brackets
> are used for blockquotes.

> > And, they can be nested.

> ##### Headers in blockquotes
>
> * You can quote a list.
> * Etc.

[This is a link](http://b2evolution.net/) if Links are turned on in the markdown plugin settings

Paragraphs are separated by a blank line.

    This is a preformatted
    code block.

Text attributes *Italic*, **bold**, `monospace`.

Shopping list:

* apples
* oranges
* pears

The rain---not the reign---in Spain.'
).
"\n".
T_('Button examples:
[button]This is a button[/button]
[like]I like this[/like] [dislike]I don\'t like this[/dislike]
[cta:1:info]Call to action 1 info button[/cta] [cta:2:warning]Call to action 2 warning button[/cta] [cta:3:default]Call to action 3 default button[/cta]
[cta:1:link]Call to action 1 link only[/cta]'
) );

        if(
$EmailCampaign->dbinsert() )
        {    
// Send email after successfull email campaign creating:
           
$count++;
           
$loop_user_IDs = array_rand( array_flip( $user_IDs ), rand( 1, count( $user_IDs) ) );
            if( !
is_array( $loop_user_IDs ) )
            {
               
$loop_user_IDs = array( $loop_user_IDs );
            }
            if( ! empty(
$loop_user_IDs ) )
            {    
// Only if we have found the users in DB
               
if( $send_campaign_emails )
                {
                   
$EmailCampaign->send_all_emails( false, $loop_user_IDs );
                   
// Randomly set clicked values
                   
$DB->query( 'UPDATE T_email__campaign_send
                            SET
                                csnd_clicked_unsubscribe = IF( RAND() > 0.95, 1, 0 ),
                                csnd_like = IF( RAND() > 0.75, 1, IF( RAND() > 0.8, -1, 0 ) ),
                                csnd_cta1 = IF( RAND() > 0.85, 1, 0 ),
                                csnd_cta2 = IF( RAND() > 0.85, 1, 0 ),
                                csnd_cta3 = IF( RAND() > 0.85, 1, 0 )
                            WHERE
                                csnd_camp_ID = '
.$EmailCampaign->ID );

                   
// Update timestamps based on randomly generated click values above:
                   
$DB->query( 'UPDATE T_email__campaign_send
                            SET
                                csnd_last_open_ts = IF( ABS(csnd_like) + csnd_cta1 + csnd_cta2 + csnd_cta3 + csnd_clicked_unsubscribe > 0, NOW(), IF( RAND() > 0.7, NOW(), NULL ) ),
                                csnd_last_click_ts = IF( ABS(csnd_like) + csnd_cta1 + csnd_cta2 + csnd_cta3 > 0, NOW(), NULL )
                            WHERE
                                csnd_camp_ID = '
.$EmailCampaign->ID );

                   
// Decrement last email count part in 'last_newsletter' user setting. This will bypass the newsletter limit setting of the users.
                   
$DB->query( 'UPDATE T_users__usersettings
                            SET uset_value = CONCAT( SUBSTRING_INDEX( uset_value, "_", 1 ), "_", CONVERT( SUBSTRING_INDEX( uset_value, "_", -1 ), SIGNED INTEGER ) - 1 )
                            WHERE uset_name = "last_newsletter" AND uset_user_ID IN ('
.$DB->quote( $loop_user_IDs ).')' );

                   
// We need to reset the user settings so the above update query changes are used
                   
$UserSettings->reset();
                }
                else
                {
                   
$EmailCampaign->add_recipients( $loop_user_IDs );
                }
            }
        }

        if(
$count % 20 == 0 )
        {    
// Display a process of creating by one dot for 20 campaigns:
           
echo ' .';
           
evo_flush();
        }

       
// Clear all debug messages, To avoid an error about full memory:
       
$Debuglog->clear( 'all' );
    }

   
// Update email campaign counters
   
$DB->query( 'UPDATE T_email__campaign
            LEFT JOIN (
                SELECT
                    csnd_camp_ID,
                    SUM( IF( csnd_last_sent_ts IS NULL, 0, 1 ) ) AS send_count,
                    SUM( IF( csnd_cta1 = 1, 1, 0 ) ) AS cta1_clicks,
                    SUM( IF( csnd_cta2 = 1, 1, 0 ) ) AS cta2_clicks,
                    SUM( IF( csnd_cta3 = 1, 1, 0 ) ) AS cta3_clicks,
                    SUM( IF( csnd_like = 1, 1, 0 ) ) AS like_count,
                    SUM( IF( csnd_like = -1, 1, 0 ) ) AS dislike_count,
                    SUM( COALESCE( csnd_clicked_unsubscribe, 0 ) ) AS unsub_clicks,
                    SUM( IF( csnd_last_open_ts IS NULL, 0, 1 ) ) AS img_loads,
                    SUM( IF( csnd_last_click_ts IS NULL, 0, 1 ) ) AS link_clicks,
                    SUM( IF( csnd_last_open_ts IS NOT NULL OR csnd_last_click_ts IS NOT NULL OR
                        csnd_like <> 0 OR csnd_cta1 > 0 OR csnd_cta2 > 0 OR csnd_cta3 > 0, 1, 0 ) ) AS open_count
                FROM T_email__campaign_send
                WHERE csnd_emlog_ID IS NOT NULL
                GROUP BY csnd_camp_ID
            ) AS a ON a.csnd_camp_ID = ecmp_ID
            SET
                ecmp_send_count = COALESCE( a.send_count, 0 ),
                ecmp_open_count = COALESCE( a.open_count, 0 ),
                ecmp_img_loads = COALESCE( a.img_loads, 0 ),
                ecmp_link_clicks = COALESCE( a.link_clicks, 0 ),
                ecmp_cta1_clicks = COALESCE( a.cta1_clicks, 0 ),
                ecmp_cta2_clicks = COALESCE( a.cta2_clicks, 0 ),
                ecmp_cta3_clicks = COALESCE( a.cta3_clicks, 0 ),
                ecmp_like_count = COALESCE( a.like_count, 0 ),
                ecmp_dislike_count = COALESCE( a.dislike_count, 0 ),
                ecmp_unsub_clicks = COALESCE( a.unsub_clicks, 0 )'
);

   
// Restore simulate email sending setting
   
$email_send_simulate_only = $temp_email_send_simulate_only;

   
// Restore email campaign chunk size
   
$Settings->set( 'email_campaign_chunk_size', $temp_email_campaign_chunk_size );
   
$Settings->set( 'email_campaign_max_domain', $temp_email_campaign_max_domain );
   
$Settings->dbupdate();

   
$DB->commit();

    echo
' OK.';

   
$Messages->add( sprintf( T_('Created %d email campaigns.'), $count - 1 ), 'success' );
}


/**
 * Test a flush function
 */
function tool_test_flush()
{
    for(
$i = 1; $i <= 30; $i++ )
    {
        echo
T_('Sleeping for 1 second...').'<br />';
       
evo_flush();
       
sleep( 1 );
    }
}

/**
 * Resize all images in media folder
 */
function tool_resize_all_images()
{
    global
$Session, $Settings, $media_path;
   
$params = array(
           
'inc_files'      => true,  // include files (not only directories)
           
'inc_dirs'       => false,  // include directories (not the directory itself!)
           
'flat'           => true,  // return a one-dimension-array
           
'recurse'        => true,  // recurse into subdirectories
           
'basename'       => false, // get the basename only
           
'trailing_slash' => false, // add trailing slash
           
'inc_hidden'     => true,  // inlcude hidden files, directories and content
           
'inc_evocache'   => true, // exclude evocache directories and content
           
'inc_temp'       => false,  // include temporary files and directories
   
);

   
$Session->assert_received_crumb( 'tools' );

   
load_funcs( 'files/model/_image.funcs.php' );
   
$Timer = new Timer('resize_all_images');

   
$Timer->start( 'resize_all_images' );
   
$filenames = get_filenames( $media_path, $params );
   
$fit_width = $Settings->get( 'fm_resize_width' );
   
$fit_height = $Settings->get( 'fm_resize_height' );
   
$file_counter = 0;

   
print_log( T_('Resize images...'), 'normal', array( 'text_style' => 'bold' ) );
    echo
'<br />';

    foreach(
$filenames as $filename )
    {
       
$filename = str_replace( $media_path, '', $filename );
       
$edited_File = & get_file_by_abspath( $filename );
        if( ! empty(
$edited_File ) && $edited_File->is_image() )
        {
           
$current_dimensions = $edited_File->get_image_size( 'widthheight_assoc' );
           
$new_dimensions = fit_into_constraint( $current_dimensions['width'], $current_dimensions['height'], $fit_width, $fit_height );
           
$result = resize_image( $edited_File, ( int ) $new_dimensions[0], ( int ) $new_dimensions[1], NULL, NULL, false );
            if(
$result )
            {
               
print_log( sprintf( T_('%s was resized to %dx%d pixels.'), '<code>'.$filename.'</code>', $new_dimensions[0], $new_dimensions[1] ) );
            }
            else
            {
               
print_log( sprintf( T_('%s could not be resized to target resolution of %dx%d pixels.'), '<code>'.$filename.'</code>', $new_dimensions[0], $new_dimensions[1] ), 'error' );
            }
           
$file_counter++;
        }
    }
   
$Timer->stop( 'resize_all_images' );
    echo
'<br />';
   
print_log( sprintf( T_('%d images were processed.'), $file_counter ), 'success' );
   
print_log( sprintf( T_('Full execution time: %s seconds'), $Timer->get_duration( 'resize_all_images' ) ), 'normal', array( 'text_style' => 'bold' ) );
}
?>