if (isset($item['language']) && $item['language'] && $item['language'] != 'none') { $text .= ' <dc:language>' . $item['language'] . '</dc:language>' . "\n"; } if (is_object($anchor)) { $text .= ' <dc:subject>' . encode_field($anchor->get_title()) . '</dc:subject>' . "\n"; } $text .= ' </rdf:Description>' . "\n" . '</rdf:RDF>'; // // transfer to the user agent // // handle the output correctly render_raw('text/xml; charset=' . $context['charset']); // suggest a name on download if (!headers_sent()) { $file_name = Skin::strip($context['page_title']) . '.opml.xml'; $file_name =& utf8::to_ascii($file_name); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
$description = Skin::strip(Codes::beautify($item['description']), 50); } // prepare the response $text = '<?xml version="1.0" encoding="' . $context['charset'] . '"?>' . "\n" . '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">' . "\n" . ' <rdf:Description rdf:about="' . $url . '">' . "\n" . ' <dc:title>' . encode_field($item['title']) . '</dc:title>' . "\n" . ' <dc:description>' . encode_field(Skin::strip($description)) . '</dc:description>' . "\n" . ' <dc:date>' . gmdate('Y-m-d') . '</dc:date>' . "\n" . ' <dc:format>text/html</dc:format>' . "\n"; if (isset($item['language']) && $item['language'] && $item['language'] != 'none') { $text .= ' <dc:language>' . $item['language'] . '</dc:language>' . "\n"; } $text .= ' </rdf:Description>' . "\n" . '</rdf:RDF>'; // // transfer to the user agent // // handle the output correctly render_raw('text/xml; charset=' . $context['charset']); // suggest a name on download if (!headers_sent()) { $file_name = utf8::to_ascii(Skin::strip($context['page_title']) . '.opml.xml'); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
$text .= $separator; } $text .= $content; } // only one script has been asked if (count($script) == 1) { // compress the page if possible, but no transcoding -- the bare handler $context['charset'] = 'ASCII'; render_raw('text/x-httpd-php'); // send the response to the caller if (!headers_sent()) { Safe::header('Content-Description: Reference file from YACS environment'); } // suggest a download if (!headers_sent()) { $file_name = utf8::to_ascii(basename($script[0])); Safe::header('Content-Disposition: attachment; filename="' . str_replace('"', '', $file_name) . '"'); } // several scripts at one } else { // multi-part separator on the first line $text = $separator . $text; // compress the page if possible, but no transcoding -- the bare handler $context['charset'] = 'ASCII'; render_raw('text/html'); // send the response to the caller if (!headers_sent()) { Safe::header('Content-Description: Reference files from YACS environment'); } } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download
/** * build one table * * Accept following variants: * - csv - to provide a downloadable csv page * - json - to provide all values in one column * - inline - to render tables within articles * - simple - the legacy fixed table * - sortable - click on column to sort the row * * @param the id of the table to build * @param string the variant to provide - default is 'simple' * @return a displayable string */ public static function build($id, $variant = 'simple') { global $context; // split parameters $attributes = preg_split("/\\s*,\\s*/", $id, 3); $id = $attributes[0]; // get the table object if (!($table = Tables::get($id))) { return NULL; } // do the SELECT statement if (!($rows = SQL::query($table['query']))) { Logger::error(sprintf(i18n::s('Error in table query %s'), $id) . BR . htmlspecialchars($table['query']) . BR . SQL::error()); return NULL; } // build the resulting string $text = ''; switch ($variant) { // produce a table readable into MS-Excel case 'csv': // comma separated values $separator = ","; // one row for the title if ($table['title']) { $label = preg_replace('/\\s/', ' ', $table['title']); // encode to ASCII $label = utf8::to_ascii($label, PRINTABLE_SAFE_ALPHABET); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); $text .= '"' . $label . '"'; $text .= "\n"; } // one row for header fields $index = 0; while ($field = SQL::fetch_field($rows)) { if ($index++) { $text .= $separator; } $label = trim(preg_replace('/\\s/', ' ', ucfirst($field->name))); // encode $label = utf8::to_ascii($label, PRINTABLE_SAFE_ALPHABET); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); $text .= '"' . $label . '"'; } $text .= "\n"; // process every table row $row_index = 0; while ($row = SQL::fetch($rows)) { // one cell at a time $index = 0; foreach ($row as $name => $value) { // glue cells if ($index++) { $text .= $separator; } // remove HTML tags $value = strip_tags(str_replace('</', ' </', str_replace(BR, ' / ', $value))); // clean spaces $label = trim(preg_replace('/\\s+/', ' ', $value)); // encode $label = utf8::to_ascii($label, PRINTABLE_SAFE_ALPHABET); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); // make a link if this is a reference if ($index == 1 && $table['with_zoom'] == 'Y') { $label = $context['url_to_home'] . $context['url_to_root'] . $label; } // quote data $text .= '"' . $label . '"'; } // new line $text .= "\n"; } return $text; // a JSON set of values // a JSON set of values case 'json': // get header labels $labels = array(); while ($field = SQL::fetch_field($rows)) { $labels[] = trim(preg_replace('/[^\\w]+/', '', ucfirst($field->name))); } // all items $data = array(); $data['items'] = array(); while ($row = SQL::fetch_row($rows)) { // all rows $datum = array(); $label = FALSE; $index = 0; $link = NULL; foreach ($row as $name => $value) { $index++; // first column is only a link if ($index == 1 && $table['with_zoom'] == 'Y') { $link = $context['url_to_home'] . $context['url_to_root'] . ltrim($value, '/'); continue; } // adjust types to not fool the json encoder if (preg_match('/^(\\+|-){0,1}[0-9]+$/', $value)) { $value = intval($value); } elseif (preg_match('/^(\\+|-){0,1}[0-9\\.,]+$/', $value)) { $value = floatval($value); } elseif (preg_match('/^(true|false)$/i', $value)) { $value = intval($value); } // ensure we have some label for SIMILE Exhibit if (!$label) { $label = $value; } // combine first and second columns if ($index == 2 && $link) { $value = Skin::build_link($link, $value, 'basic'); } // save this value $datum[$labels[$name]] = utf8::to_ascii($value, PRINTABLE_SAFE_ALPHABET); } if ($label && !in_array('label', $labels)) { $datum['label'] = utf8::to_ascii($label, PRINTABLE_SAFE_ALPHABET); } // add a tip, if any $data['items'][] = $datum; } include_once $context['path_to_root'] . 'included/json.php'; $text .= json_encode2($data); return $text; // list of facets for SIMILE Exhibit // list of facets for SIMILE Exhibit case 'json-facets': // columns are actual facets $facets = array(); $index = 0; while ($field = SQL::fetch_field($rows)) { $index++; // first column is only a link if ($index == 1 && $table['with_zoom'] == 'Y') { continue; } // first column has a link if ($index == 2 && $table['with_zoom'] == 'Y') { continue; } // column is a facet $label = '.' . trim(preg_replace('/[^\\w]+/', '', ucfirst($field->name))); $title = trim(str_replace(',', '', ucfirst($field->name))); $facets[] = '<div ex:role="facet" ex:expression="' . $label . '" ex:facetLabel="' . $title . '"></div>'; // only last columns can be faceted if (count($facets) > 7) { array_shift($facets); } } // reverse facet order $facets = array_reverse($facets); // job done $text = join("\n", $facets); return $text; // list of columns for SIMILE Exhibit // list of columns for SIMILE Exhibit case 'json-labels': // get header labels $labels = array(); $index = 0; while ($field = SQL::fetch_field($rows)) { $index++; // first column is only a link if ($index == 1 && $table['with_zoom'] == 'Y') { continue; } // column id $labels[] = '.' . trim(preg_replace('/[^\\w]+/', '', ucfirst($field->name))); // limit the number of columns put on screen if (count($labels) >= 7) { break; } } // job done $text = join(', ', $labels); return $text; // titles of columns for SIMILE Exhibit // titles of columns for SIMILE Exhibit case 'json-titles': // get header labels $labels = array(); $index = 0; while ($field = SQL::fetch_field($rows)) { $index++; // first column is only a link if ($index == 1 && $table['with_zoom'] == 'Y') { continue; } // column header $labels[] = trim(str_replace(',', '', ucfirst($field->name))); } $text = join(', ', $labels); return $text; // produce an HTML table // produce an HTML table default: case 'inline': case 'sortable': // a table with a grid $text .= Skin::table_prefix('grid'); // the title, with a menu to download the table into Excel if ($variant == 'inline') { $item_bar = array(); $item_bar += array(Tables::get_url($id) => $table['title']); $item_bar += array(Tables::get_url($id, 'fetch_as_csv') => 'CSV (Excel)'); if (Surfer::is_associate()) { $item_bar += array(Tables::get_url($id, 'edit') => i18n::s('edit')); } if (count($item_bar)) { $text .= '<caption>' . Skin::build_list($item_bar, 'menu') . "</caption>\n"; } } // column headers are clickable links $cells = array(); $index = 0; while ($field = SQL::fetch_field($rows)) { if ($index++ != 0 || $table['with_zoom'] != 'Y') { $cells[] = ucfirst($field->name); } } $text .= "\t\t" . Skin::table_row($cells, 'sortable'); // the table body $count = 0; $row_index = 0; while ($row = SQL::fetch_row($rows)) { $cells = array(); $link = ''; for ($index = 0; $index < count($row); $index++) { if ($index == 0 && $table['with_zoom'] == 'Y') { $link = $row[$index]; } elseif ($link) { $cells[] = Skin::build_link($link, $row[$index]); $link = ''; } else { $cells[] = $row[$index]; } } $text .= "\t\t" . Skin::table_row($cells, $count++); } $text .= Skin::table_suffix(); return $text; // adapted to open chart flash // adapted to open chart flash case 'chart': // get title for y series $y_title = $y2_title = $y3_title = NULL; $y_index = $y2_index = $y3_index = 0; $index = 0; while ($field = SQL::fetch_field($rows)) { // time will be used for x labels if ($index == 0 && $table['with_zoom'] == 'T') { } elseif ($index == 0 && $table['with_zoom'] == 'Y') { } elseif (!$y_title) { $y_title = '"' . ucfirst($field->name) . '"'; $y_index = $index; } elseif (!$y2_title) { $y2_title = '"' . ucfirst($field->name) . '"'; $y2_index = $index; } elseif (!$y3_title) { $y3_title = '"' . ucfirst($field->name) . '"'; $y3_index = $index; break; } $index++; } // process every table row $x_labels = array(); $y_values = array(); $y2_values = array(); $y3_values = array(); $y_min = $y_max = NULL; $count = 1; while ($row = SQL::fetch($rows)) { // one cell at a time $index = 0; foreach ($row as $name => $value) { // clean spaces $label = trim(preg_replace('/\\s/', ' ', $value)); // encode in iso8859 $label = utf8::to_iso8859($label); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); // quote data if (preg_match('/-*[^0-9\\,\\.]/', $label)) { $label = '"' . $label . '"'; } // x labels if ($index == 0) { if ($table['with_zoom'] == 'T') { array_unshift($x_labels, $label); } else { $x_labels[] = $count++; } // y value } elseif ($index == $y_index) { if ($table['with_zoom'] == 'T') { array_unshift($y_values, $label); } else { $y_values[] = $label; } if (!isset($y_min) || intval($label) < $y_min) { $y_min = intval($label); } if (!isset($y_max) || intval($label) > $y_max) { $y_max = intval($label); } // y2 value } elseif ($index == $y2_index) { if ($table['with_zoom'] == 'T') { array_unshift($y2_values, $label); } else { $y_values[] = $label; } if (!isset($y_min) || intval($label) < $y_min) { $y_min = intval($label); } if (!isset($y_max) || intval($label) > $y_max) { $y_max = intval($label); } // y3 value } elseif ($index == $y3_index) { if ($table['with_zoom'] == 'T') { array_unshift($y3_values, $label); } else { $y_values[] = $label; } if (!isset($y_min) || intval($label) < $y_min) { $y_min = intval($label); } if (!isset($y_max) || intval($label) > $y_max) { $y_max = intval($label); } // we won't process the rest break; } // next column $index++; } } // y minimum if ($y_min > 0) { $y_min = 0; } // y maximum $y_max = strval($y_max); if (strlen($y_max) == 1) { $y_max = 10; } elseif (strlen($y_max) == 2) { $y_max = (intval(substr($y_max, 0, 1)) + 1) * 10; } elseif (strlen($y_max) == 3) { $y_max = (intval(substr($y_max, 0, 2)) + 1) * 10; } else { $y_max = strval(intval(substr($y_max, 0, 2)) + 1) . substr('0000000000000000000000000000000000000000000000000000', 0, strlen($y_max) - 2); } // data series $elements = array(); if (count($y_values)) { $elements[] = '{ "type":"bar_glass", "colour":"#BF3B69", "values": [ ' . join(',', $y_values) . ' ], "text": ' . $y_title . ', "font-size": 12 }'; } if (count($y2_values)) { $elements[] = '{ "type": "line", "width": 1, "colour": "#5E4725", "values": [ ' . join(',', $y2_values) . ' ], "text": ' . $y2_title . ', "font-size": 12 }'; } if (count($y3_values)) { $elements[] = '{ "type":"bar_glass", "colour":"#5E0722", "values": [ ' . join(',', $y3_values) . ' ], "text": ' . $y3_title . ', "font-size": 12 }'; } // the full setup $text = '{ "elements": [ ' . join(',', $elements) . ' ], "x_axis": { "offset": false, "steps": 1, "labels": { "steps": 3, "rotate": 310, "labels": [ ' . join(',', $x_labels) . ' ] } }, "y_axis": { "min": ' . $y_min . ', "max": ' . $y_max . ' } }'; return $text; // first number // first number case 'column': // comma separated values $separator = ","; // process every table row while ($row = SQL::fetch($rows)) { // not always the first column $index = 0; foreach ($row as $name => $value) { $index++; // skip dates and links if ($index == 1 && $table['with_zoom'] != 'N') { continue; } // glue cells if ($text) { $text .= $separator; } // clean spaces $label = trim(preg_replace('/\\s/', ' ', $value)); // encode in iso8859 $label = utf8::to_iso8859($label); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); // quote data if (preg_match('/[^a-zA-Z0-9\\,\\.\\-_]/', $label)) { $text .= '"' . $label . '"'; } else { $text .= $label; } // only first column break; } } return $text; // produce a raw table // produce a raw table case 'raw': // comma separated values $separator = ","; // process every table row while ($row = SQL::fetch($rows)) { // one cell at a time $index = 0; foreach ($row as $name => $value) { // glue cells if ($index++) { $text .= $separator; } // clean spaces $label = trim(preg_replace('/\\s/', ' ', $value)); // encode in iso8859 $label = utf8::to_iso8859($label); // escape quotes to preserve them in the data $label = str_replace('"', '""', $label); // make a link if this is a reference if ($index == 0 && $table['with_zoom'] == 'Y') { $label = $context['url_to_home'] . $context['url_to_root'] . $label; } // quote data if (preg_match('/[^a-zA-Z0-9\\-_]/', $label)) { $text .= '"' . $label . '"'; } else { $text .= $label; } } // new line $text .= "\n"; } return $text; // a simple table // a simple table case 'simple': $text .= Skin::table_prefix('table'); // columns headers $index = 0; while ($field = SQL::fetch_field($rows)) { $cells[] = ucfirst($field->name); } $text .= Skin::table_row($cells, 'header'); // other rows while ($row = SQL::fetch_row($rows)) { $text .= Skin::table_row($row, $count++); } $text .= Skin::table_suffix(); return $text; // xml table // xml table case 'xml': $text = ''; while ($row = SQL::fetch($rows)) { $text .= ' <item>' . "\n"; foreach ($row as $name => $value) { $type = preg_replace('/[^a-z0-9]+/i', '_', $name); if (preg_match('/^[^a-z]/i', $type)) { $type = '_' . $type; } $text .= ' <' . $type . '>' . preg_replace('/&(?!(amp|#\\d+);)/i', '&', utf8::transcode(str_replace(array('left=', 'right='), '', $value))) . '</' . $type . '>' . "\n"; } $text .= ' </item>' . "\n\n"; } return '<?xml version="1.0" encoding="' . $context['charset'] . '"?>' . "\n" . '<items>' . "\n" . $text . '</items>' . "\n"; } }
// make a text include_once '../services/codec.php'; include_once '../services/rss_codec.php'; $result = rss_Codec::encode($values); $text = @$result[1]; // save in cache for the next request Cache::put($cache_id, $text, 'articles'); } // // transfer to the user agent // // handle the output correctly render_raw('text/xml; charset=' . $context['charset']); // suggest a name on download if (!headers_sent()) { $file_name = utf8::to_ascii($context['site_name'] . '.category.' . $item['id'] . '.rss.xml'); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
} // genre if ($value = implode(', ', @$data['comments_html']['genre'])) { Safe::header("icy-genre: " . utf8::to_iso8859(utf8::transcode($value))); } // audio bitrate if ($value = @$data['audio']['bitrate']) { Safe::header("icy-br: " . substr($value, 0, -3)); } // this server Safe::header("icy-url: " . $context['url_to_home'] . $context['url_to_root']); } // serve the right type Safe::header('Content-Type: ' . Files::get_mime_type($item['file_name'])); // suggest a name for the saved file $file_name = utf8::to_ascii($item['file_name']); Safe::header('Content-Disposition: attachment; filename="' . str_replace('"', '', $file_name) . '"'); // we accepted (limited) range requests Safe::header('Accept-Ranges: bytes'); // provide only a slice of the file if (isset($_SERVER['HTTP_RANGE']) && !strncmp('bytes=', $_SERVER['HTTP_RANGE'], 6)) { // maybe several ranges $range = substr($_SERVER['HTTP_RANGE'], 6); // process only the first range, if several are specified if ($position = strpos($range, ',')) { $range = substr($range, 0, $position); } // beginning and end of the range list($offset, $end) = explode('-', $range); $offset = intval($offset); if (!$end) {
$scope = ''; if ($id) { $scope = '?id=' . urlencode($id); } // available blogging api $text .= ' <apis>' . "\n" . ' <api name="MovableType" preferred="true" apiLink="' . $context['url_to_home'] . $context['url_to_root'] . 'services/blog.php' . $scope . '" blogID="' . encode_field($id) . '" />' . "\n" . ' <api name="MetaWeblog" preferred="false" apiLink="' . $context['url_to_home'] . $context['url_to_root'] . 'services/blog.php' . $scope . '" blogID="' . encode_field($id) . '" />' . "\n" . ' <api name="Blogger" preferred="false" apiLink="' . $context['url_to_home'] . $context['url_to_root'] . 'services/blog.php' . $scope . '" blogID="' . encode_field($id) . '" />' . "\n" . ' </apis>' . "\n"; // the postamble $text .= '</service>' . "\n" . '</rsd>' . "\n"; // // transfer to the user agent // // handle the output correctly render_raw('application/rsd+xml; charset=' . $context['charset']); // suggest a name on download if (!headers_sent()) { $file_name = utf8::to_ascii($context['site_name'] . '.rsd.xml'); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook
// an error occured } elseif (count($context['error'])) { } else { // put in the calendar, no more $method = 'PUBLISH'; // get the full text of the event invitation $text = $overlay->get_ics($method); // no encoding, no compression and no yacs handler... if (!headers_sent()) { Safe::header('Content-Type: text/calendar; method="' . $method . '"; charset="UTF-8"'); Safe::header('Content-Transfer-Encoding: binary'); Safe::header('Content-Length: ' . strlen($text)); } // suggest a download if (!headers_sent()) { $file_name = utf8::to_ascii(Skin::strip($anchor->get_title(false)) . '.ics'); Safe::header('Content-Disposition: attachment; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
$rows[] = array(i18n::s('Source'), $item['source']); } // keywords if ($item['keywords']) { $rows[] = array(i18n::s('Keywords'), $item['keywords']); } // display these details $context['text'] .= Skin::table(NULL, $rows); // insert anchor prefix if (is_object($anchor)) { $context['text'] .= $anchor->get_prefix(); } // if we have a local file if (!isset($item['file_href']) || !$item['file_href']) { // where the file is $path = $context['path_to_root'] . Files::get_path($item['anchor']) . '/' . rawurlencode(utf8::to_ascii($item['file_name'])); //load some file parser if one is available $analyzer = NULL; if (is_readable($context['path_to_root'] . 'included/getid3/getid3.php')) { include_once $context['path_to_root'] . 'included/getid3/getid3.php'; $analyzer = new getid3(); } // parse file content, and streamline information $data = array(); if (is_object($analyzer) && Files::is_stream($item['file_name'])) { $data = $analyzer->analyze($path); getid3_lib::CopyTagsToComments($data); } // details $rows = array(); // artist
Versions::save($item, 'file:' . $item['id']); } // assume this is just an update of the record $action = 'file:update'; // true when several files are uploaded at once $exploded = FALSE; // this record is a reference to an external file -- do not take upload into account, if any if (isset($_REQUEST['file_href']) && $_REQUEST['file_href']) { // protect from hackers -- encode_link() would introduce & $_REQUEST['file_href'] = trim(preg_replace(FORBIDDEN_IN_URLS, '_', $_REQUEST['file_href']), ' _'); // ensure we have a title if (!$_REQUEST['title']) { $_REQUEST['title'] = str_replace('%20', ' ', basename($_REQUEST['file_href'])); } // ensure we have a file name $_REQUEST['file_name'] = utf8::to_ascii(str_replace('%20', ' ', basename($_REQUEST['file_href']))); // change has been documented if (!isset($_REQUEST['version']) || !$_REQUEST['version']) { $_REQUEST['version'] = ''; } else { $_REQUEST['version'] = ' - ' . $_REQUEST['version']; } // always remember file uploads, for traceability $_REQUEST['version'] = $_REQUEST['file_name'] . ' (' . Skin::build_number($_REQUEST['file_size'], i18n::s('bytes')) . ')' . $_REQUEST['version']; // add to file history $_REQUEST['description'] = Files::add_to_history($item, $_REQUEST['version']); // when the file has been overlaid if (is_object($overlay)) { // allow for change detection $overlay->snapshot(); // update the overlay from form content
foreach ($items as $id => $attributes) { // read file content if ($content = Safe::file_get_contents($file_path . '/' . $attributes['file_name'], 'rb')) { // add the binary data $zipfile->deflate($attributes['file_name'], Safe::filemtime($file_path . '/' . $attributes['file_name']), $content); } } // // transfer to the user agent // // send the archive content if ($archive = $zipfile->get()) { // suggest a download Safe::header('Content-Type: application/octet-stream'); // suggest a name for the saved file $file_name = utf8::to_ascii($item['title']) . '.zip'; Safe::header('Content-Disposition: attachment; filename="' . str_replace('"', '', $file_name) . '"'); // file size Safe::header('Content-Length: ' . strlen($archive)); // already encoded Safe::header('Content-Transfer-Encoding: binary'); // enable 30-minute caching (30*60 = 1800), even through https, to help IE on download http::expire(1800); // strong validator $etag = '"' . md5($archive) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') {
Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // display the table in CSV } else { // force the character set $context['charset'] = 'iso-8859-15'; // render actual table content $text = strip_tags(Tables::build($item['id'], 'raw')); // // transfer to the user agent // // handle the output correctly render_raw('text/csv; charset=' . $context['charset']); // suggest a download if (!headers_sent()) { $file_name = utf8::to_ascii(Skin::strip($item['title']) . '.csv'); Safe::header('Content-Disposition: attachment; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
function explode_callback($name) { global $context; // reject all files put in sub-folders if (($path = substr($name, strlen($context['uploaded_path'] . '/'))) && strpos($path, '/') !== FALSE) { Safe::unlink($name); } elseif (!Files::is_authorized($name)) { Safe::unlink($name); } else { // make it easy to download $ascii = utf8::to_ascii(basename($name)); Safe::rename($name, $context['uploaded_path'] . '/' . $ascii); // remember this name $context['uploaded_files'][] = $ascii; } }
/** * embed an interactive object * * The id designates the target file. * It can also include width and height of the target canvas, as in: '12, 100%, 250px' * * @param string id of the target file * @return string the rendered string **/ public static function render_embed($id) { global $context; // split parameters $attributes = preg_split("/\\s*,\\s*/", $id, 4); $id = $attributes[0]; // get the file if (!($item = Files::get($id))) { $output = '[embed=' . $id . ']'; return $output; } // stream in a separate page if (isset($attributes[1]) && preg_match('/window/i', $attributes[1])) { if (!isset($attributes[2])) { $attributes[2] = i18n::s('Play in a separate window'); } $output = '<a href="' . $context['url_to_home'] . $context['url_to_root'] . Files::get_url($item['id'], 'stream', $item['file_name']) . '" onclick="window.open(this.href); return false;" class="button"><span>' . $attributes[2] . '</span></a>'; return $output; } // file extension $extension = strtolower(substr($item['file_name'], -3)); // set a default size if (!isset($attributes[1])) { if (!strcmp($extension, 'gan')) { $attributes[1] = '98%'; } elseif (!strcmp($extension, 'mm') && isset($context['skins_freemind_canvas_width'])) { $attributes[1] = $context['skins_freemind_canvas_width']; } else { $attributes[1] = 480; } } if (!isset($attributes[2])) { if (!strcmp($extension, 'gan')) { $attributes[2] = '300px'; } elseif (!strcmp($extension, 'mm') && isset($context['skins_freemind_canvas_height'])) { $attributes[2] = $context['skins_freemind_canvas_height']; } else { $attributes[2] = 360; } } // object attributes $width = $attributes[1]; $height = $attributes[2]; $flashvars = ''; if (isset($attributes[3])) { $flashvars = $attributes[3]; } // rendering depends on file extension switch ($extension) { // stream a video case '3gp': case 'flv': case 'm4v': case 'mov': case 'mp4': // a flash player to stream a flash video $flvplayer_url = $context['url_to_home'] . $context['url_to_root'] . 'included/browser/player_flv_maxi.swf'; // file is elsewhere if (isset($item['file_href']) && $item['file_href']) { $url = $item['file_href']; } else { $url = $context['url_to_home'] . $context['url_to_root'] . Files::get_url($item['id'], 'fetch', $item['file_name']); } // pass parameters to the player if ($flashvars) { $flashvars = str_replace('autostart=true', 'autoplay=1', $flashvars) . '&'; } $flashvars .= 'width=' . $width . '&height=' . $height; // if there is a static image for this video, use it if (isset($item['icon_url']) && $item['icon_url']) { $flashvars .= '&startimage=' . urlencode($item['icon_url']); } // if there is a subtitle file for this video, use it if (isset($item['file_name']) && ($srt = 'files/' . str_replace(':', '/', $item['anchor']) . '/' . str_replace('.' . $extension, '.srt', $item['file_name'])) && file_exists($context['path_to_root'] . $srt)) { $flashvars .= '&srt=1&srturl=' . urlencode($context['url_to_home'] . $context['url_to_root'] . $srt); } // if there is a logo file in the skin, use it Skin::define_img_href('FLV_IMG_HREF', 'codes/flvplayer_logo.png', ''); if (FLV_IMG_HREF) { $flashvars .= '&top1=' . urlencode(FLV_IMG_HREF . '|10|10'); } // rely on Flash if (Surfer::has_flash()) { // the full object is built in Javascript --see parameters at http://flv-player.net/players/maxi/documentation/ $output = '<div id="flv_' . $item['id'] . '" class="no_print">Flash plugin or Javascript are turned off. Activate both and reload to view the object</div>' . "\n"; Page::insert_script('var flashvars = { flv:"' . $url . '", ' . str_replace(array('&', '='), array('", ', ':"'), $flashvars) . '", autoload:0, margin:1, showiconplay:1, playeralpha:50, iconplaybgalpha:30, showfullscreen:1, showloading:"always", ondoubleclick:"fullscreen" }' . "\n" . 'var params = { allowfullscreen: "true", allowscriptaccess: "always" }' . "\n" . 'var attributes = { id: "file_' . $item['id'] . '", name: "file_' . $item['id'] . '"}' . "\n" . 'swfobject.embedSWF("' . $flvplayer_url . '", "flv_' . $item['id'] . '", "' . $width . '", "' . $height . '", "9", "' . $context['url_to_home'] . $context['url_to_root'] . 'included/browser/expressinstall.swf", flashvars, params);' . "\n"); // native support } else { // <video> is HTML5, <object> is legacy $output = '<video width="' . $width . '" height="' . $height . '" autoplay="" controls="" src="' . $url . '" >' . "\n" . ' <object width="' . $width . '" height="' . $height . '" data="' . $url . '" type="' . Files::get_mime_type($item['file_name']) . '">' . "\n" . ' <param value="' . $url . '" name="movie" />' . "\n" . ' <param value="true" name="allowFullScreen" />' . "\n" . ' <param value="always" name="allowscriptaccess" />' . "\n" . ' <a href="' . $url . '">No video playback capabilities, please download the file</a>' . "\n" . ' </object>' . "\n" . '</video>' . "\n"; } // job done return $output; // a ganttproject timeline // a ganttproject timeline case 'gan': // where the file is $path = Files::get_path($item['anchor']) . '/' . rawurlencode($item['file_name']); // we actually use a transformed version of the file $cache_id = Cache::hash($path) . '.xml'; // apply the transformation if (!file_exists($context['path_to_root'] . $cache_id) || filemtime($context['path_to_root'] . $cache_id) < filemtime($context['path_to_root'] . $path) || !($text = Safe::file_get_contents($context['path_to_root'] . $cache_id))) { // transform from GanttProject to SIMILE Timeline $text = Files::transform_gan_to_simile($path); // put in cache Safe::file_put_contents($cache_id, $text); } // load the SIMILE Timeline javascript library in shared/global.php $context['javascript']['timeline'] = TRUE; // cache would kill the loading of the library cache::poison(); // 1 week ago $now = gmdate('M d Y H:i:s', time() - 7 * 24 * 60 * 60); // load the right file $output = '<div id="gantt" style="height: ' . $height . '; width: ' . $width . '; border: 1px solid #aaa; font-family: Trebuchet MS, Helvetica, Arial, sans serif; font-size: 8pt"></div>' . "\n"; Page::insert_script('var simile_handle;' . "\n" . 'function onLoad() {' . "\n" . ' var eventSource = new Timeline.DefaultEventSource();' . "\n" . ' var theme = Timeline.ClassicTheme.create();' . "\n" . ' theme.event.bubble.width = 350;' . "\n" . ' theme.event.bubble.height = 300;' . "\n" . ' var bandInfos = [' . "\n" . ' Timeline.createBandInfo({' . "\n" . ' eventSource: eventSource,' . "\n" . ' date: "' . $now . '",' . "\n" . ' width: "80%",' . "\n" . ' intervalUnit: Timeline.DateTime.WEEK,' . "\n" . ' intervalPixels: 200,' . "\n" . ' theme: theme,' . "\n" . ' layout: "original" // original, overview, detailed' . "\n" . ' }),' . "\n" . ' Timeline.createBandInfo({' . "\n" . ' showEventText: false,' . "\n" . ' trackHeight: 0.5,' . "\n" . ' trackGap: 0.2,' . "\n" . ' eventSource: eventSource,' . "\n" . ' date: "' . $now . '",' . "\n" . ' width: "20%",' . "\n" . ' intervalUnit: Timeline.DateTime.MONTH,' . "\n" . ' intervalPixels: 50' . "\n" . ' })' . "\n" . ' ];' . "\n" . ' bandInfos[1].syncWith = 0;' . "\n" . ' bandInfos[1].highlight = true;' . "\n" . ' bandInfos[1].eventPainter.setLayout(bandInfos[0].eventPainter.getLayout());' . "\n" . ' simile_handle = Timeline.create(document.getElementById("gantt"), bandInfos, Timeline.HORIZONTAL);' . "\n" . ' simile_handle.showLoadingMessage();' . "\n" . ' Timeline.loadXML("' . $context['url_to_home'] . $context['url_to_root'] . $cache_id . '", function(xml, url) { eventSource.loadXML(xml, url); });' . "\n" . ' simile_handle.hideLoadingMessage();' . "\n" . '}' . "\n" . "\n" . 'var resizeTimerID = null;' . "\n" . 'function onResize() {' . "\n" . ' if (resizeTimerID == null) {' . "\n" . ' resizeTimerID = window.setTimeout(function() {' . "\n" . ' resizeTimerID = null;' . "\n" . ' simile_handle.layout();' . "\n" . ' }, 500);' . "\n" . ' }' . "\n" . '}' . "\n" . "\n" . '// observe page major events' . "\n" . '$(document).ready( onLoad);' . "\n" . '$(window).resize(onResize);' . "\n"); // job done return $output; // a Freemind map // a Freemind map case 'mm': // if we have an external reference, use it if (isset($item['file_href']) && $item['file_href']) { $target_href = $item['file_href']; // else redirect to ourself } else { // ensure a valid file name $file_name = utf8::to_ascii($item['file_name']); // where the file is $path = Files::get_path($item['anchor']) . '/' . rawurlencode($item['file_name']); // map the file on the regular web space $url_prefix = $context['url_to_home'] . $context['url_to_root']; // redirect to the actual file $target_href = $url_prefix . $path; } // allow several viewers to co-exist in the same page static $freemind_viewer_index; if (!isset($freemind_viewer_index)) { $freemind_viewer_index = 1; } else { $freemind_viewer_index++; } // load flash player $url = $context['url_to_home'] . $context['url_to_root'] . 'included/browser/visorFreemind.swf'; // variables $flashvars = 'initLoadFile=' . $target_href . '&openUrl=_self'; $output = '<div id="freemind_viewer_' . $freemind_viewer_index . '">Flash plugin or Javascript are turned off. Activate both and reload to view the object</div>' . "\n"; Page::insert_script('var params = {};' . "\n" . 'params.base = "' . dirname($url) . '/";' . "\n" . 'params.quality = "high";' . "\n" . 'params.wmode = "transparent";' . "\n" . 'params.menu = "false";' . "\n" . 'params.flashvars = "' . $flashvars . '";' . "\n" . 'swfobject.embedSWF("' . $url . '", "freemind_viewer_' . $freemind_viewer_index . '", "' . $width . '", "' . $height . '", "6", "' . $context['url_to_home'] . $context['url_to_root'] . 'included/browser/expressinstall.swf", false, params);' . "\n"); // offer to download a copy of the map $menu = array($target_href => i18n::s('Browse this map with Freemind')); // display menu commands below the viewer $output .= Skin::build_list($menu, 'menu_bar'); // job done return $output; // native flash // native flash case 'swf': // where to get the file if (isset($item['file_href']) && $item['file_href']) { $url = $item['file_href']; } else { $url = $context['url_to_home'] . $context['url_to_root'] . 'files/' . str_replace(':', '/', $item['anchor']) . '/' . rawurlencode($item['file_name']); } $output = '<div id="swf_' . $item['id'] . '" class="no_print">Flash plugin or Javascript are turned off. Activate both and reload to view the object</div>' . "\n"; Page::insert_script('var params = {};' . "\n" . 'params.base = "' . dirname($url) . '/";' . "\n" . 'params.quality = "high";' . "\n" . 'params.wmode = "transparent";' . "\n" . 'params.allowfullscreen = "true";' . "\n" . 'params.allowscriptaccess = "always";' . "\n" . 'params.flashvars = "' . $flashvars . '";' . "\n" . 'swfobject.embedSWF("' . $url . '", "swf_' . $item['id'] . '", "' . $width . '", "' . $height . '", "6", "' . $context['url_to_home'] . $context['url_to_root'] . 'included/browser/expressinstall.swf", false, params);' . "\n"); return $output; // link to file page // link to file page default: // link label $text = Skin::strip($item['title'] ? $item['title'] : str_replace('_', ' ', $item['file_name'])); // make a link to the target page $url = Files::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text); return $output; } }
if (!$fetched) { // increment the count of downloads if (!Surfer::is_crawler()) { Files::increment_hits($item['id']); } // record surfer activity Activities::post('file:' . $item['id'], 'fetch'); } // no encoding, no compression and no yacs handler... if (!headers_sent()) { Safe::header('Content-Type: ' . $mime); Safe::header('Content-Length: ' . strlen($text)); } // suggest a download if (!headers_sent()) { $file_name = utf8::to_ascii($item['file_name'] . $type); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
include_once '../services/codec.php'; include_once '../services/rss_codec.php'; $result = rss_Codec::encode($values); $status = @$result[0]; $text = @$result[1]; // save in cache for the next request Cache::put($cache_id, $text, 'articles'); } // // transfer to the user agent // // handle the output correctly render_raw('text/xml; charset=' . $context['charset']); // suggest a name on download if (!headers_sent()) { $file_name = utf8::to_ascii($context['site_name'] . '.section.' . $item['id'] . '.rss.xml'); Safe::header('Content-Disposition: inline; filename="' . str_replace('"', '', $file_name) . '"'); } // enable 30-minute caching (30*60 = 1800), even through https, to help IE6 on download http::expire(1800); // strong validator $etag = '"' . md5($text) . '"'; // manage web cache if (http::validate(NULL, $etag)) { return; } // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $text; } // the post-processing hook, then exit
/** * build and transmit a complex e-mail messages * * This function allows for individual posts, textual and HTML messages, and attached files. * * For this to work, e-mail service has to be explicitly activated in the * main configuration panel, at [script]control/configure.php[/script]. * * You can refer to local images in HTML parts, and the function will automatically attach these * to the message, else mail clients would not display them correctly. * * The message actually sent has a complex structure, with several parts assembled together, * as [explained at altepeter.net|http://altepeter.net/tech/articles/html-emails]. * * @link http://altepeter.net/tech/articles/html-emails * * Several recipients can be provided as a list of addresses separated by * commas. For bulk posts, recipients can be transmitted as an array of strings. * In all cases, this function sends one separate message per recipient. * * This function will ensure that only one mail message is send to a recipient, * by maintaining an internal list of addresses that have been processed. * Therefore, if this function is called several times, with some repeated recipients, * those will receive only the first message, and other messages to the same address * will be dropped. * * Bracketed recipients, such as ##Foo Bar <*****@*****.**>##, are handled properly, * meaning ##foo@bar.com## is transmitted to the mailing function, while * the string ##To: Foo Bar <*****@*****.**>## is added to headers. * * If an array of messages is provided to the function, it is turned to a multi-part * message, as in the following example: * * [php] * $message = array(); * $message['text/plain; charset=utf-8'] = 'This is a plain message'; * $message['text/html'] = '<html><head><body>This is an HTML message</body></html>'; * Mailer::post($from, $to, $subject, $message); * [/php] * * It is recommended to begin with the bare text, and to have the rich format part coming * after, as in the example. Also, if you don't provide a charset, then UTF-8 is used. * * Long lines of text/plain parts are wrapped according to * [link=Dan's suggestion]http://mailformat.dan.info/body/linelength.html[/link]. * * @link http://mailformat.dan.info/body/linelength.html Dan's Mail Format Site: Body: Line Length * * Message parts are encoded either as quoted-printable (textual entities) or as base-64 (others). * * A list of files to be attached to the message can be provided as in the following example: * * [php] * $attachments = array(); * $attachments[] = 'special/report.pdf'; * $attachments[] = 'skins/my_skin/newsletters/image.png'; * Mailer::post($from, $to, $subject, $message, $attachments); * [/php] * * Files are named from the installation directory of yacs, as visible in the examples. * * This function returns the number of successful posts, * and populates the error context, where applicable. * * @param string sender address * @param mixed recipient address(es) * @param string subject * @param mixed actual message, either a string, or an array of message parts * @param array attachments, if any * @param mixed additional headers, if any * @return the number of actual posts, or 0 * * @see articles/mail.php * @see letters/new.php * @see users/mail.php */ public static function post($from, $to, $subject, $message, $attachments = NULL, $headers = '') { global $context; // ensure that we have a sender if (!$from) { $from = Mailer::get_from_recipient(); } // email services have to be activated if (!isset($context['with_email']) || $context['with_email'] != 'Y') { Logger::error(i18n::s('E-mail has not been enabled on this system.')); return 0; // check sender address } elseif (!$from) { Logger::error(i18n::s('Empty sender address')); return 0; // check recipient address } elseif (!$to) { Logger::error(i18n::s('Empty recipient address')); return 0; // check mail subject } elseif (!$subject) { Logger::error(i18n::s('No subject')); return 0; // check mail content } elseif (!$message) { Logger::error(i18n::s('No message')); return 0; } // the end of line string for mail messages if (!defined('M_EOL')) { define('M_EOL', "\n"); } // encode the subject line $subject = Mailer::encode_subject($subject); // make some text out of an array if (is_array($headers)) { $headers = implode(M_EOL, $headers); } // From: header if (!preg_match('/^From: /im', $headers)) { $headers .= M_EOL . 'From: ' . $from; } // Reply-To: header if (!preg_match('/^Reply-To: /im', $headers)) { $headers .= M_EOL . 'Reply-To: ' . $from; } // Return-Path: header --to process errors if (!preg_match('/^Return-Path: /im', $headers)) { $headers .= M_EOL . 'Return-Path: ' . $from; } // Message-ID: header --helps to avoid spam filters if (!preg_match('/^Message-ID: /im', $headers)) { $headers .= M_EOL . 'Message-ID: <uniqid.' . uniqid() . '@' . $context['host_name'] . '>'; } // MIME-Version: header if (!preg_match('/^MIME-Version: /im', $headers)) { $headers .= M_EOL . 'MIME-Version: 1.0'; } // arrays are easier to manage if (is_string($message)) { // turn HTML entities to UTF-8 $message = Safe::html_entity_decode($message, ENT_QUOTES, 'UTF-8'); $copy = $message; $message = array(); $message['text/plain; charset=utf-8'] = $copy; unset($copy); } // turn attachments to some array too if (is_string($attachments)) { $attachments = array($attachments); } elseif (!is_array($attachments)) { $attachments = array(); } // we only consider objects from this server $my_prefix = $context['url_to_home'] . $context['url_to_root']; // transcode objects that will be transmitted along the message (i.e., images) foreach ($message as $type => $part) { // search throughout the full text $head = 0; while ($head = strpos($part, ' src="', $head)) { $head += strlen(' src="'); // a link has been found if ($tail = strpos($part, '"', $head + 1)) { $reference = substr($part, $head, $tail - $head); // remember local links only if (!strncmp($reference, $my_prefix, strlen($my_prefix))) { // local name $name = urldecode(substr($reference, strlen($my_prefix))); // content-id to be used instead of the link $cid = sprintf('%u@%s', crc32($name), $context['host_name']); // transcode the link in this part $part = substr($part, 0, $head) . 'cid:' . $cid . substr($part, $tail); // remember to put content in attachments of this message, if not done yet if (!in_array($name, $attachments)) { $attachments[] = $name; } } } } // remember the transcoded part $message[$type] = $part; } // we need some boundary string if (count($message) + count($attachments) > 1) { $boundary = md5(time()); } // wrapping threshold if (!defined('WRAPPING_LENGTH')) { define('WRAPPING_LENGTH', 70); } // combine message parts $content_type = ''; $body = ''; foreach ($message as $type => $part) { // quote textual entities if (!strncmp($type, 'text/', 5)) { $content_encoding = 'quoted-printable'; $part = quoted_printable_encode($part); // encode everything else } else { $content_encoding = 'base64'; $part = chunk_split(base64_encode($content), 76, M_EOL); } // only one part if (count($message) == 1) { $content_type = $type; $body = $part; // one part among several } else { // let user agent select among various alternatives if (!$content_type) { $content_type = 'multipart/alternative; boundary="' . $boundary . '-internal"'; } // introduction to assembled parts if (!$body) { $body = 'This is a multi-part message in MIME format.'; } // this part only --second EOL is part of the boundary chain $body .= M_EOL . M_EOL . '--' . $boundary . '-internal' . M_EOL . 'Content-Type: ' . $type . M_EOL . 'Content-Transfer-Encoding: ' . $content_encoding . M_EOL . M_EOL . $part; } } // finalize the body if (count($message) > 1) { $body .= M_EOL . M_EOL . '--' . $boundary . '-internal--'; } // a mix of things if (count($attachments)) { // encoding is irrelevant if there are multiple parts if (!strncmp($content_type, 'multipart/', 10)) { $content_encoding = ''; } else { $content_encoding = M_EOL . 'Content-Transfer-Encoding: ' . $content_encoding; } // identify the main part of the overall message $content_start = 'mainpart'; // the current body becomes the first part of a larger message $body = 'This is a multi-part message in MIME format.' . M_EOL . M_EOL . '--' . $boundary . '-external' . M_EOL . 'Content-Type: ' . $content_type . $content_encoding . M_EOL . 'Content-ID: <' . $content_start . '>' . M_EOL . M_EOL . $body; // message parts should be considered as an aggregate whole --see RFC 2387 $content_type = 'multipart/related; type="multipart/alternative"; boundary="' . $boundary . '-external"'; $content_encoding = ''; // process every file foreach ($attachments as $name => $content) { // read external file content if (preg_match('/^[0-9]+$/', $name)) { // only a file name has been provided $name = $content; // read file content from the file system if (!($content = Safe::file_get_contents($name))) { continue; } } // file name is the file type if (preg_match('/name="(.+)?"/', $name, $matches)) { $type = $name; $name = $matches[1]; } else { $type = Files::get_mime_type($name); } // a unique id for for this file $cid = sprintf('%u@%s', crc32($name), $context['host_name']); // set a name that avoids problems $basename = utf8::to_ascii(basename($name)); // headers for one file $body .= M_EOL . M_EOL . '--' . $boundary . '-external' . M_EOL . 'Content-Type: ' . $type . M_EOL . 'Content-Disposition: inline; filename="' . str_replace('"', '', $basename) . '"' . M_EOL . 'Content-ID: <' . $cid . '>'; // transfer textual entities as they are if (!strncmp($type, 'text/', 5)) { $body .= M_EOL . 'Content-Transfer-Encoding: quoted-printable' . M_EOL . M_EOL . quoted_printable_encode($content); // encode everything else } else { $body .= M_EOL . 'Content-Transfer-Encoding: base64' . M_EOL . M_EOL . chunk_split(base64_encode($content), 76, M_EOL); } } // the closing boundary $body .= M_EOL . M_EOL . '--' . $boundary . '-external--'; } // Content-Type: header if ($content_type && !preg_match('/^Content-Type: /im', $headers)) { $headers .= M_EOL . 'Content-Type: ' . $content_type; } // Content-Transfer-Encoding: header if (!isset($boundary) && $content_encoding && !preg_match('/^Content-Transfer-Encoding: /im', $headers)) { $headers .= M_EOL . 'Content-Transfer-Encoding: ' . $content_encoding; } // Start: header if (isset($boundary) && isset($content_start) && $content_start && !preg_match('/^Start: /im', $headers)) { $headers .= M_EOL . 'Start: ' . $content_start; } // X-Mailer: header --helps to avoid spam filters if (!preg_match('/^X-Mailer: /im', $headers)) { $headers .= M_EOL . 'X-Mailer: yacs'; } // strip leading spaces and newlines $headers = trim($headers); // make an array of recipients if (!is_array($to)) { $to = Mailer::explode_recipients($to); } // the list of recipients contacted during overall script execution if (!isset($context['mailer_recipients'])) { $context['mailer_recipients'] = array(); } // process every recipient $posts = 0; foreach ($to as $recipient) { // clean the provided string $recipient = trim(str_replace(array("\r\n", "\r", "\n", "\t"), ' ', $recipient)); // this e-mail address has already been processed if (in_array($recipient, $context['mailer_recipients'])) { if (isset($context['debug_mail']) && $context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: Skipping recipient already processed', $recipient, 'debug'); } continue; // remember this recipient } else { $context['mailer_recipients'][] = $recipient; } // queue the message Mailer::queue($recipient, $subject, $body, $headers); $posts++; } // track last submission include_once $context['path_to_root'] . 'shared/values.php'; Values::set('mailer.last.queued', $subject . ' (' . $posts . ' recipients)'); // return the number of actual posts return $posts; }