public function delete($delete_related_content = true) { global $DB; set_time_limit(300); if (!empty($this->id)) { if ($delete_related_content) { // delete all content related to the website // EXCEPTION: webusers, as they may be shared between websites $tables = array('nv_comments', 'nv_extensions', 'nv_notes', 'nv_paths', 'nv_properties', 'nv_properties_items', 'nv_templates', 'nv_webuser_votes', 'nv_webuser_favorites', 'nv_blocks', 'nv_items', 'nv_feeds', 'nv_structure', 'nv_webdictionary', 'nv_webdictionary_history', 'nv_backups', 'nv_files'); foreach ($tables as $table) { $DB->execute(' DELETE FROM ' . $table . ' WHERE website = ' . intval($this->id) . ' '); } // finally, remove ALL files associated to the website // including: images, documents, thumbnails, backups, cache, custom templates... core_remove_folder(NAVIGATE_PRIVATE . '/' . $this->id); } // finally delete the website entry $DB->execute(' DELETE FROM nv_websites WHERE id = ' . intval($this->id) . ' LIMIT 1 '); } // if allowed, send statistics to navigatecms.com if (NAVIGATECMS_STATS) { global $user; @core_curl_post('http://statistics.navigatecms.com/website/remove', array('name' => $this->name, 'ip' => $_SERVER['SERVER_ADDR'], 'website_id' => $this->id, 'url' => $this->absolute_path(), 'folder' => $this->folder, 'word_separator' => $this->word_separator, 'homepage' => $this->homepage, 'theme' => $this->theme, 'emails' => serialize($this->contact_emails), 'languages' => serialize($this->languages_published), 'permission' => $this->permission, 'author_name' => $user->username, 'author_email' => $user->email, 'author_language' => $user->language), NULL, 10, 'post'); } return $DB->get_affected_rows(); }
public function delete() { global $DB; global $user; $ok = false; if ($user->permission("themes.delete") == "false") { throw new Exception(t(610, "Sorry, you are not allowed to execute this function.")); } if (file_exists(NAVIGATE_PATH . '/plugins/' . $this->code . '/' . $this->code . '.plugin')) { core_remove_folder(NAVIGATE_PATH . '/plugins/' . $this->code); $ok = $DB->execute(' DELETE FROM nv_extensions WHERE id = ' . protect($this->id)); } return $ok; }
public function import_sample($ws = null) { global $DB; global $website; global $theme; global $events; if (is_null($ws)) { $ws = $website; } if (!file_exists(NAVIGATE_PATH . '/themes/' . $this->name . '/' . $this->name . '_sample.zip')) { throw new Exception(t(56, 'Unexpected error')); } $ptf = NAVIGATE_PRIVATE . '/tmp/' . $this->name . '_sample'; core_remove_folder($ptf); // decompress the zip file $extracted = false; $zip = new ZipArchive(); if ($zip->open(NAVIGATE_PATH . '/themes/' . $this->name . '/' . $this->name . '_sample.zip') === TRUE) { @mkdir($ptf, 0777, true); $extracted = $zip->extractTo($ptf); if (!$extracted) { throw new Exception(t(56, 'Unexpected error')); } $zip->close(); } // website languages (add website included languages) if (file_exists($ptf . '/languages.var_export')) { eval('$wlangs = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/languages.var_export')) . ';'); } else { $wlangs = unserialize(file_get_contents($ptf . '/languages.serialized')); } if (!is_array($wlangs)) { $wlangs = array(); } foreach ($wlangs as $lcode => $loptions) { if (!is_array($ws->languages) || !in_array($lcode, array_keys($ws->languages))) { $ws->languages[$lcode] = $loptions; } } // theme options if (file_exists($ptf . '/theme_options.var_export')) { eval('$toptions = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/theme_options.var_export')) . ';'); } else { $toptions = unserialize(file_get_contents($ptf . '/theme_options.serialized')); } $ws->theme_options = $toptions; $ws->save(); // folders (if available) $theme_files_parent = file::create_folder($this->name, "folder/generic", 0, $ws->id); $folders = array(); if (file_exists($ptf . '/folders.var_export')) { // available since v2.1.2 eval('$folders_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/folders.var_export')) . ';'); } if (!empty($folders_or)) { // assume folders are defined in order (first the parents, then their children) foreach ($folders_or as $f) { // error protection if (empty($f->id)) { continue; } $folders[$f->id] = new file(); $folders[$f->id]->load_from_resultset(array($f)); $folders[$f->id]->id = 0; $folders[$f->id]->website = $ws->id; if (isset($folders[$f->parent])) { $folders[$f->id]->parent = $folders[$f->parent]->id; } else { $folders[$f->id]->parent = $theme_files_parent; } $folders[$f->id]->insert(); } } // files $files = array(); if (file_exists($ptf . '/files.var_export')) { eval('$files_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/files.var_export')) . ';'); } else { $files_or = unserialize(file_get_contents($ptf . '/files.serialized')); } foreach ($files_or as $f) { // error protection if (empty($f->id)) { continue; } $files[$f->id] = new file(); $files[$f->id]->load_from_resultset(array($f)); $files[$f->id]->id = 0; $files[$f->id]->website = $ws->id; if (isset($folders[$f->parent])) { $files[$f->id]->parent = $folders[$f->parent]->id; } else { $files[$f->id]->parent = $theme_files_parent; } $files[$f->id]->insert(); // finally copy the sample file @copy($ptf . '/files/' . $f->id, NAVIGATE_PRIVATE . '/' . $ws->id . '/files/' . $files[$f->id]->id); } // structure $structure = array(); if (file_exists($ptf . '/structure.var_export')) { eval('$structure_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/structure.var_export')) . ';'); } else { $structure_or = unserialize(file_get_contents($ptf . '/structure.serialized')); } // hide existing structure entries $DB->execute(' UPDATE nv_structure SET permission = 2, visible = 0 WHERE website = ' . $ws->id); // we need to insert the old categories in order, in other words, the parents before its children // so to make things easy, we loop until we have no more categories to insert // this could lead to an infinite loop, so we have to add a simple protection $structure_categories_or = $structure_or; $changes = true; while (!empty($structure_categories_or) && $changes) { $changes = false; foreach ($structure_categories_or as $si => $category) { if (empty($category)) { continue; } $old_category_id = $category->id; $category->id = 0; $category->website = $ws->id; if ($category->parent > 0 && !isset($structure[$category->parent])) { // this structure entry needs a parent category that's not yet inserted // ignore the current entry until the next loop continue; } // if this category has a parent != root, update the parent id with the new value given if ($category->parent > 0) { $category->parent = $structure[$category->parent]->id; } $category->insert(); $changes = true; $structure[$old_category_id] = $category; unset($structure_categories_or[$si]); } $structure_categories_or = array_filter($structure_categories_or); } // elements $items = array(); if (file_exists($ptf . '/items.var_export')) { eval('$items_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/items.var_export')) . ';'); } else { $items_or = unserialize(file_get_contents($ptf . '/items.serialized')); } foreach ($items_or as $item) { // error protection if (empty($item->id)) { continue; } $old_item_id = $item->id; $item->id = 0; $item->website = $ws->id; // if this category has a parent != root, update the parent id with the new value given if ($item->category > 0) { $item->category = $structure[$item->category]->id; } $item->dictionary = theme::import_sample_parse_dictionary($item->dictionary, $files, $ws); // gallery images (correct FILE ids) if (!empty($item->galleries)) { $ngallery = array(); foreach ($item->galleries as $gid => $gallery) { foreach ($gallery as $fid => $caption) { $ngallery[$files[$fid]->id] = $caption; } $item->galleries[$gid] = $ngallery; } } $item->insert(); $items[$old_item_id] = $item; } // blocks $blocks = array(); if (file_exists($ptf . '/blocks.var_export')) { eval('$blocks_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/blocks.var_export')) . ';'); } else { $blocks_or = mb_unserialize(file_get_contents($ptf . '/blocks.serialized')); } if (!is_array($blocks_or)) { $blocks_or = array(); } foreach ($blocks_or as $block) { // error protection if (empty($block->id)) { continue; } $old_block_id = $block->id; $block->id = 0; $block->website = $ws->id; // update structure entries (if used) if (!empty($block->categories)) { for ($bc = 0; $bc < count($block->categories); $bc++) { $block->categories[$bc] = $structure[$block->categories[$bc]]->id; } } // update Actions (file/image) if (is_array($block->action['action-file'])) { foreach ($block->action['action-file'] as $lang => $file) { $block->action['action-file'][$lang] = $files[$file]->id; } } if (is_array($block->action['action-image'])) { foreach (@$block->action['action-image'] as $lang => $file) { $block->action['action-image'][$lang] = $files[$file]->id; } } // update Triggers (image/rolloverimage/flash/content/html) if (is_array($block->trigger['trigger-image'])) { foreach (@$block->trigger['trigger-image'] as $lang => $file) { $block->trigger['trigger-image'][$lang] = $files[$file]->id; } } if (is_array($block->trigger['trigger-rollover'])) { foreach (@$block->trigger['trigger-rollover'] as $lang => $file) { $block->trigger['trigger-rollover'][$lang] = $files[$file]->id; } } if (is_array($block->trigger['trigger-rollover-active'])) { foreach (@$block->trigger['trigger-rollover-active'] as $lang => $file) { $block->trigger['trigger-rollover'][$lang] = $files[$file]->id; } } if (is_array($block->trigger['trigger-flash'])) { foreach (@$block->trigger['trigger-flash'] as $lang => $file) { $block->trigger['trigger-flash'][$lang] = $files[$file]->id; } } $block->trigger['trigger-content'] = theme::import_sample_parse_array($block->trigger['trigger-content'], $files, $ws); $block->trigger['trigger-html'] = theme::import_sample_parse_array($block->trigger['trigger-html'], $files, $ws); $block->dictionary = theme::import_sample_parse_dictionary($block->dictionary, $files, $ws); // translate nv:// urls, which may be in: // trigger->[trigger-links][lang][link][code] => link // trigger->[trigger-content][lang] (as html code) // trigger->[trigger-html][lang] (as html code) // action->[action-web][lang] if (!empty($block->trigger['trigger-links'])) { foreach ($block->trigger['trigger-links'] as $lang => $block_trigger_link) { foreach ($block_trigger_link['link'] as $btl_code => $btl_link) { $btl_link = theme::import_sample_translate_nv_urls($btl_link, $structure, $items); $block->trigger['trigger-links'][$lang]['link'][$btl_code] = $btl_link; } } } if (!empty($block->trigger['trigger-content'])) { foreach ($block->trigger['trigger-content'] as $lang => $block_trigger_content) { $block_trigger_content = theme::import_sample_translate_nv_urls($block_trigger_content, $structure, $items); $block->trigger['trigger-content'][$lang] = $block_trigger_content; } } if (!empty($block->trigger['trigger-html'])) { foreach ($block->trigger['trigger-html'] as $lang => $block_trigger_content) { $block_trigger_content = theme::import_sample_translate_nv_urls($block_trigger_content, $structure, $items); $block->trigger['trigger-html'][$lang] = $block_trigger_content; } } if (!empty($block->action['action-web'])) { foreach ($block->action['action-web'] as $lang => $block_action_web) { $block_action_web = theme::import_sample_translate_nv_urls($block_action_web, $structure, $items); $block->action['action-web'][$lang] = $block_action_web; } } $block->insert(); $blocks[$old_block_id] = $block; } // block_groups $block_groups = array(); if (file_exists($ptf . '/block_groups.var_export')) { eval('$block_groups_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/block_groups.var_export')) . ';'); } else { $block_groups_or = unserialize(file_get_contents($ptf . '/block_groups.serialized')); } foreach ($block_groups_or as $block_group) { // error protection if (empty($block_group->id)) { continue; } $old_block_group_id = $block_group->id; $block_group->id = 0; $block_group->website = $ws->id; // fix block IDs in group $new_selection = array(); for ($bi = 0; $bi < count($block_group->blocks); $bi++) { if ($block_group->blocks[$bi]['type'] == 'block') { $block_group->blocks[$bi]['id'] = $blocks[$block_group->blocks[$bi]['id']]->id; } $new_selection[] = $block_group->blocks[$bi]; } $block_group->blocks = $new_selection; $block_group->insert(); $block_groups[$old_block_group_id] = $block_group; } // comments if (file_exists($ptf . '/comments.var_export')) { eval('$comments_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/comments.var_export')) . ';'); } else { $comments_or = unserialize(file_get_contents($ptf . '/comments.serialized')); } foreach ($comments_or as $comment) { if (empty($comment->item)) { continue; } $comment->id = 0; $comment->website = $ws->id; $comment->item = $items[$comment->item]->id; $comment->ip = ''; $comment->insert(); } // now that categories and elements have been inserted // we need to fix: // structure jumps: [jump-branch, jump-item] to its new ID values // items' sections: embedded nv:// urls // note: properties will be "translated" later // update structure properties foreach ($structure as $old_id => $entry) { foreach ($entry->dictionary as $elang => $properties) { if (!empty($properties['action-jump-item'])) { $entry->dictionary[$elang]['action-jump-item'] = $items[$properties['action-jump-item']]->id; } else { if (!empty($properties['action-jump-branch'])) { $entry->dictionary[$elang]['action-jump-branch'] = $structure[$properties['action-jump-branch']]->id; } } $entry->save(); } } // find & update items' sections nv:// urls foreach ($items as $old => $element) { foreach ($element->dictionary as $eld_lang => $eld_field) { foreach ($eld_field as $eld_field_key => $eld_field_val) { $html = theme::import_sample_translate_nv_urls($eld_field_val, $structure, $items); $items[$old]->dictionary[$eld_lang][$eld_field_key] = $html; } } $items[$old]->save(); } // translate website options; check for forced multilanguage options! $theme_options = array(); for ($toi = 0; $toi < count($theme->options); $toi++) { $to = $theme->options[$toi]; $to->value = $ws->theme_options->{$to->id}; switch ($to->type) { case 'file': case 'image': // is multi-language forced for this option? if (in_array($to->multilanguage, array('true', '1'))) { foreach ($to->value as $olang => $oval) { if (isset($files[$oval]->id)) { $to->value[$olang] = $files[$oval]->id; } } } else { if (isset($files[$to->value]->id)) { $to->value = $files[$to->value]->id; } } break; case 'category': // is multi-language forced for this option? if (in_array($to->multilanguage, array('true', '1'))) { foreach ($to->value as $olang => $oval) { if (isset($structure[$oval]->id)) { $to->value[$olang] = $structure[$oval]->id; } } } else { if (isset($structure[$to->value]->id)) { $to->value = $structure[$to->value]->id; } } break; case 'element': // is multi-language forced for this option? if (in_array($to->multilanguage, array('true', '1'))) { foreach ($to->value as $olang => $oval) { if (isset($items[$oval]->id)) { $to->value[$olang] = $items[$oval]->id; } } } else { if (isset($items[$to->value]->id)) { $to->value = $items[$to->value]->id; } } break; case 'categories': // is multi-language forced for this option? if (in_array($to->multilanguage, array('true', '1'))) { foreach ($to->value as $olang => $oval) { $property_categories_old = explode(',', $oval); $property_categories_new = array(); foreach ($property_categories_old as $oc) { $property_categories_new[] = $structure[$oc]->id; } $to->value[$olang] = implode(',', $property_categories_new); } } else { $property_categories_old = explode(',', $to->value); $property_categories_new = array(); foreach ($property_categories_old as $oc) { $property_categories_new[] = $structure[$oc]->id; } $to->value = implode(',', $property_categories_new); } break; default: // we don't need to change this type of value } // convert theme option definition to website option value $theme_options[$to->id] = $to->value; } $ws->theme_options = $theme_options; $ws->save(); // properties // array ('structure' => ..., 'item' => ..., 'block' => ...) if (file_exists($ptf . '/properties.var_export')) { eval('$properties = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/properties.var_export')) . ';'); } else { $properties = unserialize(file_get_contents($ptf . '/properties.serialized')); } $elements_with_properties = array('structure', 'item', 'block', 'block_group_block'); foreach ($elements_with_properties as $el) { if ($el == 'structure') { $real = $structure; } else { if ($el == 'item') { $real = $items; } else { if ($el == 'block') { $real = $blocks; } else { if ($el == 'block_group_block') { $real = $block_groups; } else { continue; } } } } // unrecognized element type, ignore if (!is_array($properties[$el])) { continue; } foreach ($properties[$el] as $el_id => $el_properties) { if (empty($el_properties)) { continue; } $item_uid = ""; if ($el == 'block_group_block') { // find each assigned block UID reference in this block group block foreach ($el_properties as $item_uid => $el_properties_bg) { theme::import_sample_properties($ws, $el_properties_bg, $el, $files, $structure, $items, $real, $el_id, $item_uid); } } else { theme::import_sample_properties($ws, $el_properties, $el, $files, $structure, $items, $real, $el_id, $item_uid); } } } // apply final settings from export if (file_exists($ptf . '/settings.var_export')) { eval('$settings_or = ' . str_replace("stdClass::__set_state", "(object)", file_get_contents($ptf . '/settings.var_export')) . ';'); } else { // get first structure ID $structure_id = array_keys($structure); $structure_id = $structure_id[0]; $settings_or = array('homepage' => $structure_id); } if (!empty($settings_or['favicon'])) { $ws->favicon = $files[$settings_or['favicon']]->id; } // what is the homepage? if (is_numeric($settings_or['homepage'])) { // homepage as a category ID $ws->homepage = $structure[$settings_or['homepage']]->id; } else { // homepage as a path $ws->homepage = $settings_or['homepage']; } $ws->save(); core_remove_folder($ptf); }
public static function install_from_file($version, $revision, $ufile, $ulog) { global $DB; // remove old update files (will be there if a previous update fails) file_put_contents($ulog, "remove old update folder\n", FILE_APPEND); core_remove_folder(NAVIGATE_PATH . '/updates/update'); // decompress file_put_contents($ulog, "create new folder\n", FILE_APPEND); mkdir(NAVIGATE_PATH . '/updates/update'); $zip = new ZipArchive(); file_put_contents($ulog, "open zip file\n", FILE_APPEND); if ($zip->open($ufile) === TRUE) { file_put_contents($ulog, "extract zip file\n", FILE_APPEND); $zip->extractTo(NAVIGATE_PATH . '/updates/update'); $zip->close(); } else { file_put_contents($ulog, "zip extraction failed\n", FILE_APPEND); @unlink($ufile); core_remove_folder(NAVIGATE_PATH . '/updates/update'); return false; } // chmod files (may fail, but not fatal error) file_put_contents($ulog, "chmod update (may fail in Windows)... ", FILE_APPEND); $chmod_status = core_chmodr(NAVIGATE_PATH . '/updates/update', 0755); file_put_contents($ulog, $chmod_status . "\n", FILE_APPEND); // do file changes file_put_contents($ulog, "parse file changes\n", FILE_APPEND); $hgchanges = file_get_contents(NAVIGATE_PATH . '/updates/update/changes.txt'); $hgchanges = explode("\n", $hgchanges); foreach ($hgchanges as $change) { file_put_contents($ulog, $change . "\n", FILE_APPEND); $change = trim($change); if (empty($change)) { continue; } $change = explode(" ", $change, 2); // new, removed and modified files // M = modified // A = added // R = removed // C = clean // ! = missing (deleted by non-hg command, but still tracked) // ? = not tracked // I = ignored // = origin of the previous file listed as A (added) $file = str_replace('\\', '/', $change[1]); //if(substr($file, 0, strlen('plugins/'))=='plugins/') continue; if (substr($file, 0, strlen('setup/')) == 'setup/') { continue; } switch ($change[0]) { case 'A': // added a new file // added a new file case 'M': // modified file if (!file_exists(NAVIGATE_PATH . '/updates/update/' . $file)) { file_put_contents($ulog, "file doesn't exist!\n", FILE_APPEND); return false; } @mkdir(dirname(NAVIGATE_PATH . '/' . $file), 0777, true); if (!@copy(NAVIGATE_PATH . '/updates/update/' . $file, NAVIGATE_PATH . '/' . $file)) { file_put_contents($ulog, "cannot copy file!\n", FILE_APPEND); return false; } break; case 'R': // remove file @unlink(NAVIGATE_PATH . '/' . $file); break; default: // all other cases // IGNORE the change, as we are now only getting the modified files } } // process SQL updates file_put_contents($ulog, "process sql update\n", FILE_APPEND); if (file_exists(NAVIGATE_PATH . '/updates/update/update.sql')) { $sql = file_get_contents(NAVIGATE_PATH . '/updates/update/update.sql'); // execute SQL in a transaction // http://php.net/manual/en/pdo.transactions.php try { // can't do it in one step => SQLSTATE[HY000]: General error: 2014 $sql = explode("\n\n", $sql); //file_put_contents($ulog, "begin transaction\n", FILE_APPEND); //$DB->beginTransaction(); foreach ($sql as $sqlline) { $sqlline = trim($sqlline); if (empty($sqlline)) { continue; } file_put_contents($ulog, "execute sql:\n" . $sqlline . "\n", FILE_APPEND); if (!$DB->execute($sqlline)) { file_put_contents($ulog, "execute failed: " . $DB->get_last_error() . "\n", FILE_APPEND); //throw new Exception($DB->get_last_error()); } // force commit changes (slower but safer... no --> SQLSTATE[HY000]: General error: 2014) $DB->disconnect(); $DB->connect(); } //file_put_contents($ulog, "commit transaction\n", FILE_APPEND); //$DB->commit(); } catch (Exception $e) { file_put_contents($ulog, "transaction error: \n" . $e->getMessage() . "\n", FILE_APPEND); //$DB->rollBack(); return false; } } else { file_put_contents($ulog, "no SQL found\n", FILE_APPEND); } // add the update row to know which navigate revision is currently installed file_put_contents($ulog, "insert new version row on updates\n", FILE_APPEND); $urow = new update(); $urow->id = 0; $urow->version = $version; $urow->revision = $revision; $urow->date_updated = time(); $urow->status = 'ok'; $urow->changelog = ''; try { $ok = $urow->insert(); } catch (Exception $e) { $error = $e->getMessage(); } if ($error) { file_put_contents($ulog, "execute insert failed:\n" . $DB->get_last_error() . "\n", FILE_APPEND); } if (file_exists(NAVIGATE_PATH . '/updates/update/update-post.php')) { include_once NAVIGATE_PATH . '/updates/update/update-post.php'; } file_put_contents($ulog, "update finished!\n", FILE_APPEND); $urow->changelog = file_get_contents($ulog); $urow->save(); @unlink($ufile); update::cache_clean(); return true; }
/** * Removes a folder on the disk and its subfolders * * @param string $dir Path of the folder to remove */ function core_remove_folder($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (filetype($dir . "/" . $object) == "dir") { core_remove_folder($dir . "/" . $object); } else { unlink($dir . "/" . $object); } } } reset($objects); rmdir($dir); } }