1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Repeat of entry

Discussion in 'XenForo Development Discussions' started by Mythotical, Jan 15, 2012.

  1. Mythotical

    Mythotical Well-Known Member

    I am attempting to take a post count, multiply it, divide it, etc then insert that new total into a separate table.

    Here is a screenshot: http://gyazo.com/0c51285871b289a9eca7f335e740f7ef

    Steve - Has over 2k posts
    Test - Has 0 posts

    Therefore lifetime and total points for Test should be 0 no matter what. But the points from Steve keep getting inserted under each username.

    Soooo now my code, hope you can make heads or tails of it as I have commented out lines, I don't like to delete lines until I'm done with that feature.

    PHP:
    <?php

    class xShop_ControllerAdmin_Index_Convert extends XenForo_ControllerAdmin_Abstract
    {
    //    Public $perms;

        
    public function actionIndex()
        {
            
    $options XenForo_Application::get('options');
            
    $db XenForo_Application::get('db');

            
    $xs_sub_total $db->fetchOne('
                SELECT COUNT(*) 
                FROM xf_user'
    );
            
        
    /*    $xs_total_left = $db->fetchAll('
                SELECT user.user_id, COUNT(*) AS pointcount
                FROM xf_user AS user
                LEFT JOIN xshop_points AS pts
                ON user.user_id = pts.user_id
                GROUP BY user.user_id');*/
            
            //$xs_insert_total = $xs_sub_total-$xs_total_left;

            
    $xs_subs $db->fetchAll('
                SELECT user_id, message_count
                FROM xf_user ORDER BY user_id DESC'
    );
                        
                foreach (
    $xs_subs AS $xs_sub)
                {
                    if(
    $xs_sub['message_count'] == '0'){
                        
    $new_point_total 0;
                    } else {
                    
    $new_point_total round($xs_sub['message_count']*$options->xshop_convert_rate/15*2-50);
                    }
                    
    $userid $xs_sub['user_id'];
                    
    //$this->_insertData($xs_sub, $points_insert, $new_point_total);
                
    }

                
    $viewParams = array(
                    
    'xs_sub_total' => $xs_sub_total,
                    
    'new_point_total' => $new_point_total,
                    
    'userid' => $userid,
                    
    //'xs_insert_total' => $xs_insert_total,
                    //'points_insert' => $points_insert,
                    
    'xs_sub' => $xs_sub
                
    );
            
            return 
    $this->responseView('xShop_ViewAdmin_Convert''xshop_convert'$viewParams);
        }

        public function 
    actionConversion()
        {
            
    $boardTotals $this->getModelFromCache('XenForo_Model_DataRegistry')->get('boardTotals');
            if (!
    $boardTotals)
            {
                
    $boardTotals $this->getModelFromCache('XenForo_Model_Counters')->rebuildBoardTotalsCounter();
            }
            
            
    $this->_assertPostOnly();
                
            
    $options XenForo_Application::get('options');
            
    $db XenForo_Application::get('db');

            
    $points_insert $this->_input->filter(array(
                
    'user_id' => XenForo_Input::UINT,
                
    'message_count' => XenForo_Input::UINT,
                
    'new_point_total' => XenForo_Input::UINT
            
    ));
            
            
    $lang $db->fetchAll('
                SELECT language_id
                FROM xf_language WHERE language_id = ?'
    1);
            
            
    $xs_sub_total $db->fetchOne('
                SELECT COUNT(*) 
                FROM xf_user'
    );
            
        
    /*    $xs_total_left = $db->fetchAll('
                SELECT user.user_id, COUNT(*) AS pointcount
                FROM xf_user AS user
                LEFT JOIN xshop_points AS pts
                ON user.user_id = pts.user_id
                GROUP BY user.user_id');*/
            
            //$xs_insert_total = $xs_sub_total-$xs_total_left;

            
    $page max(1$this->_input->filterSingle('page'XenForo_Input::UINT));
            
    $perPage 250;

            
    $xs_subs $db->fetchAll('
                SELECT user_id, message_count
                FROM xf_user ORDER BY user_id DESC'
    );
                        
            
    $xs_subss = array(
                
    'page' => $page,
                
    'perPage' => $perPage
            
    );

                foreach (
    $xs_subs AS $xs_sub)
                {
                    if(
    $xs_sub['message_count'] == '0'){
                        
    $new_point_total 0;
                    } else {
                    
    $new_point_total round($xs_sub['message_count']*$options->xshop_convert_rate/15*2-50);
                    }
                    
    $userid $xs_sub['user_id'];
                    
    $this->_insertData($xs_sub$points_insert$new_point_total);
                }

                
    $viewParams = array(
                    
    'xs_sub_total' => $xs_sub_total,
                    
    'new_point_total' => $new_point_total,
                    
    //'xs_insert_total' => $xs_insert_total,
                    
    'points_insert' => $points_insert,
                    
    'userid' => $userid,
                    
    'completed' => ($page 1) * $perPage count($xs_sub_total),
                    
    'nextPage' => $page 1,
                    
    'xs_sub' => $xs_sub,
                    
    'boardTotals' => $boardTotals
                
    );

            return 
    $this->responseView('xShop_ViewAdmin_ConvertConversion''xshop_converting'$viewParams);
        }        

        public function 
    _insertData(array $points_insert)
        {
            
    $this->_assertPostOnly();

            
    $dwInput $this->_input->filter(array(
                
    'points_id' => XenForo_Input::UINT,
                
    'user_id' => XenForo_Input::UINT,
                
    'points_total' => XenForo_Input::UINT,
                
    'points_earned' => XenForo_Input::UINT,
                
    'new' => XenForo_Input::UINT
            
    ));

            
    $dw XenForo_DataWriter::create('xShop_DataWriter_Convert');
            if (
    $dwInput['points_id'])
                
    $dw->setExistingData($dwInput['points_id']);
            
            
    $dw->set('points_id'$dwInput['points_id']);
            
    $dw->set('user_id'$points_insert['user_id']);
            
    $dw->set('points_total'$dwInput['new']);
            
    $dw->set('points_earned'$dwInput['new']);
            
    $dw->save();
            
            
    $redirectType = ($dwInput['points_id'] ?
                
    XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED :
                
    XenForo_ControllerResponse_Redirect::RESOURCE_CREATED);
                
            return 
    $this->responseRedirect(
                
    $redirectType,
                
    XenForo_Link::buildAdminLink('xshop/points')
            );
        }
    }
    xshop_convert template
    HTML:
    <xen:title>Conversion Tool</xen:title>
        <div class="selection">
            <h2 class="subHeading">Conversion</h2>
                <br />
                <p>You are about to perform a conversion process that will convert all current post counts to {$xenOptions.xshop_currency}. This process can only be ran once and will cause any points accumulated so far to get doubled. This process should be ran right after the install.</p>
                <br />
    {xen:raw $new_point_total}
                <br />
            <xen:include template="xshop_footer" />
            <xen:form action="{xen:adminlink xshop/convert/conversion}">        
                <input type="hidden" name="user_id" value="{$xs_subs.user_id}" />
                <input type="hidden" name="new" value="{$new_point_total}" />
                <input type="hidden" name="message_count" value="{$xs_subs.message_count} />
                <xen:submitunit save="Continue with Conversion?" />
            </xen:form>
        </div>
    
    <xen:require css="filter_list.css" />
    <xen:require js="js/xenforo/filter_list.js" />
    xshop_converting template
    HTML:
    <xen:title>Converting post count to {$xenOptions.xshop_currency}...</xen:title>
    
    <xen:form action="{xen:adminlink xshop/points}" id="conversionTool">
        
        <p>
            Converting users post count... {xen:number $completed} / {xen:number $xs_sub_total}
            <img src="@imagePath/widgets/ajaxload.info_000000_facebook.gif" alt="Loading..." id="loadingImage" style="display:none" />
        </p>
        <input type="submit" value="Continue" class="button primary" id="insertData" />
        
        <input type="hidden" name="page" value="{$nextPage}" />
            
        <input type="hidden" name="_xfConfirm" value="1" />
        
    </xen:form>
    
    <script type="text/javascript">
        $('#loadingImage').show();
    </script>
     
  2. Jake Bunce

    Jake Bunce XenForo Moderator Staff Member

    Your foreach loop is overwriting those vars at each iteration:

    Code:
                foreach ($xs_subs AS $xs_sub)
                {
                    if($xs_sub['message_count'] == '0'){
                        $new_point_total = 0;
                    } else {
                    $new_point_total = round($xs_sub['message_count']*$options->xshop_convert_rate/15*2-50);
                    }
                    $userid = $xs_sub['user_id'];
                    //$this->_insertData($xs_sub, $points_insert, $new_point_total);
                }
    
    That means those vars will contain the values for the last user that is processed by the foreach. You should use an array that is indexed by user_id, or even make $xs_sub a reference variable (foreach ($xs_subs AS &$xs_sub)) and then set a new index during the foreach.
     
  3. Mythotical

    Mythotical Well-Known Member

    The funny thing is that it inserts the userid's just fine. Aside from that, the method you mentioned I have never used. Do you have an in depth explanation or example?
     
  4. Mythotical

    Mythotical Well-Known Member

    EDIT: Apparently I don't so if you could give me an explanation or direct to me to some online documents that would help.
     
  5. Mythotical

    Mythotical Well-Known Member

    Ok I have officially broke the process. LOL now it won't insert nothing.
     
  6. Jake Bunce

    Jake Bunce XenForo Moderator Staff Member

    Example of foreach using reference parameter:

    XenForo_ControllerPublic_Thread::actionIndex

    Code:
    		foreach ($posts AS &$post)
    		{
    			$post['position_on_page'] = ++$pagePosition;
    
    			$postModOptions = $postModel->addInlineModOptionToPost(
    				$post, $thread, $forum, $permissions
    			);
    			$inlineModOptions += $postModOptions;
    
    			$post = $postModel->preparePost($post, $thread, $forum, $permissions);
    
    			if ($post['post_date'] > $maxPostDate)
    			{
    				$maxPostDate = $post['post_date'];
    			}
    
    			if ($post['isDeleted'])
    			{
    				$deletedPosts++;
    			}
    			if ($post['isModerated'])
    			{
    				$moderatedPosts++;
    			}
    
    			if (!$firstUnreadPostId && $post['isNew'])
    			{
    				$firstUnreadPostId = $post['post_id'];
    			}
    		}
    
    &$post is a reference, and it sets position_on_page for each post as the foreach iterates through $posts array.
     

Share This Page