open($filename);
$this->user = $this->query('SELECT username, language, created, last_login, preferences FROM users');
}
public function hasUserData()
{
return (bool)$this->user;
}
public function userData()
{
return $this->user->fetchArray(SQLITE3_ASSOC);
}
public function contacts()
{
$result = $this->query('SELECT contact_id, email, name, changed, firstname, surname, vcard, words FROM contacts');
$contacts = [];
if ($result)
{
while($contact = $result->fetchArray(SQLITE3_ASSOC))
{
array_push($contacts, $contact);
}
}
return $contacts;
}
public function identities()
{
$identities = [];
$result = $this->query('SELECT email, standard, name, changed, organization, "reply-to", bcc, signature, html_signature from identities');
if ($result) {
while ($identity = $result->fetchArray(SQLITE3_ASSOC))
{
array_push($identities, $identity);
}
}
return $identities;
}
public function getContactGroups($contact_id)
{
$groups = [];
$result = $this->query("
SELECT cg.name, cg.changed, cm.created
FROM contactgroupmembers cm
LEFT JOIN contactgroups cg ON cm.contactgroup_id = cg.contactgroup_id
WHERE cm.contact_id = $contact_id
");
if ($result) {
while ($row = $result->fetchArray(SQLITE3_ASSOC))
{
array_push($groups, $row);
}
}
return $groups;
}
}
class RoundcubeDBList
{
public function __construct()
{
$this->list = [];
$this->xml = new SimpleXMLElement("");
}
public function push($db)
{
$this->list[] = $db;
}
private function assocToXml($el, $assocArray)
{
if ($assocArray) {
foreach($assocArray as $key => $value) {
$el->addChild(strtoupper($key), urlencode($value));
}
}
}
private function buildXML()
{
foreach($this->list as $db) {
$this->insertEmail($db);
}
return $this->xml;
}
public function hasEmails()
{
return (count($this->list) > 0);
}
private function insertEmail($db)
{
$el = $this->xml->addChild('EMAIL');
$this->assocToXML($el, $db->userData());
$identities_el = $el->addChild('INDENTITIES');
foreach($db->identities() as $identity)
{
$this->assocToXML(
$identities_el->addChild('INDENTITY'),
$identity
);
}
$contacts_el = $el->addChild('CONTACTS');
foreach($db->contacts() as $contact)
{
$contact_id = $contact['contact_id'];
unset($contact['contact_id']);
$contact_el = $contacts_el->addChild('CONTACT');
$this->assocToXML($contact_el, $contact);
$groups_el = $contact_el->addChild('GROUPS');
foreach ($db->getContactGroups($contact_id) as $group) {
$this->assocToXML($groups_el->addChild('GROUP'), $group);
}
}
}
public function getXML()
{
$domxml = dom_import_simplexml($this->buildXML());
return $domxml->ownerDocument->saveXML($domxml->ownerDocument->documentElement);
}
public function saveXML($filename)
{
$xmlpath = dirname($filename);
if(!file_exists($xmlpath))
{
if (!mkdir($xmlpath, 0777, true))
{
die("Unable to create XML path: $xmlpath. Unable to backup RoundCube data");
};
}
if (!file_put_contents($filename, $this->getXML()))
{
die("Unable to open $filename for writing. Unable to backup RoundCube data");
}
echo "Backup saved.\n";
}
}
function processArguments($argv) {
$arguments = [
'output' => false,
'pattern' => false,
'files' => [],
];
foreach(array_slice($argv, 1) as $argument)
{
if (preg_match('/^--(?P\w+)=(?P.*)$/',$argument, $matches))
{
$arguments[$matches['arg']] = $matches['value'];
} else {
array_push($arguments['files'], $argument);
}
}
if ($arguments['pattern']) { // pattern given, merging results to files list
$matchedFiles = glob($arguments['pattern']);
if ($matchedFiles === FALSE) {
// Glob experienced error ()
echo "WARN: glob matching failed";
$matchedFiles = []; // mimic no matched files behavior and continue
}
$arguments['files'] = array_unique(
array_merge(
$arguments['files'],
$matchedFiles
)
);
unset($arguments['pattern']);
}
return $arguments;
}
// Start Process
$arguments = processArguments($argv);
if (count($arguments['files']) === 0 || !$arguments['output'])
{
echo "Usage: php cpanel_sqlite_da_roundcube.php --output=/root/output.xml --pattern=/root/backup/homedir/etc/domain.com/*.rcube.db\n";
echo "Usage: php cpanel_sqlite_da_roundcube.php --output=/root/output.xml info.rcube.db support.rcube.db\n";
exit();
}
echo "Generating ".$arguments['output']."...\n";
$files = [];
foreach ($arguments['files'] as $file)
{
if (file_exists($file)) {
array_push($files, $file);
}
else {
echo "WARN: File $file does not exists, skipping it...\n";
}
}
if (count($files) > 0)
{
$db_list = new RoundcubeDBList();
foreach ($files as $file)
{
$db = new RoundcubeDB($file);
if ($db->hasUserData()) {
$db_list->push($db);
}
}
if ($db_list->hasEmails())
{
$db_list->saveXML($arguments['output']);
}
else {
echo "WARN: no emails in given files, no xml file produced";
exit();
}
}
else
{
echo "WARN: no files given, no xml file produced";
exit();
}
?>