Example #1
0
/**
 * Move files for a web script into the Alfresco repository and refresh the list of currently
 * installed web scripts.
 *
 * @param $CFG
 * @param array  $files An array of full file paths to install.
 * @param string $uuid  The node UUID to install the files in.
 * @return bool True on success, False otherwise.
 */
function alfresco_install_web_script($files, $uuid)
{
    global $CFG;
    $status = true;
    if (!is_array($files)) {
        debugging('Not array');
        return false;
    }
    foreach ($files as $file) {
        if (!is_file($file)) {
            debugging('Not a file: ' . $file);
            return false;
        }
        $staus = $status && alfresco_upload_file('', $file, $uuid);
    }
    if ($status) {
        sleep(2);
        $url = alfresco_base_url() . '/?reset=on';
        /// Prepare curl session
        $session = curl_init($url);
        curl_setopt($session, CURLOPT_VERBOSE, true);
        /// Don't return HTTP headers. Do return the contents of the call
        curl_setopt($session, CURLOPT_HEADER, false);
        curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($session, CURLOPT_POST, true);
        /// Make the call
        $return_data = curl_exec($session);
        /// Get return http status code
        $httpcode = curl_getinfo($session, CURLINFO_HTTP_CODE);
        /// Close HTTP session
        curl_close($session);
        if ($httpcode !== 200) {
            debugging('HTTP code: ' . $httpcode);
            debugging($return_data);
            $status = false;
        }
    }
    return $status;
}
    /**
     * Process an uploaded file and send it into the repository.
     *
     * @uses $CFG
     * @uses $USER
     * @param string $upload   The array index for the uploaded file in the $_FILES superglobal.
     * @param string $uuid     The parent folder UUID value.
     * @param bool   $useadmin Set to false to make sure that the administrative user configured in
     *                         the plug-in is not used for this operation (default: true).
     * @return string|bool The new node's UUID value or, False on error.
     */
    function upload_file($upload = '', $path = '', $uuid = '', $useadmin = true)
    {
        global $CFG, $USER;
        if (ALFRESCO_DEBUG_TRACE) {
            mtrace('upload_file(' . $upload . ', ' . $path . ', ' . $uuid . ')');
        }
        if (ALFRESCO_DEBUG_TIME) {
            $start = microtime(true);
        }
        require_once $CFG->libdir . '/filelib.php';
        if (self::is_version('3.2')) {
            if ($node = alfresco_upload_file($upload, $path, $uuid)) {
                if (ALFRESCO_DEBUG_TIME) {
                    $end = microtime(true);
                    $time = $end - $start;
                    mtrace("upload_file('{$upload}', '{$path}', '{$uuid}'): {$time}");
                }
                return $node->uuid;
            }
            return false;
        } else {
            if (self::is_version('3.4')) {
                if (!empty($upload)) {
                    if (!isset($_FILES[$upload]) || !empty($_FILES[$upload]->error)) {
                        return false;
                    }
                    $filename = $_FILES[$upload]['name'];
                    $filepath = $_FILES[$upload]['tmp_name'];
                    $filemime = $_FILES[$upload]['type'];
                    $filesize = $_FILES[$upload]['size'];
                } else {
                    if (!empty($path)) {
                        if (!is_file($path)) {
                            return false;
                        }
                        $filename = basename($path);
                        $filepath = $path;
                        $filemime = mimeinfo('type', $filename);
                        $filesize = filesize($path);
                    } else {
                        return false;
                    }
                }
                $chunksize = 8192;
                $data1 = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <atom:entry xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/"
                xmlns:cmism="http://docs.oasis-open.org/ns/cmis/messaging/200908/"
                xmlns:atom="http://www.w3.org/2005/Atom"
                xmlns:app="http://www.w3.org/2007/app"
                xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/">
        <atom:title>' . $filename . '</atom:title>
        <atom:summary>' . get_string('uploadedbymoodle', 'repository_alfresco') . '</atom:summary>
        <cmisra:content>
            <cmisra:mediatype>' . $filemime . '</cmisra:mediatype>
            <cmisra:base64>';
                $data2 = '</cmisra:base64>
        </cmisra:content>

        <cmisra:object>
            <cmis:properties>
                <cmis:propertyId propertyDefinitionId="cmis:objectTypeId">
                    <cmis:value>cmis:document</cmis:value>
                </cmis:propertyId>
            </cmis:properties>
        </cmisra:object>
    </atom:entry>';
                $encodedbytes = 0;
                // Use a stream filter to base64 encode the file contents to a temporary file.
                if ($fi = fopen($filepath, 'r')) {
                    if ($fo = tmpfile()) {
                        stream_filter_append($fi, 'convert.base64-encode');
                        // Write the beginning of the XML document to the temporary file.
                        $encodedbytes += fwrite($fo, $data1, strlen($data1));
                        // Copy the uploaded file into the temporary file (usng the base64 encode stream filter)
                        // in 8K chunks to conserve memory.
                        while (($encbytes = stream_copy_to_stream($fi, $fo, $chunksize)) !== 0) {
                            $encodedbytes += $encbytes;
                        }
                        fclose($fi);
                        // Write the end of the XML document to the temporary file.
                        $encodedbytes += fwrite($fo, $data2, strlen($data2));
                    }
                }
                rewind($fo);
                // Force the usage of the configured Alfresco admin account, if requested.
                if ($useadmin) {
                    $username = '';
                } else {
                    $username = $USER->username;
                }
                // Fix username
                $username = $this->fix_username($username);
                $serviceuri = '/cmis/s/workspace://SpacesStore/i/' . $uuid . '/children';
                $url = alfresco_utils_get_wc_url($serviceuri, 'refresh', $username);
                $uri = parse_url($url);
                switch ($uri['scheme']) {
                    case 'http':
                        $port = isset($uri['port']) ? $uri['port'] : 80;
                        $host = $uri['host'] . ($port != 80 ? ':' . $port : '');
                        $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15);
                        break;
                    case 'https':
                        /// Note: Only works for PHP 4.3 compiled with OpenSSL.
                        $port = isset($uri['port']) ? $uri['port'] : 443;
                        $host = $uri['host'] . ($port != 443 ? ':' . $port : '');
                        $fp = @fsockopen('ssl://' . $uri['host'], $port, $errno, $errstr, 20);
                        break;
                    default:
                        $result->error = 'invalid schema ' . $uri['scheme'];
                        return $result;
                }
                // Make sure the socket opened properly.
                if (!$fp) {
                    $result->error = trim($errno . ' ' . $errstr);
                    return $result;
                }
                // Construct the path to act on.
                $path = isset($uri['path']) ? $uri['path'] : '/';
                if (isset($uri['query'])) {
                    $path .= '?' . $uri['query'];
                }
                // Create HTTP request.
                $headers = array('Host' => "Host: {$host}", 'Content-type' => 'Content-type: application/atom+xml;type=entry', 'User-Agent' => 'User-Agent: Moodle (+http://moodle.org/)', 'Content-Length' => 'Content-Length: ' . $encodedbytes, 'MIME-Version' => 'MIME-Version: 1.0');
                $request = 'POST  ' . $path . " HTTP/1.0\r\n";
                $request .= implode("\r\n", $headers);
                $request .= "\r\n\r\n";
                fwrite($fp, $request);
                // Write the XML request (which contains the base64-encoded uploaded file contents) into the socket.
                stream_copy_to_stream($fo, $fp);
                fclose($fo);
                fwrite($fp, "\r\n");
                // Fetch response.
                $response = '';
                while (!feof($fp) && ($chunk = fread($fp, 1024))) {
                    $response .= $chunk;
                }
                fclose($fp);
                // Parse response.
                list($split, $result->data) = explode("\r\n\r\n", $response, 2);
                $split = preg_split("/\r\n|\n|\r/", $split);
                list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3);
                $result->headers = array();
                // Parse headers.
                while ($line = trim(array_shift($split))) {
                    list($header, $value) = explode(':', $line, 2);
                    if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
                        // RFC 2109: the Set-Cookie response header comprises the token Set-
                        // Cookie:, followed by a comma-separated list of one or more cookies.
                        $result->headers[$header] .= ',' . trim($value);
                    } else {
                        $result->headers[$header] = trim($value);
                    }
                }
                $responses = array(100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported');
                // RFC 2616 states that all unknown HTTP codes must be treated the same as
                // the base code in their class.
                if (!isset($responses[$code])) {
                    $code = floor($code / 100) * 100;
                }
                //TODO: check for $code 500 and add menu to replace copy or cancel the uploaded file with the same name as an existing file
                //        if($code == 500) {
                //
                //        } else
                if ($code != 200 && $code != 201 && $code != 304) {
                    debugging(get_string('couldnotaccessserviceat', 'repository_alfresco', $serviceuri), DEBUG_DEVELOPER);
                    return false;
                }
                $response = preg_replace('/(&[^amp;])+/', '&amp;', $response);
                $dom = new DOMDocument();
                $dom->preserveWhiteSpace = false;
                $dom->loadXML($result->data);
                $nodes = $dom->getElementsByTagName('entry');
                if (!$nodes->length) {
                    return false;
                }
                $type = '';
                $properties = alfresco_process_node($dom, $nodes->item(0), $type);
                // Ensure that we set the current user to be the owner of the newly created directory.
                if (!empty($properties->uuid)) {
                    $username = alfresco_transform_username($USER->username);
                    // We're not going to check the response for this right now.
                    alfresco_request('/moodle/nodeowner/' . $properties->uuid . '?username=' . $username);
                }
                return $properties;
            }
        }
    }