diff --git a/interface/web/vcs/form/web_git.tform.php b/interface/web/vcs/form/web_git.tform.php
new file mode 100644
index 0000000000000000000000000000000000000000..e52efe9a06d24336f0d1bfd46252fc251bd1b9fb
--- /dev/null
+++ b/interface/web/vcs/form/web_git.tform.php
@@ -0,0 +1,179 @@
+ 0 id must match with id of current user
+$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user
+$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete
+
+
+//* Maybe we're writing in a response to another message
+$sm_default_recipient_id = '';
+$sm_default_subject = '';
+if(isset($_GET['reply']))
+{
+ $sm_msg_id = preg_replace("/[^0-9]/", "", $_GET['reply']);
+ $res = $app->db->queryOneRecord("SELECT sender_id, subject FROM support_message WHERE support_message_id=?", $sm_msg_id);
+ if($res['sender_id'])
+ {
+ $sm_default_recipient_id = $res['sender_id'];
+ $sm_default_subject = (preg_match("/^Re:/", $res['subject'])?"":"Re: ") . $res['subject'];
+ }
+}
+
+$authsql = $app->tform->getAuthSQL('r', 'client');
+
+//* Begin of the form definition of the first tab. The name of the tab is called "message". We refer
+//* to this name in the $form["tab_default"] setting above.
+$form["tabs"]['info'] = array (
+ 'title' => "Website", // Title of the Tab
+ 'width' => 100, // Tab width
+ 'template' => "templates/web_git_edit.htm", // Template file name
+ 'fields' => array (
+ //#################################
+ // Begin Datatable fields
+ //#################################
+
+ //Website
+ 'parent_domain_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => "SELECT web_domain.domain_id, CONCAT(web_domain.domain, ' :: ', server.server_name) AS parent_domain FROM web_domain, server WHERE web_domain.type = 'vhost' AND web_domain.server_id = server.server_id AND {AUTHSQL::web_domain} ORDER BY web_domain.domain",
+ 'keyfield'=> 'domain_id',
+ 'valuefield'=> 'parent_domain'
+ ),
+ 'value' => ''
+ ),
+ 'url' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'subject_is_empty'),
+ ),
+ 'filters' => array(
+ 0 => array( 'event' => 'SAVE',
+ 'type' => 'STRIPTAGS'),
+ 1 => array( 'event' => 'SAVE',
+ 'type' => 'STRIPNL')
+ ),
+ 'default' => $sm_default_subject,
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'username' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '30',
+ 'maxlength' => '255',
+ 'rows' => '',
+ 'cols' => '',
+ 'searchable' => 2
+ ),
+ 'password' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '30',
+ 'maxlength' => '255',
+ 'rows' => '',
+ 'cols' => '',
+ 'searchable' => 0
+ ),
+ /*'password' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'PASSWORD',
+ 'encryption'=> 'CRYPT',
+ 'default' => '',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '30',
+ 'maxlength' => '255',
+ 'rows' => '',
+ 'cols' => ''
+ ),*/
+ 'tstamp' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'default' => time(),
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '30'
+ ),
+ //#################################
+ // ENDE Datatable fields
+ //#################################
+ )
+);
+
+
+
+?>
\ No newline at end of file
diff --git a/interface/web/vcs/index.php b/interface/web/vcs/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..93204bc52586a7f8e6c63998048328bdb2402d77
--- /dev/null
+++ b/interface/web/vcs/index.php
@@ -0,0 +1,16 @@
+
+
+
+ISPConfig Help
+
+
+
+
+
+
\ No newline at end of file
diff --git a/interface/web/vcs/lib/admin.conf.php b/interface/web/vcs/lib/admin.conf.php
new file mode 100644
index 0000000000000000000000000000000000000000..b081da9fe5f09a1817495c7be34572912cbc8d5e
--- /dev/null
+++ b/interface/web/vcs/lib/admin.conf.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/interface/web/vcs/lib/lang/en_web_git.lng b/interface/web/vcs/lib/lang/en_web_git.lng
new file mode 100644
index 0000000000000000000000000000000000000000..688c3c7ef711490ebfcf1478782b01643fd3b5ba
--- /dev/null
+++ b/interface/web/vcs/lib/lang/en_web_git.lng
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/interface/web/vcs/lib/lang/en_web_git_list.lng b/interface/web/vcs/lib/lang/en_web_git_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..9e6f98dd7bb15f63577af2d12f8d2ff0c2b594be
--- /dev/null
+++ b/interface/web/vcs/lib/lang/en_web_git_list.lng
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/interface/web/vcs/lib/module.conf.php b/interface/web/vcs/lib/module.conf.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba575aae9b545d7640a1139416c2d88ec2440616
--- /dev/null
+++ b/interface/web/vcs/lib/module.conf.php
@@ -0,0 +1,75 @@
+ 'View repositories',
+ 'target' => 'content',
+ 'link' => 'vcs/web_git_list.php'
+ );
+
+// Add a menu item with the label 'View messages'
+$items[] = array( 'title' => 'Add repository',
+ 'target' => 'content',
+ 'link' => 'vcs/web_git_edit.php'
+ );
+
+// Append the menu $items defined above to a menu section labeled 'Support'
+$module['nav'][] = array( 'title' => 'Git',
+ 'open' => 1,
+ 'items' => $items
+ );
+
+?>
\ No newline at end of file
diff --git a/interface/web/vcs/list/web_git.list.php b/interface/web/vcs/list/web_git.list.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2fb0d925f34d8a7c0f78861a2ae75351b05f012
--- /dev/null
+++ b/interface/web/vcs/list/web_git.list.php
@@ -0,0 +1,102 @@
+ "parent_domain_id",
+ 'datatype' => "VARCHAR",
+ 'filters' => array( 0 => array( 'event' => 'SHOW',
+ 'type' => 'IDNTOUTF8')
+ ),
+ 'formtype' => "SELECT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => "SELECT domain_id,domain FROM web_domain WHERE type = 'vhost' AND {AUTHSQL} ORDER BY domain",
+ 'keyfield'=> 'domain_id',
+ 'valuefield'=> 'domain'
+ ),
+ 'width' => "",
+ 'value' => "");
+
+$liste['item'][] = array( 'field' => 'url',
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'op' => 'like',
+ 'prefix' => '%',
+ 'suffix' => '%',
+ 'width' => '',
+ 'value' => '');
+
+$liste['item'][] = array( 'field' => 'tstamp',
+ 'datatype' => 'DATETIMETSTAMP',
+ 'formtype' => 'TEXT',
+ 'op' => '=',
+ 'prefix' => '',
+ 'suffix' => '',
+ 'width' => '',
+ 'value' => '');
+
+
+?>
\ No newline at end of file
diff --git a/interface/web/vcs/templates/web_git_edit.htm b/interface/web/vcs/templates/web_git_edit.htm
new file mode 100644
index 0000000000000000000000000000000000000000..4c0f33900ad8655ddf17b646b4b6832c7f3c0ddd
--- /dev/null
+++ b/interface/web/vcs/templates/web_git_edit.htm
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interface/web/vcs/templates/web_git_list.htm b/interface/web/vcs/templates/web_git_list.htm
new file mode 100644
index 0000000000000000000000000000000000000000..095c02df73120120822f182f95d88c63aadb2f36
--- /dev/null
+++ b/interface/web/vcs/templates/web_git_list.htm
@@ -0,0 +1,59 @@
+
+
+
+
+ {tmpl_var name="toolsarea_head_txt"}
+
+
+
+
+
+
+
+
+
+
diff --git a/interface/web/vcs/templates/web_git_log.htm b/interface/web/vcs/templates/web_git_log.htm
new file mode 100644
index 0000000000000000000000000000000000000000..a9b6211dc5e03fa7f929dc6b2a9d3b94b11f3f10
--- /dev/null
+++ b/interface/web/vcs/templates/web_git_log.htm
@@ -0,0 +1,3 @@
+{tmpl_var name='log'}
+
+
diff --git a/interface/web/vcs/web_git_del.php b/interface/web/vcs/web_git_del.php
new file mode 100644
index 0000000000000000000000000000000000000000..92bbe1525954c2f5dfff69b19a3428d11606ad26
--- /dev/null
+++ b/interface/web/vcs/web_git_del.php
@@ -0,0 +1,48 @@
+auth->check_module_permissions('vcs');
+
+//* Load the form
+$app->uses('tform_actions');
+$app->tform_actions->onDelete();
+
+?>
\ No newline at end of file
diff --git a/interface/web/vcs/web_git_edit.php b/interface/web/vcs/web_git_edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..28a69421b47672482fb523e776814dfe02af9aeb
--- /dev/null
+++ b/interface/web/vcs/web_git_edit.php
@@ -0,0 +1,56 @@
+uses('tpl,tform,tform_actions');
+$app->load('tform_actions');
+
+// Create a class page_action that extends the tform_actions base class
+class page_action extends tform_actions {
+
+ //Customisations for the page actions will be defined here
+ function onAfterInsert()
+ {
+ global $app, $conf;
+ //
+ }
+
+ /* Get the log file */
+ function onLoad() {
+ global $app, $conf;
+
+ $this->id = $app->functions->intval($_REQUEST["id"]);
+ $filename = $this->id.".log";
+ $log = "No data logged for this repository";
+
+ $array_logs = $app->db->queryAllArray("SELECT data FROM monitor_data WHERE type = ?", "log_web_git_" . $this->id);
+ if(count($array_logs) > 0) {
+ $log = '';
+ foreach($array_logs as $datalog) {
+ $log .= unserialize($datalog).PHP_EOL;
+ }
+ }
+
+ $app->tpl->setVar("log", nl2br($log));
+ parent::onLoad();
+ }
+}
+
+// Create the new page object
+$page = new page_action();
+
+// Start the page rendering and action handling
+$page->onLoad();
+
+?>
diff --git a/interface/web/vcs/web_git_list.php b/interface/web/vcs/web_git_list.php
new file mode 100644
index 0000000000000000000000000000000000000000..a77c69778f4598c3ce1f6b98280a05a8c35c972e
--- /dev/null
+++ b/interface/web/vcs/web_git_list.php
@@ -0,0 +1,50 @@
+auth->check_module_permissions('vcs');
+
+//* Loading the class
+$app->uses('listform_actions');
+
+//* Optional limit
+$userid=$app->functions->intval($_SESSION['s']['user']['userid']);
+$app->listform_actions->SQLExtWhere = "web_git.sys_userid = $userid";
+
+//* Start the form rendering and action ahndling
+$app->listform_actions->onLoad();
+
+?>
\ No newline at end of file
diff --git a/interface/web/vcs/web_git_update.php b/interface/web/vcs/web_git_update.php
new file mode 100644
index 0000000000000000000000000000000000000000..534bcc4a0d54ea918ea3c3ce6c5f4102680dc669
--- /dev/null
+++ b/interface/web/vcs/web_git_update.php
@@ -0,0 +1,87 @@
+functions->intval($_GET['id']);
+
+if($userid && $web_git_id) {
+ /*
+ * Get the data of the repository
+ */
+ $dbgit = $app->db->queryOneRecord(
+ "SELECT * FROM web_git WHERE web_git_id = ?", $web_git_id);
+
+ if($dbgit && $dbgit["sys_userid"] == $userid) {
+ $data = [];
+ $data['old'] = $data['new'] = $dbgit;
+ $insert_data = [
+ "server_id" => 1,
+ "dbtable" => "web_git",
+ "dbidx" => "web_git_id:".$web_git_id,
+ "action" => 'p',
+ "tstamp" => time(),
+ "user" => "admin",
+ "data" => serialize($data),
+ "status" => "ok"
+ ];
+
+ $mysql_db_user_id = $app->db->insertFromArray('sys_datalog', $insert_data);
+
+ /* Sending this headers prevents the page to load the new content */
+ header('HTTP/1.1 500 Internal Server Error');
+ } else {
+ echo "You don't have permission to perform that action.";
+ }
+} else {
+ echo "You must be logued in and provide an id.";
+ die();
+}
+
+die();
+?>
\ No newline at end of file
diff --git a/server/mods-available/vcs_module.inc.php b/server/mods-available/vcs_module.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..756dcb8730eac91e1b45c194203ce78ca4f0ed25
--- /dev/null
+++ b/server/mods-available/vcs_module.inc.php
@@ -0,0 +1,96 @@
+plugins->announceEvents($this->module_name, $this->actions_available);
+
+ /*
+ As we want to get notified of any changes on several database tables,
+ we register for them.
+
+ The following function registers the function "functionname"
+ to be executed when a record for the table "dbtable" is
+ processed in the sys_datalog. "classname" is the name of the
+ class that contains the function functionname.
+ */
+
+ $app->modules->registerTableHook('web_git', $this->module_name, 'process');
+ }
+
+ /*
+ This function is called when a change in one of the registered tables is detected.
+ The function then raises the events for the plugins.
+ */
+
+ function process($tablename, $action, $data) {
+ global $app;
+
+ switch ($tablename) {
+ case 'web_git':
+ if($action == 'i') $app->plugins->raiseEvent('web_git_insert', $data);
+ if($action == 'u') $app->plugins->raiseEvent('web_git_insert', $data);
+ if($action == 'p') $app->plugins->raiseEvent('web_git_update', $data);
+ //if($action == 'd') $app->plugins->raiseEvent('web_git_delete', $data);
+ break;
+ } // end switch
+ } // end function
+
+
+} // end class
+
+?>
\ No newline at end of file
diff --git a/server/plugins-available/vcs_plugin.inc.php b/server/plugins-available/vcs_plugin.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..ebf4c660097bc3f8146886ef2eba9a528ad8a991
--- /dev/null
+++ b/server/plugins-available/vcs_plugin.inc.php
@@ -0,0 +1,369 @@
+plugins->registerEvent('web_git_insert', $this->plugin_name, 'insert');
+ $app->plugins->registerEvent('web_git_update', $this->plugin_name, 'update');
+ //$app->plugins->registerEvent('git_delete', $this->plugin_name, 'delete');
+
+ }
+
+ /* Pull request */
+ function update($event_name, $data) {
+ global $app, $conf;
+
+ $this->insert($event_name, $data);
+ }
+
+ /* Check if clone the repo or make a pull */
+ function insert($event_name, $data) {
+ global $app, $conf;
+ $this->action = 'insert';
+
+ //Website
+ $web_id = $data['new']['parent_domain_id'];
+ $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $web_id);
+
+ //user:grup
+ $username = escapeshellcmd($website['system_user']);
+ $groupname = escapeshellcmd($website['system_group']);
+
+ //document_root
+ $document_root = escapeshellcmd($website['document_root']);
+
+ //Git URL
+ $git_url = escapeshellcmd($data['new']['url']);
+ //Git User
+ $git_user = escapeshellcmd($data['new']['username']);
+ //Git pass
+ $git_pass = escapeshellcmd($data['new']['password']);
+
+ if($website) {
+ //Document root is a git folder?
+ $dr_isGit = $this->pathIsGit($document_root . '/web');
+ if($dr_isGit) {
+ $this->pull_request($data['new'], $website);
+ } else {
+ $this->setup_git($data['new'], $website);
+ }
+
+ }
+
+
+ }
+
+ private function pull_request($data, $website) {
+ global $app, $conf;
+
+ $curr_path = $this->_exec('pwd'); // Current path
+
+ //document_root
+ $document_root = escapeshellcmd($website['document_root'])."/web";
+ //cd to document_root path
+ chdir($document_root);
+
+ $gitBinary = $this->_exec("which git");
+
+ $log = date('Y-m-d h:i:s') . " ==========================================================================".PHP_EOL;
+ $log .= $this->_exec($gitBinary . ' pull');
+ $log .= PHP_EOL."===========================================================================================".PHP_EOL;
+
+ /* the id of the server as int */
+ $server_id = intval($conf['server_id']);
+
+ /** The type of the data */
+ $type = 'log_web_git_' . $data['web_git_id'];
+
+ /*
+ * actually this info has no state.
+ * maybe someone knows better...???...
+ */
+ $state = 'no_state';
+
+ /*
+ * Return the Result
+ */
+ $res = array();
+ $res['server_id'] = $server_id;
+ $res['type'] = $type;
+ $res['data'] = $log;
+ $res['state'] = $state;
+
+ /*
+ * Insert the log into the database
+ */
+ $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' .
+ 'VALUES (?, ?, UNIX_TIMESTAMP(), ?, ?)';
+ $app->dbmaster->query($sql, $res['server_id'], $res['type'], serialize($res['data']), $res['state']);
+
+ //Permissions
+ //user:grup
+ $username = escapeshellcmd($website['system_user']);
+ $groupname = escapeshellcmd($website['system_group']);
+
+ //Change permsis
+ $this->_exec('chown -R ' . $username . ':' . $groupname . ' ' . $document_root);
+
+ chdir($curr_path);
+ }
+
+ /* Creates a new git repo */
+ private function setup_git($data, $website) {
+ global $app, $conf;
+
+ //Create temp folder for the initial checkout
+ $tmp_path = '/tmp/web_git';
+ $this->_exec('mkdir -p ' . $tmp_path);
+ $tmp_path .= '/' . $website['domain_id'];
+
+ //Construir URL git con user y pass
+ $url_parts = parse_url($data['url']);
+
+ if($data['username'] != "") $url_parts['user'] = $data['username'];
+ if($data['password'] != "") $url_parts['pass'] = $data['password'];
+
+ $git_url = http_build_url($url_parts);
+
+ $gitBinary = $this->_exec("which git");
+ if($gitBinary) {
+ //Clonar repo
+ $this->_exec($gitBinary . ' clone ' . $git_url . ' ' . $tmp_path);
+
+ //user:grup
+ $username = escapeshellcmd($website['system_user']);
+ $groupname = escapeshellcmd($website['system_group']);
+ //document_root
+ $document_root = escapeshellcmd($website['document_root']);
+
+ //Cambiar permsis
+ $this->_exec('chown -R ' . $username . ':' . $groupname . ' ' . $tmp_path);
+
+ //mover .git a document_root
+ $this->_exec('mv ' . $tmp_path . '/*' . ' ' . $document_root . '/web/'); /* nano comment */
+ $this->_exec('mv ' . $tmp_path . '/.*' . ' ' . $document_root . '/web/');
+
+ //Eliminar carpeta temporal
+ $this->_exec('rm -rf ' . $tmp_path);
+ }
+ }
+
+ function pathIsGit($path) {
+ global $app, $conf;
+ $curr_path = $this->_exec('pwd'); // Current path
+ //cd to document_root path
+ chdir($path);
+
+ $gitBinary = $this->_exec("which git");
+ $check = '';
+ if($gitBinary) {
+ $check = $this->_exec($gitBinary . ' rev-parse --is-inside-work-tree'); //Returns "true" if inside a git repo
+ }
+
+ chdir($curr_path); //back to previous path
+
+ $app->log($check, LOGLEVEL_DEBUG);
+
+ if($check == "true") {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private function _exec($command) {
+ global $app;
+ $app->log('exec: '. $command, LOGLEVEL_DEBUG);
+ $output = shell_exec($command);
+ return trim($output);
+ }
+
+
+} // end class
+
+
+/**
+ * URL constants as defined in the PHP Manual under "Constants usable with
+ * http_build_url()".
+ *
+ * @see http://us2.php.net/manual/en/http.constants.php#http.constants.url
+ */
+if (!defined('HTTP_URL_REPLACE')) {
+ define('HTTP_URL_REPLACE', 1);
+}
+if (!defined('HTTP_URL_JOIN_PATH')) {
+ define('HTTP_URL_JOIN_PATH', 2);
+}
+if (!defined('HTTP_URL_JOIN_QUERY')) {
+ define('HTTP_URL_JOIN_QUERY', 4);
+}
+if (!defined('HTTP_URL_STRIP_USER')) {
+ define('HTTP_URL_STRIP_USER', 8);
+}
+if (!defined('HTTP_URL_STRIP_PASS')) {
+ define('HTTP_URL_STRIP_PASS', 16);
+}
+if (!defined('HTTP_URL_STRIP_AUTH')) {
+ define('HTTP_URL_STRIP_AUTH', 32);
+}
+if (!defined('HTTP_URL_STRIP_PORT')) {
+ define('HTTP_URL_STRIP_PORT', 64);
+}
+if (!defined('HTTP_URL_STRIP_PATH')) {
+ define('HTTP_URL_STRIP_PATH', 128);
+}
+if (!defined('HTTP_URL_STRIP_QUERY')) {
+ define('HTTP_URL_STRIP_QUERY', 256);
+}
+if (!defined('HTTP_URL_STRIP_FRAGMENT')) {
+ define('HTTP_URL_STRIP_FRAGMENT', 512);
+}
+if (!defined('HTTP_URL_STRIP_ALL')) {
+ define('HTTP_URL_STRIP_ALL', 1024);
+}
+if (!function_exists('http_build_url')) {
+ /**
+ * Build a URL.
+ *
+ * The parts of the second URL will be merged into the first according to
+ * the flags argument.
+ *
+ * @param mixed $url (part(s) of) an URL in form of a string or
+ * associative array like parse_url() returns
+ * @param mixed $parts same as the first argument
+ * @param int $flags a bitmask of binary or'ed HTTP_URL constants;
+ * HTTP_URL_REPLACE is the default
+ * @param array $new_url if set, it will be filled with the parts of the
+ * composed url like parse_url() would return
+ * @return string
+ */
+ function http_build_url($url, $parts = array(), $flags = HTTP_URL_REPLACE, &$new_url = array())
+ {
+ is_array($url) || $url = parse_url($url);
+ is_array($parts) || $parts = parse_url($parts);
+ isset($url['query']) && is_string($url['query']) || $url['query'] = null;
+ isset($parts['query']) && is_string($parts['query']) || $parts['query'] = null;
+ $keys = array('user', 'pass', 'port', 'path', 'query', 'fragment');
+ // HTTP_URL_STRIP_ALL and HTTP_URL_STRIP_AUTH cover several other flags.
+ if ($flags & HTTP_URL_STRIP_ALL) {
+ $flags |= HTTP_URL_STRIP_USER | HTTP_URL_STRIP_PASS
+ | HTTP_URL_STRIP_PORT | HTTP_URL_STRIP_PATH
+ | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT;
+ } elseif ($flags & HTTP_URL_STRIP_AUTH) {
+ $flags |= HTTP_URL_STRIP_USER | HTTP_URL_STRIP_PASS;
+ }
+ // Schema and host are alwasy replaced
+ foreach (array('scheme', 'host') as $part) {
+ if (isset($parts[$part])) {
+ $url[$part] = $parts[$part];
+ }
+ }
+ if ($flags & HTTP_URL_REPLACE) {
+ foreach ($keys as $key) {
+ if (isset($parts[$key])) {
+ $url[$key] = $parts[$key];
+ }
+ }
+ } else {
+ if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
+ if (isset($url['path']) && substr($parts['path'], 0, 1) !== '/') {
+ // Workaround for trailing slashes
+ $url['path'] .= 'a';
+ $url['path'] = rtrim(
+ str_replace(basename($url['path']), '', $url['path']),
+ '/'
+ ) . '/' . ltrim($parts['path'], '/');
+ } else {
+ $url['path'] = $parts['path'];
+ }
+ }
+ if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
+ if (isset($url['query'])) {
+ parse_str($url['query'], $url_query);
+ parse_str($parts['query'], $parts_query);
+ $url['query'] = http_build_query(
+ array_replace_recursive(
+ $url_query,
+ $parts_query
+ )
+ );
+ } else {
+ $url['query'] = $parts['query'];
+ }
+ }
+ }
+ if (isset($url['path']) && $url['path'] !== '' && substr($url['path'], 0, 1) !== '/') {
+ $url['path'] = '/' . $url['path'];
+ }
+ foreach ($keys as $key) {
+ $strip = 'HTTP_URL_STRIP_' . strtoupper($key);
+ if ($flags & constant($strip)) {
+ unset($url[$key]);
+ }
+ }
+ $parsed_string = '';
+ if (!empty($url['scheme'])) {
+ $parsed_string .= $url['scheme'] . '://';
+ }
+ if (!empty($url['user'])) {
+ $parsed_string .= $url['user'];
+ if (isset($url['pass'])) {
+ $parsed_string .= ':' . $url['pass'];
+ }
+ $parsed_string .= '@';
+ }
+ if (!empty($url['host'])) {
+ $parsed_string .= $url['host'];
+ }
+ if (!empty($url['port'])) {
+ $parsed_string .= ':' . $url['port'];
+ }
+ if (!empty($url['path'])) {
+ $parsed_string .= $url['path'];
+ }
+ if (!empty($url['query'])) {
+ $parsed_string .= '?' . $url['query'];
+ }
+ if (!empty($url['fragment'])) {
+ $parsed_string .= '#' . $url['fragment'];
+ }
+ $new_url = $url;
+ return $parsed_string;
+ }
+}
+
+?>