<?php
/*
dv at josheli.com
2/10/2004

Script to redefine or "re-theme" client cpanels
Requires cURL extension
Not tested on large resellers; may time-out if run from a browser
I've tested it on my WHM setup, but PLEASE test it on yours before using fully!

NO WARRANTY, GUARANTEE, RESPONSIBILITY ASSUMED BY THE AUTHOR
USE AT YOUR OWN RISK :)
*/

/*** BEGIN CONFIG ***/

$reseller 'www.mydomain.com';//your reseller url
$whmUser 'username';//your web host manager user name
$whmPass 'password';//your web host manager password
$logEchoNone 'echo';//write a log to 'log'(file) or 'echo'(browser or cli) or 'none'(no log)
$logFileName 'retheme_log.txt';//can include a path too; only makes sense if $logEchoNone = 'log'
$useSsl true;
$changeLang true;//change the language to EnglishCP as well? this is required for the new themes
/*
A comma-separated list of domain names on which to change the themes;
Leave blank to change all applicable domains
If not blank, ONLY the domains listed will be checked/changed.
If listed, the domains must be listed EXACTLY like they appear on the
list accounts page in WHM, i.e. usually without 'www.'
$domains = 'example1.com,example2.net';
*/
$domains '';

/*** END CONFIG ***/

/*
You can change these if you want. Format is:
'oldtheme' => 'new_theme'
*/
$themes = array(
'bluetrix' =>'blue_trix'
'redtrix'=> 'red_trix'
'babysim' =>'sim_skins'
'bluesim' =>'sim_skins'
'graysim' =>'sim_skins'
'redsim' =>'sim_skins'
);

/*** BEGIN MAIN ***/

set_time_limit(0);
$time_start getMicroTime();

if (!
extension_loaded('curl')) {
  
dl('php_curl.' .PHP_SHLIB_SUFFIX) or die("Could not load curl extension");
}
if(
$useSsl) {
  
$protocol 'https://';
  
$cpPort '2083';
  
$whmPort '2087';
  
writeLog("Using SSL.\n");
}
else {
  
$protocol 'http://';
  
$cpPort '2082';
  
$whmPort '2086';
  
writeLog("Not using SSL.\n");


$domains trim($domains);
if(!empty(
$domains)){
  
$chkDoms true;
  
$domains explode(',',$domains);
  foreach(
$domains as $d){
    
$domains[] = trim($d);
  }
}
else {
  
$chkDoms false;
  
$domains = array();
}

//get the WHM 'list accounts' page
writeLog("Retrieving WHM accounts page...\n");
$acctsPage getByCurl("$protocol$reseller:$whmPort/scripts2/listaccts?viewall=1",$whmUser,$whmPass);
//get each accounts table row
$int2 preg_match_all("/<tr class=(?:tdshade2|tdshade1)>(.*?)<\/tr>/is"$acctsPage$matches);

$accounts = array();
if(
$int2 && is_array($matches[1])) { 
  
writeLog("Parsing accounts...\n");
  foreach(
$matches[1] as $match) {

    
$account = array();
    
$accDom '';
    
$accUser '';
    
$accTheme '';

    
$account explode('</td><td>',$match);
    
$accDom strip_tags(trim($account[0]));//domain
    
if($chkDoms)
      if(!
in_array($accDom,$domains)) continue;
    
$accUser strip_tags(trim($account[2]));//username
    
$accTheme strip_tags(trim($account[9]));//current theme

    
if(in_array($accTheme,array_keys($themes))){
      
$accounts[$accUser] = $accTheme;//$accDom~|~
    
}
  }
}

if(!empty(
$accounts)){
  
writeLog('Found '.count($accounts)." accounts with old themes.\n");
  foreach(
$accounts as $user => $theme){
    
writeLog("Retrieving modification page for $user ...\n");
    
$initUrl "$protocol$reseller:$whmPort/scripts/edituser?domain=$user&user=$user&submit-domain=Edit";
    
$editPage getByCurl($initUrl,$whmUser,$whmPass);

    
//get input form values
    
$fields preg_match_all('/<input type=(?:hidden|text) name=(.*?) value=(.*?)>/i',$editPage,$formMatches);
    if(
$fields && is_array($formMatches[1]) && (count($formMatches[1]) == count($formMatches[2]))){
      
//build edit URL
      
$editUrl "$protocol$reseller:$whmPort/scripts/saveedituser?";
      foreach(
$formMatches[1] as $num => $name){
        
$name trim(str_replace(array('"','"'),'',$name));
        
$val trim(str_replace(array('"','"'),'',$formMatches[2][$num]));
        
$editUrl .= $name.'='.$val.'&';
        if(
strpos($name,'DNS')!==false$domain $val;
      }
      
$editUrl .= 'RS='.$themes[$theme];
      if(
$changeLang$editUrl .= '&LANG=EnglishCP';
      else 
$editUrl .= '&LANG=english';
      
//echo $editUrl."\n";
      
writeLog("Changing $domain from $theme to {$themes[$theme]} ...\n");
      
$finalPage =  getByCurl($editUrl,$whmUser,$whmPass,array('CURLOPT_REFERER'=>$initUrl));
      if(
preg_match('/<pre>(.*?)<\/pre>/ism',$finalPage,$response)){
        if(
strpos($response[1],'RS='.$themes[$theme])!==false) {
          
writeLog("Successfully changed theme to $themes[$theme].\n");
        }
        if(
$changeLang && strpos($response[1],'LANG=EnglishCP')!==false) {
          
writeLog("Successfully changed language to EnglishCP.\n");
        }
      }
      else {
        
writeLog("No repsonse from server\n");
      }
    }
    else {
      
writeLog("Could not parse modification page.\n");
    }
  }
}
else {
  
writeLog("There were no accounts with outdated themes.\n");
}

$time_end getMicroTime();
$time $time_end $time_start;

writeLog("Elapsed time: ".round($time,2)." seconds.\n");

/*** END MAIN ***/


/*** BEGIN FUNCTIONS ***/

function getByCurl($url$user ''$pass '',$extra '') {
  global 
$useSsl;

  
$ch curl_init(); 
  
//tells curl to save result in a variable instead of outputing to page
  
curl_setopt($chCURLOPT_RETURNTRANSFER1);
  
curl_setopt($chCURLOPT_URL$url);  
  
curl_setopt($chCURLOPT_USERPWD"$user:$pass");
  
curl_setopt ($chCURLOPT_COOKIEJAR'./cookie.txt');
  
curl_setopt ($chCURLOPT_FOLLOWLOCATION,1);
  if(!empty(
$extra) && is_array($extra)){
    foreach(
$extra as $opt=>$val){
      switch(
$opt){
        case 
'CURLOPT_REFERER':
          
curl_setopt($ch,CURLOPT_REFERER,$val);
        break;
      }
    }
  }
  if(
$useSsl){
    
curl_setopt ($chCURLOPT_SSL_VERIFYPEER0);
    
curl_setopt ($chCURLOPT_SSL_VERIFYHOST0);
  }
  
$result curl_exec($ch);
  
curl_close($ch);

  return 
$result;
}

function 
writeLog($entry) {
  global 
$logEchoNone,$logFileName;

  
$method strtolower($logEchoNone);

  
$entry date('r').' - '.$entry;
  
  if(
$method == 'log') {
    
$fp fopen($logFileName,'ab');
  }
  elseif(
$method == 'echo'){
    if(isset(
$_SERVER['REQUEST_METHOD'])) {
      echo 
nl2br($entry);//browser
      
flush();
      return;
    }
    else {
      
$fp STDOUT;//cli
    
}
  }
  else {
    return;
  }
  
  
fwrite($fp$entry);

  if(
$method == 'log')
    
fclose($fp);

  return;
}

function 
getMicroTime(){ 
  list(
$usec$sec) = explode(" ",microtime()); 
  return ((float)
$usec + (float)$sec); 

?>