First semi-stable version
1292
soundmap/api/getid3.lib.php
Normal file
1757
soundmap/api/getid3.php
Normal file
2011
soundmap/api/module.audio.mp3.php
Normal file
372
soundmap/api/module.tag.apetag.php
Normal file
@ -0,0 +1,372 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.tag.apetag.php //
|
||||
// module for analyzing APE tags //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
class getid3_apetag extends getid3_handler
|
||||
{
|
||||
var $inline_attachments = true; // true: return full data for all attachments; false: return no data for all attachments; integer: return data for attachments <= than this; string: save as file to this directory
|
||||
var $overrideendoffset = 0;
|
||||
|
||||
function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
$id3v1tagsize = 128;
|
||||
$apetagheadersize = 32;
|
||||
$lyrics3tagsize = 10;
|
||||
|
||||
if ($this->overrideendoffset == 0) {
|
||||
|
||||
fseek($this->getid3->fp, 0 - $id3v1tagsize - $apetagheadersize - $lyrics3tagsize, SEEK_END);
|
||||
$APEfooterID3v1 = fread($this->getid3->fp, $id3v1tagsize + $apetagheadersize + $lyrics3tagsize);
|
||||
|
||||
//if (preg_match('/APETAGEX.{24}TAG.{125}$/i', $APEfooterID3v1)) {
|
||||
if (substr($APEfooterID3v1, strlen($APEfooterID3v1) - $id3v1tagsize - $apetagheadersize, 8) == 'APETAGEX') {
|
||||
|
||||
// APE tag found before ID3v1
|
||||
$info['ape']['tag_offset_end'] = $info['filesize'] - $id3v1tagsize;
|
||||
|
||||
//} elseif (preg_match('/APETAGEX.{24}$/i', $APEfooterID3v1)) {
|
||||
} elseif (substr($APEfooterID3v1, strlen($APEfooterID3v1) - $apetagheadersize, 8) == 'APETAGEX') {
|
||||
|
||||
// APE tag found, no ID3v1
|
||||
$info['ape']['tag_offset_end'] = $info['filesize'];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
fseek($this->getid3->fp, $this->overrideendoffset - $apetagheadersize, SEEK_SET);
|
||||
if (fread($this->getid3->fp, 8) == 'APETAGEX') {
|
||||
$info['ape']['tag_offset_end'] = $this->overrideendoffset;
|
||||
}
|
||||
|
||||
}
|
||||
if (!isset($info['ape']['tag_offset_end'])) {
|
||||
|
||||
// APE tag not found
|
||||
unset($info['ape']);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// shortcut
|
||||
$thisfile_ape = &$info['ape'];
|
||||
|
||||
fseek($this->getid3->fp, $thisfile_ape['tag_offset_end'] - $apetagheadersize, SEEK_SET);
|
||||
$APEfooterData = fread($this->getid3->fp, 32);
|
||||
if (!($thisfile_ape['footer'] = $this->parseAPEheaderFooter($APEfooterData))) {
|
||||
$info['error'][] = 'Error parsing APE footer at offset '.$thisfile_ape['tag_offset_end'];
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($thisfile_ape['footer']['flags']['header']) && $thisfile_ape['footer']['flags']['header']) {
|
||||
fseek($this->getid3->fp, $thisfile_ape['tag_offset_end'] - $thisfile_ape['footer']['raw']['tagsize'] - $apetagheadersize, SEEK_SET);
|
||||
$thisfile_ape['tag_offset_start'] = ftell($this->getid3->fp);
|
||||
$APEtagData = fread($this->getid3->fp, $thisfile_ape['footer']['raw']['tagsize'] + $apetagheadersize);
|
||||
} else {
|
||||
$thisfile_ape['tag_offset_start'] = $thisfile_ape['tag_offset_end'] - $thisfile_ape['footer']['raw']['tagsize'];
|
||||
fseek($this->getid3->fp, $thisfile_ape['tag_offset_start'], SEEK_SET);
|
||||
$APEtagData = fread($this->getid3->fp, $thisfile_ape['footer']['raw']['tagsize']);
|
||||
}
|
||||
$info['avdataend'] = $thisfile_ape['tag_offset_start'];
|
||||
|
||||
if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] < $thisfile_ape['tag_offset_end'])) {
|
||||
$info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in APEtag data';
|
||||
unset($info['id3v1']);
|
||||
foreach ($info['warning'] as $key => $value) {
|
||||
if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
|
||||
unset($info['warning'][$key]);
|
||||
sort($info['warning']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$offset = 0;
|
||||
if (isset($thisfile_ape['footer']['flags']['header']) && $thisfile_ape['footer']['flags']['header']) {
|
||||
if ($thisfile_ape['header'] = $this->parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize))) {
|
||||
$offset += $apetagheadersize;
|
||||
} else {
|
||||
$info['error'][] = 'Error parsing APE header at offset '.$thisfile_ape['tag_offset_start'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// shortcut
|
||||
$info['replay_gain'] = array();
|
||||
$thisfile_replaygain = &$info['replay_gain'];
|
||||
|
||||
for ($i = 0; $i < $thisfile_ape['footer']['raw']['tag_items']; $i++) {
|
||||
$value_size = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
|
||||
$offset += 4;
|
||||
$item_flags = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
|
||||
$offset += 4;
|
||||
if (strstr(substr($APEtagData, $offset), "\x00") === false) {
|
||||
$info['error'][] = 'Cannot find null-byte (0x00) seperator between ItemKey #'.$i.' and value. ItemKey starts '.$offset.' bytes into the APE tag, at file offset '.($thisfile_ape['tag_offset_start'] + $offset);
|
||||
return false;
|
||||
}
|
||||
$ItemKeyLength = strpos($APEtagData, "\x00", $offset) - $offset;
|
||||
$item_key = strtolower(substr($APEtagData, $offset, $ItemKeyLength));
|
||||
|
||||
// shortcut
|
||||
$thisfile_ape['items'][$item_key] = array();
|
||||
$thisfile_ape_items_current = &$thisfile_ape['items'][$item_key];
|
||||
|
||||
$thisfile_ape_items_current['offset'] = $thisfile_ape['tag_offset_start'] + $offset;
|
||||
|
||||
$offset += ($ItemKeyLength + 1); // skip 0x00 terminator
|
||||
$thisfile_ape_items_current['data'] = substr($APEtagData, $offset, $value_size);
|
||||
$offset += $value_size;
|
||||
|
||||
$thisfile_ape_items_current['flags'] = $this->parseAPEtagFlags($item_flags);
|
||||
switch ($thisfile_ape_items_current['flags']['item_contents_raw']) {
|
||||
case 0: // UTF-8
|
||||
case 3: // Locator (URL, filename, etc), UTF-8 encoded
|
||||
$thisfile_ape_items_current['data'] = explode("\x00", trim($thisfile_ape_items_current['data']));
|
||||
break;
|
||||
|
||||
default: // binary data
|
||||
break;
|
||||
}
|
||||
|
||||
switch (strtolower($item_key)) {
|
||||
case 'replaygain_track_gain':
|
||||
$thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['track']['originator'] = 'unspecified';
|
||||
break;
|
||||
|
||||
case 'replaygain_track_peak':
|
||||
$thisfile_replaygain['track']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['track']['originator'] = 'unspecified';
|
||||
if ($thisfile_replaygain['track']['peak'] <= 0) {
|
||||
$info['warning'][] = 'ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'replaygain_album_gain':
|
||||
$thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['album']['originator'] = 'unspecified';
|
||||
break;
|
||||
|
||||
case 'replaygain_album_peak':
|
||||
$thisfile_replaygain['album']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['album']['originator'] = 'unspecified';
|
||||
if ($thisfile_replaygain['album']['peak'] <= 0) {
|
||||
$info['warning'][] = 'ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mp3gain_undo':
|
||||
list($mp3gain_undo_left, $mp3gain_undo_right, $mp3gain_undo_wrap) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['undo_left'] = intval($mp3gain_undo_left);
|
||||
$thisfile_replaygain['mp3gain']['undo_right'] = intval($mp3gain_undo_right);
|
||||
$thisfile_replaygain['mp3gain']['undo_wrap'] = (($mp3gain_undo_wrap == 'Y') ? true : false);
|
||||
break;
|
||||
|
||||
case 'mp3gain_minmax':
|
||||
list($mp3gain_globalgain_min, $mp3gain_globalgain_max) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_track_min'] = intval($mp3gain_globalgain_min);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_track_max'] = intval($mp3gain_globalgain_max);
|
||||
break;
|
||||
|
||||
case 'mp3gain_album_minmax':
|
||||
list($mp3gain_globalgain_album_min, $mp3gain_globalgain_album_max) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_album_min'] = intval($mp3gain_globalgain_album_min);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_album_max'] = intval($mp3gain_globalgain_album_max);
|
||||
break;
|
||||
|
||||
case 'tracknumber':
|
||||
if (is_array($thisfile_ape_items_current['data'])) {
|
||||
foreach ($thisfile_ape_items_current['data'] as $comment) {
|
||||
$thisfile_ape['comments']['track'][] = $comment;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'cover art (artist)':
|
||||
case 'cover art (back)':
|
||||
case 'cover art (band logo)':
|
||||
case 'cover art (band)':
|
||||
case 'cover art (colored fish)':
|
||||
case 'cover art (composer)':
|
||||
case 'cover art (conductor)':
|
||||
case 'cover art (front)':
|
||||
case 'cover art (icon)':
|
||||
case 'cover art (illustration)':
|
||||
case 'cover art (lead)':
|
||||
case 'cover art (leaflet)':
|
||||
case 'cover art (lyricist)':
|
||||
case 'cover art (media)':
|
||||
case 'cover art (movie scene)':
|
||||
case 'cover art (other icon)':
|
||||
case 'cover art (other)':
|
||||
case 'cover art (performance)':
|
||||
case 'cover art (publisher logo)':
|
||||
case 'cover art (recording)':
|
||||
case 'cover art (studio)':
|
||||
// list of possible cover arts from http://taglib-sharp.sourcearchive.com/documentation/2.0.3.0-2/Ape_2Tag_8cs-source.html
|
||||
list($thisfile_ape_items_current['filename'], $thisfile_ape_items_current['data']) = explode("\x00", $thisfile_ape_items_current['data'], 2);
|
||||
$thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00");
|
||||
$thisfile_ape_items_current['data_length'] = strlen($thisfile_ape_items_current['data']);
|
||||
|
||||
$thisfile_ape_items_current['image_mime'] = '';
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
|
||||
$thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
|
||||
|
||||
do {
|
||||
if ($this->inline_attachments === false) {
|
||||
// skip entirely
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
if ($this->inline_attachments === true) {
|
||||
// great
|
||||
} elseif (is_int($this->inline_attachments)) {
|
||||
if ($this->inline_attachments < $thisfile_ape_items_current['data_length']) {
|
||||
// too big, skip
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' is too large to process inline ('.number_format($thisfile_ape_items_current['data_length']).' bytes)';
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
} elseif (is_string($this->inline_attachments)) {
|
||||
$this->inline_attachments = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->inline_attachments), DIRECTORY_SEPARATOR);
|
||||
if (!is_dir($this->inline_attachments) || !is_writable($this->inline_attachments)) {
|
||||
// cannot write, skip
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$this->inline_attachments.'" (not writable)';
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we get this far, must be OK
|
||||
if (is_string($this->inline_attachments)) {
|
||||
$destination_filename = $this->inline_attachments.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$thisfile_ape_items_current['data_offset'];
|
||||
if (!file_exists($destination_filename) || is_writable($destination_filename)) {
|
||||
file_put_contents($destination_filename, $thisfile_ape_items_current['data']);
|
||||
} else {
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$destination_filename.'" (not writable)';
|
||||
}
|
||||
$thisfile_ape_items_current['data_filename'] = $destination_filename;
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
} else {
|
||||
if (!isset($info['ape']['comments']['picture'])) {
|
||||
$info['ape']['comments']['picture'] = array();
|
||||
}
|
||||
$info['ape']['comments']['picture'][] = array('data'=>$thisfile_ape_items_current['data'], 'image_mime'=>$thisfile_ape_items_current['image_mime']);
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (is_array($thisfile_ape_items_current['data'])) {
|
||||
foreach ($thisfile_ape_items_current['data'] as $comment) {
|
||||
$thisfile_ape['comments'][strtolower($item_key)][] = $comment;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (empty($thisfile_replaygain)) {
|
||||
unset($info['replay_gain']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseAPEheaderFooter($APEheaderFooterData) {
|
||||
// http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html
|
||||
|
||||
// shortcut
|
||||
$headerfooterinfo['raw'] = array();
|
||||
$headerfooterinfo_raw = &$headerfooterinfo['raw'];
|
||||
|
||||
$headerfooterinfo_raw['footer_tag'] = substr($APEheaderFooterData, 0, 8);
|
||||
if ($headerfooterinfo_raw['footer_tag'] != 'APETAGEX') {
|
||||
return false;
|
||||
}
|
||||
$headerfooterinfo_raw['version'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 8, 4));
|
||||
$headerfooterinfo_raw['tagsize'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 12, 4));
|
||||
$headerfooterinfo_raw['tag_items'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 16, 4));
|
||||
$headerfooterinfo_raw['global_flags'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 20, 4));
|
||||
$headerfooterinfo_raw['reserved'] = substr($APEheaderFooterData, 24, 8);
|
||||
|
||||
$headerfooterinfo['tag_version'] = $headerfooterinfo_raw['version'] / 1000;
|
||||
if ($headerfooterinfo['tag_version'] >= 2) {
|
||||
$headerfooterinfo['flags'] = $this->parseAPEtagFlags($headerfooterinfo_raw['global_flags']);
|
||||
}
|
||||
return $headerfooterinfo;
|
||||
}
|
||||
|
||||
function parseAPEtagFlags($rawflagint) {
|
||||
// "Note: APE Tags 1.0 do not use any of the APE Tag flags.
|
||||
// All are set to zero on creation and ignored on reading."
|
||||
// http://www.uni-jena.de/~pfk/mpp/sv8/apetagflags.html
|
||||
$flags['header'] = (bool) ($rawflagint & 0x80000000);
|
||||
$flags['footer'] = (bool) ($rawflagint & 0x40000000);
|
||||
$flags['this_is_header'] = (bool) ($rawflagint & 0x20000000);
|
||||
$flags['item_contents_raw'] = ($rawflagint & 0x00000006) >> 1;
|
||||
$flags['read_only'] = (bool) ($rawflagint & 0x00000001);
|
||||
|
||||
$flags['item_contents'] = $this->APEcontentTypeFlagLookup($flags['item_contents_raw']);
|
||||
|
||||
return $flags;
|
||||
}
|
||||
|
||||
function APEcontentTypeFlagLookup($contenttypeid) {
|
||||
static $APEcontentTypeFlagLookup = array(
|
||||
0 => 'utf-8',
|
||||
1 => 'binary',
|
||||
2 => 'external',
|
||||
3 => 'reserved'
|
||||
);
|
||||
return (isset($APEcontentTypeFlagLookup[$contenttypeid]) ? $APEcontentTypeFlagLookup[$contenttypeid] : 'invalid');
|
||||
}
|
||||
|
||||
function APEtagItemIsUTF8Lookup($itemkey) {
|
||||
static $APEtagItemIsUTF8Lookup = array(
|
||||
'title',
|
||||
'subtitle',
|
||||
'artist',
|
||||
'album',
|
||||
'debut album',
|
||||
'publisher',
|
||||
'conductor',
|
||||
'track',
|
||||
'composer',
|
||||
'comment',
|
||||
'copyright',
|
||||
'publicationright',
|
||||
'file',
|
||||
'year',
|
||||
'record date',
|
||||
'record location',
|
||||
'genre',
|
||||
'media',
|
||||
'related',
|
||||
'isrc',
|
||||
'abstract',
|
||||
'language',
|
||||
'bibliography'
|
||||
);
|
||||
return in_array(strtolower($itemkey), $APEtagItemIsUTF8Lookup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
362
soundmap/api/module.tag.id3v1.php
Normal file
@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.tag.id3v1.php //
|
||||
// module for analyzing ID3v1 tags //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class getid3_id3v1 extends getid3_handler
|
||||
{
|
||||
|
||||
function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for ID3v1 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek($this->getid3->fp, -256, SEEK_END);
|
||||
$preid3v1 = fread($this->getid3->fp, 128);
|
||||
$id3v1tag = fread($this->getid3->fp, 128);
|
||||
|
||||
if (substr($id3v1tag, 0, 3) == 'TAG') {
|
||||
|
||||
$info['avdataend'] = $info['filesize'] - 128;
|
||||
|
||||
$ParsedID3v1['title'] = $this->cutfield(substr($id3v1tag, 3, 30));
|
||||
$ParsedID3v1['artist'] = $this->cutfield(substr($id3v1tag, 33, 30));
|
||||
$ParsedID3v1['album'] = $this->cutfield(substr($id3v1tag, 63, 30));
|
||||
$ParsedID3v1['year'] = $this->cutfield(substr($id3v1tag, 93, 4));
|
||||
$ParsedID3v1['comment'] = substr($id3v1tag, 97, 30); // can't remove nulls yet, track detection depends on them
|
||||
$ParsedID3v1['genreid'] = ord(substr($id3v1tag, 127, 1));
|
||||
|
||||
// If second-last byte of comment field is null and last byte of comment field is non-null
|
||||
// then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number
|
||||
if (($id3v1tag{125} === "\x00") && ($id3v1tag{126} !== "\x00")) {
|
||||
$ParsedID3v1['track'] = ord(substr($ParsedID3v1['comment'], 29, 1));
|
||||
$ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28);
|
||||
}
|
||||
$ParsedID3v1['comment'] = $this->cutfield($ParsedID3v1['comment']);
|
||||
|
||||
$ParsedID3v1['genre'] = $this->LookupGenreName($ParsedID3v1['genreid']);
|
||||
if (!empty($ParsedID3v1['genre'])) {
|
||||
unset($ParsedID3v1['genreid']);
|
||||
}
|
||||
if (isset($ParsedID3v1['genre']) && (empty($ParsedID3v1['genre']) || ($ParsedID3v1['genre'] == 'Unknown'))) {
|
||||
unset($ParsedID3v1['genre']);
|
||||
}
|
||||
|
||||
foreach ($ParsedID3v1 as $key => $value) {
|
||||
$ParsedID3v1['comments'][$key][0] = $value;
|
||||
}
|
||||
|
||||
// ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces
|
||||
$GoodFormatID3v1tag = $this->GenerateID3v1Tag(
|
||||
$ParsedID3v1['title'],
|
||||
$ParsedID3v1['artist'],
|
||||
$ParsedID3v1['album'],
|
||||
$ParsedID3v1['year'],
|
||||
(isset($ParsedID3v1['genre']) ? $this->LookupGenreID($ParsedID3v1['genre']) : false),
|
||||
$ParsedID3v1['comment'],
|
||||
(!empty($ParsedID3v1['track']) ? $ParsedID3v1['track'] : ''));
|
||||
$ParsedID3v1['padding_valid'] = true;
|
||||
if ($id3v1tag !== $GoodFormatID3v1tag) {
|
||||
$ParsedID3v1['padding_valid'] = false;
|
||||
$info['warning'][] = 'Some ID3v1 fields do not use NULL characters for padding';
|
||||
}
|
||||
|
||||
$ParsedID3v1['tag_offset_end'] = $info['filesize'];
|
||||
$ParsedID3v1['tag_offset_start'] = $ParsedID3v1['tag_offset_end'] - 128;
|
||||
|
||||
$info['id3v1'] = $ParsedID3v1;
|
||||
}
|
||||
|
||||
if (substr($preid3v1, 0, 3) == 'TAG') {
|
||||
// The way iTunes handles tags is, well, brain-damaged.
|
||||
// It completely ignores v1 if ID3v2 is present.
|
||||
// This goes as far as adding a new v1 tag *even if there already is one*
|
||||
|
||||
// A suspected double-ID3v1 tag has been detected, but it could be that
|
||||
// the "TAG" identifier is a legitimate part of an APE or Lyrics3 tag
|
||||
if (substr($preid3v1, 96, 8) == 'APETAGEX') {
|
||||
// an APE tag footer was found before the last ID3v1, assume false "TAG" synch
|
||||
} elseif (substr($preid3v1, 119, 6) == 'LYRICS') {
|
||||
// a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch
|
||||
} else {
|
||||
// APE and Lyrics3 footers not found - assume double ID3v1
|
||||
$info['warning'][] = 'Duplicate ID3v1 tag detected - this has been known to happen with iTunes';
|
||||
$info['avdataend'] -= 128;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function cutfield($str) {
|
||||
return trim(substr($str, 0, strcspn($str, "\x00")));
|
||||
}
|
||||
|
||||
static function ArrayOfGenres($allowSCMPXextended=false) {
|
||||
static $GenreLookup = array(
|
||||
0 => 'Blues',
|
||||
1 => 'Classic Rock',
|
||||
2 => 'Country',
|
||||
3 => 'Dance',
|
||||
4 => 'Disco',
|
||||
5 => 'Funk',
|
||||
6 => 'Grunge',
|
||||
7 => 'Hip-Hop',
|
||||
8 => 'Jazz',
|
||||
9 => 'Metal',
|
||||
10 => 'New Age',
|
||||
11 => 'Oldies',
|
||||
12 => 'Other',
|
||||
13 => 'Pop',
|
||||
14 => 'R&B',
|
||||
15 => 'Rap',
|
||||
16 => 'Reggae',
|
||||
17 => 'Rock',
|
||||
18 => 'Techno',
|
||||
19 => 'Industrial',
|
||||
20 => 'Alternative',
|
||||
21 => 'Ska',
|
||||
22 => 'Death Metal',
|
||||
23 => 'Pranks',
|
||||
24 => 'Soundtrack',
|
||||
25 => 'Euro-Techno',
|
||||
26 => 'Ambient',
|
||||
27 => 'Trip-Hop',
|
||||
28 => 'Vocal',
|
||||
29 => 'Jazz+Funk',
|
||||
30 => 'Fusion',
|
||||
31 => 'Trance',
|
||||
32 => 'Classical',
|
||||
33 => 'Instrumental',
|
||||
34 => 'Acid',
|
||||
35 => 'House',
|
||||
36 => 'Game',
|
||||
37 => 'Sound Clip',
|
||||
38 => 'Gospel',
|
||||
39 => 'Noise',
|
||||
40 => 'Alt. Rock',
|
||||
41 => 'Bass',
|
||||
42 => 'Soul',
|
||||
43 => 'Punk',
|
||||
44 => 'Space',
|
||||
45 => 'Meditative',
|
||||
46 => 'Instrumental Pop',
|
||||
47 => 'Instrumental Rock',
|
||||
48 => 'Ethnic',
|
||||
49 => 'Gothic',
|
||||
50 => 'Darkwave',
|
||||
51 => 'Techno-Industrial',
|
||||
52 => 'Electronic',
|
||||
53 => 'Pop-Folk',
|
||||
54 => 'Eurodance',
|
||||
55 => 'Dream',
|
||||
56 => 'Southern Rock',
|
||||
57 => 'Comedy',
|
||||
58 => 'Cult',
|
||||
59 => 'Gangsta Rap',
|
||||
60 => 'Top 40',
|
||||
61 => 'Christian Rap',
|
||||
62 => 'Pop/Funk',
|
||||
63 => 'Jungle',
|
||||
64 => 'Native American',
|
||||
65 => 'Cabaret',
|
||||
66 => 'New Wave',
|
||||
67 => 'Psychedelic',
|
||||
68 => 'Rave',
|
||||
69 => 'Showtunes',
|
||||
70 => 'Trailer',
|
||||
71 => 'Lo-Fi',
|
||||
72 => 'Tribal',
|
||||
73 => 'Acid Punk',
|
||||
74 => 'Acid Jazz',
|
||||
75 => 'Polka',
|
||||
76 => 'Retro',
|
||||
77 => 'Musical',
|
||||
78 => 'Rock & Roll',
|
||||
79 => 'Hard Rock',
|
||||
80 => 'Folk',
|
||||
81 => 'Folk/Rock',
|
||||
82 => 'National Folk',
|
||||
83 => 'Swing',
|
||||
84 => 'Fast-Fusion',
|
||||
85 => 'Bebob',
|
||||
86 => 'Latin',
|
||||
87 => 'Revival',
|
||||
88 => 'Celtic',
|
||||
89 => 'Bluegrass',
|
||||
90 => 'Avantgarde',
|
||||
91 => 'Gothic Rock',
|
||||
92 => 'Progressive Rock',
|
||||
93 => 'Psychedelic Rock',
|
||||
94 => 'Symphonic Rock',
|
||||
95 => 'Slow Rock',
|
||||
96 => 'Big Band',
|
||||
97 => 'Chorus',
|
||||
98 => 'Easy Listening',
|
||||
99 => 'Acoustic',
|
||||
100 => 'Humour',
|
||||
101 => 'Speech',
|
||||
102 => 'Chanson',
|
||||
103 => 'Opera',
|
||||
104 => 'Chamber Music',
|
||||
105 => 'Sonata',
|
||||
106 => 'Symphony',
|
||||
107 => 'Booty Bass',
|
||||
108 => 'Primus',
|
||||
109 => 'Porn Groove',
|
||||
110 => 'Satire',
|
||||
111 => 'Slow Jam',
|
||||
112 => 'Club',
|
||||
113 => 'Tango',
|
||||
114 => 'Samba',
|
||||
115 => 'Folklore',
|
||||
116 => 'Ballad',
|
||||
117 => 'Power Ballad',
|
||||
118 => 'Rhythmic Soul',
|
||||
119 => 'Freestyle',
|
||||
120 => 'Duet',
|
||||
121 => 'Punk Rock',
|
||||
122 => 'Drum Solo',
|
||||
123 => 'A Cappella',
|
||||
124 => 'Euro-House',
|
||||
125 => 'Dance Hall',
|
||||
126 => 'Goa',
|
||||
127 => 'Drum & Bass',
|
||||
128 => 'Club-House',
|
||||
129 => 'Hardcore',
|
||||
130 => 'Terror',
|
||||
131 => 'Indie',
|
||||
132 => 'BritPop',
|
||||
133 => 'Negerpunk',
|
||||
134 => 'Polsk Punk',
|
||||
135 => 'Beat',
|
||||
136 => 'Christian Gangsta Rap',
|
||||
137 => 'Heavy Metal',
|
||||
138 => 'Black Metal',
|
||||
139 => 'Crossover',
|
||||
140 => 'Contemporary Christian',
|
||||
141 => 'Christian Rock',
|
||||
142 => 'Merengue',
|
||||
143 => 'Salsa',
|
||||
144 => 'Trash Metal',
|
||||
145 => 'Anime',
|
||||
146 => 'JPop',
|
||||
147 => 'Synthpop',
|
||||
|
||||
255 => 'Unknown',
|
||||
|
||||
'CR' => 'Cover',
|
||||
'RX' => 'Remix'
|
||||
);
|
||||
|
||||
static $GenreLookupSCMPX = array();
|
||||
if ($allowSCMPXextended && empty($GenreLookupSCMPX)) {
|
||||
$GenreLookupSCMPX = $GenreLookup;
|
||||
// http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended
|
||||
// Extended ID3v1 genres invented by SCMPX
|
||||
// Note that 255 "Japanese Anime" conflicts with standard "Unknown"
|
||||
$GenreLookupSCMPX[240] = 'Sacred';
|
||||
$GenreLookupSCMPX[241] = 'Northern Europe';
|
||||
$GenreLookupSCMPX[242] = 'Irish & Scottish';
|
||||
$GenreLookupSCMPX[243] = 'Scotland';
|
||||
$GenreLookupSCMPX[244] = 'Ethnic Europe';
|
||||
$GenreLookupSCMPX[245] = 'Enka';
|
||||
$GenreLookupSCMPX[246] = 'Children\'s Song';
|
||||
$GenreLookupSCMPX[247] = 'Japanese Sky';
|
||||
$GenreLookupSCMPX[248] = 'Japanese Heavy Rock';
|
||||
$GenreLookupSCMPX[249] = 'Japanese Doom Rock';
|
||||
$GenreLookupSCMPX[250] = 'Japanese J-POP';
|
||||
$GenreLookupSCMPX[251] = 'Japanese Seiyu';
|
||||
$GenreLookupSCMPX[252] = 'Japanese Ambient Techno';
|
||||
$GenreLookupSCMPX[253] = 'Japanese Moemoe';
|
||||
$GenreLookupSCMPX[254] = 'Japanese Tokusatsu';
|
||||
//$GenreLookupSCMPX[255] = 'Japanese Anime';
|
||||
}
|
||||
|
||||
return ($allowSCMPXextended ? $GenreLookupSCMPX : $GenreLookup);
|
||||
}
|
||||
|
||||
static function LookupGenreName($genreid, $allowSCMPXextended=true) {
|
||||
switch ($genreid) {
|
||||
case 'RX':
|
||||
case 'CR':
|
||||
break;
|
||||
default:
|
||||
if (!is_numeric($genreid)) {
|
||||
return false;
|
||||
}
|
||||
$genreid = intval($genreid); // to handle 3 or '3' or '03'
|
||||
break;
|
||||
}
|
||||
$GenreLookup = getid3_id3v1::ArrayOfGenres($allowSCMPXextended);
|
||||
return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false);
|
||||
}
|
||||
|
||||
static function LookupGenreID($genre, $allowSCMPXextended=false) {
|
||||
$GenreLookup = getid3_id3v1::ArrayOfGenres($allowSCMPXextended);
|
||||
$LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre));
|
||||
foreach ($GenreLookup as $key => $value) {
|
||||
if (strtolower(str_replace(' ', '', $value)) == $LowerCaseNoSpaceSearchTerm) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function StandardiseID3v1GenreName($OriginalGenre) {
|
||||
if (($GenreID = getid3_id3v1::LookupGenreID($OriginalGenre)) !== false) {
|
||||
return getid3_id3v1::LookupGenreName($GenreID);
|
||||
}
|
||||
return $OriginalGenre;
|
||||
}
|
||||
|
||||
static function GenerateID3v1Tag($title, $artist, $album, $year, $genreid, $comment, $track='') {
|
||||
$ID3v1Tag = 'TAG';
|
||||
$ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($artist, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($album, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($year, 0, 4)), 4, "\x00", STR_PAD_LEFT);
|
||||
if (!empty($track) && ($track > 0) && ($track <= 255)) {
|
||||
$ID3v1Tag .= str_pad(trim(substr($comment, 0, 28)), 28, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= "\x00";
|
||||
if (gettype($track) == 'string') {
|
||||
$track = (int) $track;
|
||||
}
|
||||
$ID3v1Tag .= chr($track);
|
||||
} else {
|
||||
$ID3v1Tag .= str_pad(trim(substr($comment, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
if (($genreid < 0) || ($genreid > 147)) {
|
||||
$genreid = 255; // 'unknown' genre
|
||||
}
|
||||
switch (gettype($genreid)) {
|
||||
case 'string':
|
||||
case 'integer':
|
||||
$ID3v1Tag .= chr(intval($genreid));
|
||||
break;
|
||||
default:
|
||||
$ID3v1Tag .= chr(255); // 'unknown' genre
|
||||
break;
|
||||
}
|
||||
|
||||
return $ID3v1Tag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
3303
soundmap/api/module.tag.id3v2.php
Normal file
297
soundmap/api/module.tag.lyrics3.php
Normal file
@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// //
|
||||
// module.tag.lyrics3.php //
|
||||
// module for analyzing Lyrics3 tags //
|
||||
// dependencies: module.tag.apetag.php (optional) //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class getid3_lyrics3 extends getid3_handler
|
||||
{
|
||||
|
||||
function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
// http://www.volweb.cz/str/tags.htm
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek($this->getid3->fp, (0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - "LYRICSEND" - [Lyrics3size]
|
||||
$lyrics3_id3v1 = fread($this->getid3->fp, 128 + 9 + 6);
|
||||
$lyrics3lsz = substr($lyrics3_id3v1, 0, 6); // Lyrics3size
|
||||
$lyrics3end = substr($lyrics3_id3v1, 6, 9); // LYRICSEND or LYRICS200
|
||||
$id3v1tag = substr($lyrics3_id3v1, 15, 128); // ID3v1
|
||||
|
||||
if ($lyrics3end == 'LYRICSEND') {
|
||||
// Lyrics3v1, ID3v1, no APE
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
|
||||
$lyrics3version = 1;
|
||||
|
||||
} elseif ($lyrics3end == 'LYRICS200') {
|
||||
// Lyrics3v2, ID3v1, no APE
|
||||
|
||||
// LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200');
|
||||
$lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
|
||||
} elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICSEND')) {
|
||||
// Lyrics3v1, no ID3v1, no APE
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
$lyrics3version = 1;
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
|
||||
} elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) {
|
||||
|
||||
// Lyrics3v2, no ID3v1, no APE
|
||||
|
||||
$lyrics3size = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
|
||||
} else {
|
||||
|
||||
if (isset($info['ape']['tag_offset_start']) && ($info['ape']['tag_offset_start'] > 15)) {
|
||||
|
||||
fseek($this->getid3->fp, $info['ape']['tag_offset_start'] - 15, SEEK_SET);
|
||||
$lyrics3lsz = fread($this->getid3->fp, 6);
|
||||
$lyrics3end = fread($this->getid3->fp, 9);
|
||||
|
||||
if ($lyrics3end == 'LYRICSEND') {
|
||||
// Lyrics3v1, APE, maybe ID3v1
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
|
||||
$info['avdataend'] = $lyrics3offset;
|
||||
$lyrics3version = 1;
|
||||
$info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
|
||||
|
||||
} elseif ($lyrics3end == 'LYRICS200') {
|
||||
// Lyrics3v2, APE, maybe ID3v1
|
||||
|
||||
$lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
$info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($lyrics3offset)) {
|
||||
$info['avdataend'] = $lyrics3offset;
|
||||
$this->getLyrics3Data($lyrics3offset, $lyrics3version, $lyrics3size);
|
||||
|
||||
if (!isset($info['ape'])) {
|
||||
$GETID3_ERRORARRAY = &$info['warning'];
|
||||
if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, false)) {
|
||||
$getid3_temp = new getID3();
|
||||
$getid3_temp->openfile($this->getid3->filename);
|
||||
$getid3_apetag = new getid3_apetag($getid3_temp);
|
||||
$getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
|
||||
$getid3_apetag->Analyze();
|
||||
if (!empty($getid3_temp->info['ape'])) {
|
||||
$info['ape'] = $getid3_temp->info['ape'];
|
||||
}
|
||||
if (!empty($getid3_temp->info['replay_gain'])) {
|
||||
$info['replay_gain'] = $getid3_temp->info['replay_gain'];
|
||||
}
|
||||
unset($getid3_temp, $getid3_apetag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLyrics3Data($endoffset, $version, $length) {
|
||||
// http://www.volweb.cz/str/tags.htm
|
||||
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($endoffset)) {
|
||||
$info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek($this->getid3->fp, $endoffset, SEEK_SET);
|
||||
if ($length <= 0) {
|
||||
return false;
|
||||
}
|
||||
$rawdata = fread($this->getid3->fp, $length);
|
||||
|
||||
$ParsedLyrics3['raw']['lyrics3version'] = $version;
|
||||
$ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
|
||||
$ParsedLyrics3['tag_offset_start'] = $endoffset;
|
||||
$ParsedLyrics3['tag_offset_end'] = $endoffset + $length - 1;
|
||||
|
||||
if (substr($rawdata, 0, 11) != 'LYRICSBEGIN') {
|
||||
if (strpos($rawdata, 'LYRICSBEGIN') !== false) {
|
||||
|
||||
$info['warning'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but actually found at '.($endoffset + strpos($rawdata, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$version;
|
||||
$info['avdataend'] = $endoffset + strpos($rawdata, 'LYRICSBEGIN');
|
||||
$rawdata = substr($rawdata, strpos($rawdata, 'LYRICSBEGIN'));
|
||||
$length = strlen($rawdata);
|
||||
$ParsedLyrics3['tag_offset_start'] = $info['avdataend'];
|
||||
$ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
|
||||
|
||||
} else {
|
||||
|
||||
$info['error'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but found "'.substr($rawdata, 0, 11).'" instead';
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch ($version) {
|
||||
|
||||
case 1:
|
||||
if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICSEND') {
|
||||
$ParsedLyrics3['raw']['LYR'] = trim(substr($rawdata, 11, strlen($rawdata) - 11 - 9));
|
||||
$this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
|
||||
} else {
|
||||
$info['error'][] = '"LYRICSEND" expected at '.(ftell($this->getid3->fp) - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICS200') {
|
||||
$ParsedLyrics3['raw']['unparsed'] = substr($rawdata, 11, strlen($rawdata) - 11 - 9 - 6); // LYRICSBEGIN + LYRICS200 + LSZ
|
||||
$rawdata = $ParsedLyrics3['raw']['unparsed'];
|
||||
while (strlen($rawdata) > 0) {
|
||||
$fieldname = substr($rawdata, 0, 3);
|
||||
$fieldsize = (int) substr($rawdata, 3, 5);
|
||||
$ParsedLyrics3['raw'][$fieldname] = substr($rawdata, 8, $fieldsize);
|
||||
$rawdata = substr($rawdata, 3 + 5 + $fieldsize);
|
||||
}
|
||||
|
||||
if (isset($ParsedLyrics3['raw']['IND'])) {
|
||||
$i = 0;
|
||||
$flagnames = array('lyrics', 'timestamps', 'inhibitrandom');
|
||||
foreach ($flagnames as $flagname) {
|
||||
if (strlen($ParsedLyrics3['raw']['IND']) > $i++) {
|
||||
$ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1 - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fieldnametranslation = array('ETT'=>'title', 'EAR'=>'artist', 'EAL'=>'album', 'INF'=>'comment', 'AUT'=>'author');
|
||||
foreach ($fieldnametranslation as $key => $value) {
|
||||
if (isset($ParsedLyrics3['raw'][$key])) {
|
||||
$ParsedLyrics3['comments'][$value][] = trim($ParsedLyrics3['raw'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($ParsedLyrics3['raw']['IMG'])) {
|
||||
$imagestrings = explode("\r\n", $ParsedLyrics3['raw']['IMG']);
|
||||
foreach ($imagestrings as $key => $imagestring) {
|
||||
if (strpos($imagestring, '||') !== false) {
|
||||
$imagearray = explode('||', $imagestring);
|
||||
$ParsedLyrics3['images'][$key]['filename'] = (isset($imagearray[0]) ? $imagearray[0] : '');
|
||||
$ParsedLyrics3['images'][$key]['description'] = (isset($imagearray[1]) ? $imagearray[1] : '');
|
||||
$ParsedLyrics3['images'][$key]['timestamp'] = $this->Lyrics3Timestamp2Seconds(isset($imagearray[2]) ? $imagearray[2] : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($ParsedLyrics3['raw']['LYR'])) {
|
||||
$this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
|
||||
}
|
||||
} else {
|
||||
$info['error'][] = '"LYRICS200" expected at '.(ftell($this->getid3->fp) - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$info['error'][] = 'Cannot process Lyrics3 version '.$version.' (only v1 and v2)';
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] <= $ParsedLyrics3['tag_offset_end'])) {
|
||||
$info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data';
|
||||
unset($info['id3v1']);
|
||||
foreach ($info['warning'] as $key => $value) {
|
||||
if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
|
||||
unset($info['warning'][$key]);
|
||||
sort($info['warning']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$info['lyrics3'] = $ParsedLyrics3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function Lyrics3Timestamp2Seconds($rawtimestamp) {
|
||||
if (preg_match('#^\\[([0-9]{2}):([0-9]{2})\\]$#', $rawtimestamp, $regs)) {
|
||||
return (int) (($regs[1] * 60) + $regs[2]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function Lyrics3LyricsTimestampParse(&$Lyrics3data) {
|
||||
$lyricsarray = explode("\r\n", $Lyrics3data['raw']['LYR']);
|
||||
foreach ($lyricsarray as $key => $lyricline) {
|
||||
$regs = array();
|
||||
unset($thislinetimestamps);
|
||||
while (preg_match('#^(\\[[0-9]{2}:[0-9]{2}\\])#', $lyricline, $regs)) {
|
||||
$thislinetimestamps[] = $this->Lyrics3Timestamp2Seconds($regs[0]);
|
||||
$lyricline = str_replace($regs[0], '', $lyricline);
|
||||
}
|
||||
$notimestamplyricsarray[$key] = $lyricline;
|
||||
if (isset($thislinetimestamps) && is_array($thislinetimestamps)) {
|
||||
sort($thislinetimestamps);
|
||||
foreach ($thislinetimestamps as $timestampkey => $timestamp) {
|
||||
if (isset($Lyrics3data['synchedlyrics'][$timestamp])) {
|
||||
// timestamps only have a 1-second resolution, it's possible that multiple lines
|
||||
// could have the same timestamp, if so, append
|
||||
$Lyrics3data['synchedlyrics'][$timestamp] .= "\r\n".$lyricline;
|
||||
} else {
|
||||
$Lyrics3data['synchedlyrics'][$timestamp] = $lyricline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$Lyrics3data['unsynchedlyrics'] = implode("\r\n", $notimestamplyricsarray);
|
||||
if (isset($Lyrics3data['synchedlyrics']) && is_array($Lyrics3data['synchedlyrics'])) {
|
||||
ksort($Lyrics3data['synchedlyrics']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function IntString2Bool($char) {
|
||||
if ($char == '1') {
|
||||
return true;
|
||||
} elseif ($char == '0') {
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
766
soundmap/api/module.tag.xmp.php
Normal file
@ -0,0 +1,766 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.tag.xmp.php //
|
||||
// module for analyzing XMP metadata (e.g. in JPEG files) //
|
||||
// dependencies: NONE //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Module originally written [2009-Mar-26] by //
|
||||
// Nigel Barnes <ngbarnesØhotmail*com> //
|
||||
// Bundled into getID3 with permission //
|
||||
// called by getID3 in module.graphic.jpg.php //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**************************************************************************************************
|
||||
* SWISScenter Source Nigel Barnes
|
||||
*
|
||||
* Provides functions for reading information from the 'APP1' Extensible Metadata
|
||||
* Platform (XMP) segment of JPEG format files.
|
||||
* This XMP segment is XML based and contains the Resource Description Framework (RDF)
|
||||
* data, which itself can contain the Dublin Core Metadata Initiative (DCMI) information.
|
||||
*
|
||||
* This code uses segments from the JPEG Metadata Toolkit project by Evan Hunter.
|
||||
*************************************************************************************************/
|
||||
class Image_XMP
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* The name of the image file that contains the XMP fields to extract and modify.
|
||||
* @see Image_XMP()
|
||||
*/
|
||||
var $_sFilename = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* The XMP fields that were extracted from the image or updated by this class.
|
||||
* @see getAllTags()
|
||||
*/
|
||||
var $_aXMP = array();
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* True if an APP1 segment was found to contain XMP metadata.
|
||||
* @see isValid()
|
||||
*/
|
||||
var $_bXMPParse = false;
|
||||
|
||||
/**
|
||||
* Returns the status of XMP parsing during instantiation
|
||||
*
|
||||
* You'll normally want to call this method before trying to get XMP fields.
|
||||
*
|
||||
* @return boolean
|
||||
* Returns true if an APP1 segment was found to contain XMP metadata.
|
||||
*/
|
||||
function isValid()
|
||||
{
|
||||
return $this->_bXMPParse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of all XMP tags extracted from the image
|
||||
*
|
||||
* @return array - An array of XMP fields as it extracted by the XMPparse() function
|
||||
*/
|
||||
function getAllTags()
|
||||
{
|
||||
return $this->_aXMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the JPEG header segments from an JPEG image file into an array
|
||||
*
|
||||
* @param string $filename - the filename of the JPEG file to read
|
||||
* @return array $headerdata - Array of JPEG header segments
|
||||
* @return boolean FALSE - if headers could not be read
|
||||
*/
|
||||
function _get_jpeg_header_data($filename)
|
||||
{
|
||||
// prevent refresh from aborting file operations and hosing file
|
||||
ignore_user_abort(true);
|
||||
|
||||
// Attempt to open the jpeg file - the at symbol supresses the error message about
|
||||
// not being able to open files. The file_exists would have been used, but it
|
||||
// does not work with files fetched over http or ftp.
|
||||
if (is_readable($filename) && is_file($filename) && ($filehnd = fopen($filename, 'rb'))) {
|
||||
// great
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the first two characters
|
||||
$data = fread($filehnd, 2);
|
||||
|
||||
// Check that the first two characters are 0xFF 0xD8 (SOI - Start of image)
|
||||
if ($data != "\xFF\xD8")
|
||||
{
|
||||
// No SOI (FF D8) at start of file - This probably isn't a JPEG file - close file and return;
|
||||
echo '<p>This probably is not a JPEG file</p>'."\n";
|
||||
fclose($filehnd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the third character
|
||||
$data = fread($filehnd, 2);
|
||||
|
||||
// Check that the third character is 0xFF (Start of first segment header)
|
||||
if ($data{0} != "\xFF")
|
||||
{
|
||||
// NO FF found - close file and return - JPEG is probably corrupted
|
||||
fclose($filehnd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Flag that we havent yet hit the compressed image data
|
||||
$hit_compressed_image_data = false;
|
||||
|
||||
// Cycle through the file until, one of: 1) an EOI (End of image) marker is hit,
|
||||
// 2) we have hit the compressed image data (no more headers are allowed after data)
|
||||
// 3) or end of file is hit
|
||||
|
||||
while (($data{1} != "\xD9") && (!$hit_compressed_image_data) && (!feof($filehnd)))
|
||||
{
|
||||
// Found a segment to look at.
|
||||
// Check that the segment marker is not a Restart marker - restart markers don't have size or data after them
|
||||
if ((ord($data{1}) < 0xD0) || (ord($data{1}) > 0xD7))
|
||||
{
|
||||
// Segment isn't a Restart marker
|
||||
// Read the next two bytes (size)
|
||||
$sizestr = fread($filehnd, 2);
|
||||
|
||||
// convert the size bytes to an integer
|
||||
$decodedsize = unpack('nsize', $sizestr);
|
||||
|
||||
// Save the start position of the data
|
||||
$segdatastart = ftell($filehnd);
|
||||
|
||||
// Read the segment data with length indicated by the previously read size
|
||||
$segdata = fread($filehnd, $decodedsize['size'] - 2);
|
||||
|
||||
// Store the segment information in the output array
|
||||
$headerdata[] = array(
|
||||
'SegType' => ord($data{1}),
|
||||
'SegName' => $GLOBALS['JPEG_Segment_Names'][ord($data{1})],
|
||||
'SegDataStart' => $segdatastart,
|
||||
'SegData' => $segdata,
|
||||
);
|
||||
}
|
||||
|
||||
// If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows
|
||||
if ($data{1} == "\xDA")
|
||||
{
|
||||
// Flag that we have hit the compressed image data - exit loop as no more headers available.
|
||||
$hit_compressed_image_data = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not an SOS - Read the next two bytes - should be the segment marker for the next segment
|
||||
$data = fread($filehnd, 2);
|
||||
|
||||
// Check that the first byte of the two is 0xFF as it should be for a marker
|
||||
if ($data{0} != "\xFF")
|
||||
{
|
||||
// NO FF found - close file and return - JPEG is probably corrupted
|
||||
fclose($filehnd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close File
|
||||
fclose($filehnd);
|
||||
// Alow the user to abort from now on
|
||||
ignore_user_abort(false);
|
||||
|
||||
// Return the header data retrieved
|
||||
return $headerdata;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves XMP information from an APP1 JPEG segment and returns the raw XML text as a string.
|
||||
*
|
||||
* @param string $filename - the filename of the JPEG file to read
|
||||
* @return string $xmp_data - the string of raw XML text
|
||||
* @return boolean FALSE - if an APP 1 XMP segment could not be found, or if an error occured
|
||||
*/
|
||||
function _get_XMP_text($filename)
|
||||
{
|
||||
//Get JPEG header data
|
||||
$jpeg_header_data = $this->_get_jpeg_header_data($filename);
|
||||
|
||||
//Cycle through the header segments
|
||||
for ($i = 0; $i < count($jpeg_header_data); $i++)
|
||||
{
|
||||
// If we find an APP1 header,
|
||||
if (strcmp($jpeg_header_data[$i]['SegName'], 'APP1') == 0)
|
||||
{
|
||||
// And if it has the Adobe XMP/RDF label (http://ns.adobe.com/xap/1.0/\x00) ,
|
||||
if (strncmp($jpeg_header_data[$i]['SegData'], 'http://ns.adobe.com/xap/1.0/'."\x00", 29) == 0)
|
||||
{
|
||||
// Found a XMP/RDF block
|
||||
// Return the XMP text
|
||||
$xmp_data = substr($jpeg_header_data[$i]['SegData'], 29);
|
||||
|
||||
return trim($xmp_data); // trim() should not be neccesary, but some files found in the wild with null-terminated block (known samples from Apple Aperture) causes problems elsewhere (see http://www.getid3.org/phpBB3/viewtopic.php?f=4&t=1153)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string containing XMP data (XML), and returns an array
|
||||
* which contains all the XMP (XML) information.
|
||||
*
|
||||
* @param string $xml_text - a string containing the XMP data (XML) to be parsed
|
||||
* @return array $xmp_array - an array containing all xmp details retrieved.
|
||||
* @return boolean FALSE - couldn't parse the XMP data
|
||||
*/
|
||||
function read_XMP_array_from_text($xmltext)
|
||||
{
|
||||
// Check if there actually is any text to parse
|
||||
if (trim($xmltext) == '')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create an instance of a xml parser to parse the XML text
|
||||
$xml_parser = xml_parser_create('UTF-8');
|
||||
|
||||
// Change: Fixed problem that caused the whitespace (especially newlines) to be destroyed when converting xml text to an xml array, as of revision 1.10
|
||||
|
||||
// We would like to remove unneccessary white space, but this will also
|
||||
// remove things like newlines (
) in the XML values, so white space
|
||||
// will have to be removed later
|
||||
if (xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0) == false)
|
||||
{
|
||||
// Error setting case folding - destroy the parser and return
|
||||
xml_parser_free($xml_parser);
|
||||
return false;
|
||||
}
|
||||
|
||||
// to use XML code correctly we have to turn case folding
|
||||
// (uppercasing) off. XML is case sensitive and upper
|
||||
// casing is in reality XML standards violation
|
||||
if (xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0) == false)
|
||||
{
|
||||
// Error setting case folding - destroy the parser and return
|
||||
xml_parser_free($xml_parser);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the XML text into a array structure
|
||||
if (xml_parse_into_struct($xml_parser, $xmltext, $values, $tags) == 0)
|
||||
{
|
||||
// Error Parsing XML - destroy the parser and return
|
||||
xml_parser_free($xml_parser);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy the xml parser
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
// Clear the output array
|
||||
$xmp_array = array();
|
||||
|
||||
// The XMP data has now been parsed into an array ...
|
||||
|
||||
// Cycle through each of the array elements
|
||||
$current_property = ''; // current property being processed
|
||||
$container_index = -1; // -1 = no container open, otherwise index of container content
|
||||
foreach ($values as $xml_elem)
|
||||
{
|
||||
// Syntax and Class names
|
||||
switch ($xml_elem['tag'])
|
||||
{
|
||||
case 'x:xmpmeta':
|
||||
// only defined attribute is x:xmptk written by Adobe XMP Toolkit; value is the version of the toolkit
|
||||
break;
|
||||
|
||||
case 'rdf:RDF':
|
||||
// required element immediately within x:xmpmeta; no data here
|
||||
break;
|
||||
|
||||
case 'rdf:Description':
|
||||
switch ($xml_elem['type'])
|
||||
{
|
||||
case 'open':
|
||||
case 'complete':
|
||||
if (array_key_exists('attributes', $xml_elem))
|
||||
{
|
||||
// rdf:Description may contain wanted attributes
|
||||
foreach (array_keys($xml_elem['attributes']) as $key)
|
||||
{
|
||||
// Check whether we want this details from this attribute
|
||||
if (in_array($key, $GLOBALS['XMP_tag_captions']))
|
||||
{
|
||||
// Attribute wanted
|
||||
$xmp_array[$key] = $xml_elem['attributes'][$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'cdata':
|
||||
case 'close':
|
||||
break;
|
||||
}
|
||||
|
||||
case 'rdf:ID':
|
||||
case 'rdf:nodeID':
|
||||
// Attributes are ignored
|
||||
break;
|
||||
|
||||
case 'rdf:li':
|
||||
// Property member
|
||||
if ($xml_elem['type'] == 'complete')
|
||||
{
|
||||
if (array_key_exists('attributes', $xml_elem))
|
||||
{
|
||||
// If Lang Alt (language alternatives) then ensure we take the default language
|
||||
if (isset($xml_elem['attributes']['xml:lang']) && ($xml_elem['attributes']['xml:lang'] != 'x-default'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($current_property != '')
|
||||
{
|
||||
$xmp_array[$current_property][$container_index] = (isset($xml_elem['value']) ? $xml_elem['value'] : '');
|
||||
$container_index += 1;
|
||||
}
|
||||
//else unidentified attribute!!
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rdf:Seq':
|
||||
case 'rdf:Bag':
|
||||
case 'rdf:Alt':
|
||||
// Container found
|
||||
switch ($xml_elem['type'])
|
||||
{
|
||||
case 'open':
|
||||
$container_index = 0;
|
||||
break;
|
||||
case 'close':
|
||||
$container_index = -1;
|
||||
break;
|
||||
case 'cdata':
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Check whether we want the details from this attribute
|
||||
if (in_array($xml_elem['tag'], $GLOBALS['XMP_tag_captions']))
|
||||
{
|
||||
switch ($xml_elem['type'])
|
||||
{
|
||||
case 'open':
|
||||
// open current element
|
||||
$current_property = $xml_elem['tag'];
|
||||
break;
|
||||
|
||||
case 'close':
|
||||
// close current element
|
||||
$current_property = '';
|
||||
break;
|
||||
|
||||
case 'complete':
|
||||
// store attribute value
|
||||
$xmp_array[$xml_elem['tag']] = (isset($xml_elem['value']) ? $xml_elem['value'] : '');
|
||||
break;
|
||||
|
||||
case 'cdata':
|
||||
// ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return $xmp_array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string - Name of the image file to access and extract XMP information from.
|
||||
*/
|
||||
function Image_XMP($sFilename)
|
||||
{
|
||||
$this->_sFilename = $sFilename;
|
||||
|
||||
if (is_file($this->_sFilename))
|
||||
{
|
||||
// Get XMP data
|
||||
$xmp_data = $this->_get_XMP_text($sFilename);
|
||||
if ($xmp_data)
|
||||
{
|
||||
$this->_aXMP = $this->read_XMP_array_from_text($xmp_data);
|
||||
$this->_bXMPParse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Global Variable: XMP_tag_captions
|
||||
*
|
||||
* The Property names of all known XMP fields.
|
||||
* Note: this is a full list with unrequired properties commented out.
|
||||
*/
|
||||
$GLOBALS['XMP_tag_captions'] = array(
|
||||
// IPTC Core
|
||||
'Iptc4xmpCore:CiAdrCity',
|
||||
'Iptc4xmpCore:CiAdrCtry',
|
||||
'Iptc4xmpCore:CiAdrExtadr',
|
||||
'Iptc4xmpCore:CiAdrPcode',
|
||||
'Iptc4xmpCore:CiAdrRegion',
|
||||
'Iptc4xmpCore:CiEmailWork',
|
||||
'Iptc4xmpCore:CiTelWork',
|
||||
'Iptc4xmpCore:CiUrlWork',
|
||||
'Iptc4xmpCore:CountryCode',
|
||||
'Iptc4xmpCore:CreatorContactInfo',
|
||||
'Iptc4xmpCore:IntellectualGenre',
|
||||
'Iptc4xmpCore:Location',
|
||||
'Iptc4xmpCore:Scene',
|
||||
'Iptc4xmpCore:SubjectCode',
|
||||
// Dublin Core Schema
|
||||
'dc:contributor',
|
||||
'dc:coverage',
|
||||
'dc:creator',
|
||||
'dc:date',
|
||||
'dc:description',
|
||||
'dc:format',
|
||||
'dc:identifier',
|
||||
'dc:language',
|
||||
'dc:publisher',
|
||||
'dc:relation',
|
||||
'dc:rights',
|
||||
'dc:source',
|
||||
'dc:subject',
|
||||
'dc:title',
|
||||
'dc:type',
|
||||
// XMP Basic Schema
|
||||
'xmp:Advisory',
|
||||
'xmp:BaseURL',
|
||||
'xmp:CreateDate',
|
||||
'xmp:CreatorTool',
|
||||
'xmp:Identifier',
|
||||
'xmp:Label',
|
||||
'xmp:MetadataDate',
|
||||
'xmp:ModifyDate',
|
||||
'xmp:Nickname',
|
||||
'xmp:Rating',
|
||||
'xmp:Thumbnails',
|
||||
'xmpidq:Scheme',
|
||||
// XMP Rights Management Schema
|
||||
'xmpRights:Certificate',
|
||||
'xmpRights:Marked',
|
||||
'xmpRights:Owner',
|
||||
'xmpRights:UsageTerms',
|
||||
'xmpRights:WebStatement',
|
||||
// These are not in spec but Photoshop CS seems to use them
|
||||
'xap:Advisory',
|
||||
'xap:BaseURL',
|
||||
'xap:CreateDate',
|
||||
'xap:CreatorTool',
|
||||
'xap:Identifier',
|
||||
'xap:MetadataDate',
|
||||
'xap:ModifyDate',
|
||||
'xap:Nickname',
|
||||
'xap:Rating',
|
||||
'xap:Thumbnails',
|
||||
'xapidq:Scheme',
|
||||
'xapRights:Certificate',
|
||||
'xapRights:Copyright',
|
||||
'xapRights:Marked',
|
||||
'xapRights:Owner',
|
||||
'xapRights:UsageTerms',
|
||||
'xapRights:WebStatement',
|
||||
// XMP Media Management Schema
|
||||
'xapMM:DerivedFrom',
|
||||
'xapMM:DocumentID',
|
||||
'xapMM:History',
|
||||
'xapMM:InstanceID',
|
||||
'xapMM:ManagedFrom',
|
||||
'xapMM:Manager',
|
||||
'xapMM:ManageTo',
|
||||
'xapMM:ManageUI',
|
||||
'xapMM:ManagerVariant',
|
||||
'xapMM:RenditionClass',
|
||||
'xapMM:RenditionParams',
|
||||
'xapMM:VersionID',
|
||||
'xapMM:Versions',
|
||||
'xapMM:LastURL',
|
||||
'xapMM:RenditionOf',
|
||||
'xapMM:SaveID',
|
||||
// XMP Basic Job Ticket Schema
|
||||
'xapBJ:JobRef',
|
||||
// XMP Paged-Text Schema
|
||||
'xmpTPg:MaxPageSize',
|
||||
'xmpTPg:NPages',
|
||||
'xmpTPg:Fonts',
|
||||
'xmpTPg:Colorants',
|
||||
'xmpTPg:PlateNames',
|
||||
// Adobe PDF Schema
|
||||
'pdf:Keywords',
|
||||
'pdf:PDFVersion',
|
||||
'pdf:Producer',
|
||||
// Photoshop Schema
|
||||
'photoshop:AuthorsPosition',
|
||||
'photoshop:CaptionWriter',
|
||||
'photoshop:Category',
|
||||
'photoshop:City',
|
||||
'photoshop:Country',
|
||||
'photoshop:Credit',
|
||||
'photoshop:DateCreated',
|
||||
'photoshop:Headline',
|
||||
'photoshop:History',
|
||||
// Not in XMP spec
|
||||
'photoshop:Instructions',
|
||||
'photoshop:Source',
|
||||
'photoshop:State',
|
||||
'photoshop:SupplementalCategories',
|
||||
'photoshop:TransmissionReference',
|
||||
'photoshop:Urgency',
|
||||
// EXIF Schemas
|
||||
'tiff:ImageWidth',
|
||||
'tiff:ImageLength',
|
||||
'tiff:BitsPerSample',
|
||||
'tiff:Compression',
|
||||
'tiff:PhotometricInterpretation',
|
||||
'tiff:Orientation',
|
||||
'tiff:SamplesPerPixel',
|
||||
'tiff:PlanarConfiguration',
|
||||
'tiff:YCbCrSubSampling',
|
||||
'tiff:YCbCrPositioning',
|
||||
'tiff:XResolution',
|
||||
'tiff:YResolution',
|
||||
'tiff:ResolutionUnit',
|
||||
'tiff:TransferFunction',
|
||||
'tiff:WhitePoint',
|
||||
'tiff:PrimaryChromaticities',
|
||||
'tiff:YCbCrCoefficients',
|
||||
'tiff:ReferenceBlackWhite',
|
||||
'tiff:DateTime',
|
||||
'tiff:ImageDescription',
|
||||
'tiff:Make',
|
||||
'tiff:Model',
|
||||
'tiff:Software',
|
||||
'tiff:Artist',
|
||||
'tiff:Copyright',
|
||||
'exif:ExifVersion',
|
||||
'exif:FlashpixVersion',
|
||||
'exif:ColorSpace',
|
||||
'exif:ComponentsConfiguration',
|
||||
'exif:CompressedBitsPerPixel',
|
||||
'exif:PixelXDimension',
|
||||
'exif:PixelYDimension',
|
||||
'exif:MakerNote',
|
||||
'exif:UserComment',
|
||||
'exif:RelatedSoundFile',
|
||||
'exif:DateTimeOriginal',
|
||||
'exif:DateTimeDigitized',
|
||||
'exif:ExposureTime',
|
||||
'exif:FNumber',
|
||||
'exif:ExposureProgram',
|
||||
'exif:SpectralSensitivity',
|
||||
'exif:ISOSpeedRatings',
|
||||
'exif:OECF',
|
||||
'exif:ShutterSpeedValue',
|
||||
'exif:ApertureValue',
|
||||
'exif:BrightnessValue',
|
||||
'exif:ExposureBiasValue',
|
||||
'exif:MaxApertureValue',
|
||||
'exif:SubjectDistance',
|
||||
'exif:MeteringMode',
|
||||
'exif:LightSource',
|
||||
'exif:Flash',
|
||||
'exif:FocalLength',
|
||||
'exif:SubjectArea',
|
||||
'exif:FlashEnergy',
|
||||
'exif:SpatialFrequencyResponse',
|
||||
'exif:FocalPlaneXResolution',
|
||||
'exif:FocalPlaneYResolution',
|
||||
'exif:FocalPlaneResolutionUnit',
|
||||
'exif:SubjectLocation',
|
||||
'exif:SensingMethod',
|
||||
'exif:FileSource',
|
||||
'exif:SceneType',
|
||||
'exif:CFAPattern',
|
||||
'exif:CustomRendered',
|
||||
'exif:ExposureMode',
|
||||
'exif:WhiteBalance',
|
||||
'exif:DigitalZoomRatio',
|
||||
'exif:FocalLengthIn35mmFilm',
|
||||
'exif:SceneCaptureType',
|
||||
'exif:GainControl',
|
||||
'exif:Contrast',
|
||||
'exif:Saturation',
|
||||
'exif:Sharpness',
|
||||
'exif:DeviceSettingDescription',
|
||||
'exif:SubjectDistanceRange',
|
||||
'exif:ImageUniqueID',
|
||||
'exif:GPSVersionID',
|
||||
'exif:GPSLatitude',
|
||||
'exif:GPSLongitude',
|
||||
'exif:GPSAltitudeRef',
|
||||
'exif:GPSAltitude',
|
||||
'exif:GPSTimeStamp',
|
||||
'exif:GPSSatellites',
|
||||
'exif:GPSStatus',
|
||||
'exif:GPSMeasureMode',
|
||||
'exif:GPSDOP',
|
||||
'exif:GPSSpeedRef',
|
||||
'exif:GPSSpeed',
|
||||
'exif:GPSTrackRef',
|
||||
'exif:GPSTrack',
|
||||
'exif:GPSImgDirectionRef',
|
||||
'exif:GPSImgDirection',
|
||||
'exif:GPSMapDatum',
|
||||
'exif:GPSDestLatitude',
|
||||
'exif:GPSDestLongitude',
|
||||
'exif:GPSDestBearingRef',
|
||||
'exif:GPSDestBearing',
|
||||
'exif:GPSDestDistanceRef',
|
||||
'exif:GPSDestDistance',
|
||||
'exif:GPSProcessingMethod',
|
||||
'exif:GPSAreaInformation',
|
||||
'exif:GPSDifferential',
|
||||
'stDim:w',
|
||||
'stDim:h',
|
||||
'stDim:unit',
|
||||
'xapGImg:height',
|
||||
'xapGImg:width',
|
||||
'xapGImg:format',
|
||||
'xapGImg:image',
|
||||
'stEvt:action',
|
||||
'stEvt:instanceID',
|
||||
'stEvt:parameters',
|
||||
'stEvt:softwareAgent',
|
||||
'stEvt:when',
|
||||
'stRef:instanceID',
|
||||
'stRef:documentID',
|
||||
'stRef:versionID',
|
||||
'stRef:renditionClass',
|
||||
'stRef:renditionParams',
|
||||
'stRef:manager',
|
||||
'stRef:managerVariant',
|
||||
'stRef:manageTo',
|
||||
'stRef:manageUI',
|
||||
'stVer:comments',
|
||||
'stVer:event',
|
||||
'stVer:modifyDate',
|
||||
'stVer:modifier',
|
||||
'stVer:version',
|
||||
'stJob:name',
|
||||
'stJob:id',
|
||||
'stJob:url',
|
||||
// Exif Flash
|
||||
'exif:Fired',
|
||||
'exif:Return',
|
||||
'exif:Mode',
|
||||
'exif:Function',
|
||||
'exif:RedEyeMode',
|
||||
// Exif OECF/SFR
|
||||
'exif:Columns',
|
||||
'exif:Rows',
|
||||
'exif:Names',
|
||||
'exif:Values',
|
||||
// Exif CFAPattern
|
||||
'exif:Columns',
|
||||
'exif:Rows',
|
||||
'exif:Values',
|
||||
// Exif DeviceSettings
|
||||
'exif:Columns',
|
||||
'exif:Rows',
|
||||
'exif:Settings',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Global Variable: JPEG_Segment_Names
|
||||
*
|
||||
* The names of the JPEG segment markers, indexed by their marker number
|
||||
*/
|
||||
$GLOBALS['JPEG_Segment_Names'] = array(
|
||||
0x01 => 'TEM',
|
||||
0x02 => 'RES',
|
||||
0xC0 => 'SOF0',
|
||||
0xC1 => 'SOF1',
|
||||
0xC2 => 'SOF2',
|
||||
0xC3 => 'SOF4',
|
||||
0xC4 => 'DHT',
|
||||
0xC5 => 'SOF5',
|
||||
0xC6 => 'SOF6',
|
||||
0xC7 => 'SOF7',
|
||||
0xC8 => 'JPG',
|
||||
0xC9 => 'SOF9',
|
||||
0xCA => 'SOF10',
|
||||
0xCB => 'SOF11',
|
||||
0xCC => 'DAC',
|
||||
0xCD => 'SOF13',
|
||||
0xCE => 'SOF14',
|
||||
0xCF => 'SOF15',
|
||||
0xD0 => 'RST0',
|
||||
0xD1 => 'RST1',
|
||||
0xD2 => 'RST2',
|
||||
0xD3 => 'RST3',
|
||||
0xD4 => 'RST4',
|
||||
0xD5 => 'RST5',
|
||||
0xD6 => 'RST6',
|
||||
0xD7 => 'RST7',
|
||||
0xD8 => 'SOI',
|
||||
0xD9 => 'EOI',
|
||||
0xDA => 'SOS',
|
||||
0xDB => 'DQT',
|
||||
0xDC => 'DNL',
|
||||
0xDD => 'DRI',
|
||||
0xDE => 'DHP',
|
||||
0xDF => 'EXP',
|
||||
0xE0 => 'APP0',
|
||||
0xE1 => 'APP1',
|
||||
0xE2 => 'APP2',
|
||||
0xE3 => 'APP3',
|
||||
0xE4 => 'APP4',
|
||||
0xE5 => 'APP5',
|
||||
0xE6 => 'APP6',
|
||||
0xE7 => 'APP7',
|
||||
0xE8 => 'APP8',
|
||||
0xE9 => 'APP9',
|
||||
0xEA => 'APP10',
|
||||
0xEB => 'APP11',
|
||||
0xEC => 'APP12',
|
||||
0xED => 'APP13',
|
||||
0xEE => 'APP14',
|
||||
0xEF => 'APP15',
|
||||
0xF0 => 'JPG0',
|
||||
0xF1 => 'JPG1',
|
||||
0xF2 => 'JPG2',
|
||||
0xF3 => 'JPG3',
|
||||
0xF4 => 'JPG4',
|
||||
0xF5 => 'JPG5',
|
||||
0xF6 => 'JPG6',
|
||||
0xF7 => 'JPG7',
|
||||
0xF8 => 'JPG8',
|
||||
0xF9 => 'JPG9',
|
||||
0xFA => 'JPG10',
|
||||
0xFB => 'JPG11',
|
||||
0xFC => 'JPG12',
|
||||
0xFD => 'JPG13',
|
||||
0xFE => 'COM',
|
||||
);
|
||||
|
||||
?>
|
448
soundmap/css/jplayer.blue.monday.css
Normal file
@ -0,0 +1,448 @@
|
||||
/*
|
||||
* Skin for jPlayer Plugin (jQuery JavaScript Library)
|
||||
* http://www.happyworm.com/jquery/jplayer
|
||||
*
|
||||
* Skin Name: Blue Monday
|
||||
*
|
||||
* Copyright (c) 2010 Happyworm Ltd
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* - http://www.opensource.org/licenses/mit-license.php
|
||||
* - http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Author: Silvia Benvenuti
|
||||
* Skin Version: 3.0 (jPlayer 2.0.0)
|
||||
* Date: 20th December 2010
|
||||
*/
|
||||
|
||||
div.jp-audio,
|
||||
div.jp-video {
|
||||
|
||||
/* Edit the font-size to counteract inherited font sizing.
|
||||
* Eg. 1.25em = 1 / 0.8em
|
||||
*/
|
||||
|
||||
font-size:1.25em;
|
||||
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
line-height:1.6;
|
||||
color: #666;
|
||||
}
|
||||
div.jp-audio {
|
||||
width:420px;
|
||||
}
|
||||
div.jp-video-270p {
|
||||
width:480px;
|
||||
}
|
||||
div.jp-video-360p {
|
||||
width:640px;
|
||||
}
|
||||
div.jp-interface {
|
||||
position: relative;
|
||||
background-color:#eee;
|
||||
/* width:418px; */
|
||||
width:100%;
|
||||
border:1px solid #009be3;
|
||||
}
|
||||
div.jp-audio div.jp-type-single div.jp-interface {
|
||||
height:80px;
|
||||
border-bottom:none;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist div.jp-interface {
|
||||
height:80px;
|
||||
}
|
||||
div.jp-video div.jp-type-single div.jp-interface {
|
||||
height:60px;
|
||||
border-bottom:none;
|
||||
}
|
||||
div.jp-video div.jp-type-playlist div.jp-interface {
|
||||
height:60px;
|
||||
}
|
||||
div.jp-interface ul.jp-controls {
|
||||
list-style-type:none;
|
||||
padding:0;
|
||||
margin: 0;
|
||||
}
|
||||
div.jp-interface ul.jp-controls li {
|
||||
/* position: absolute; */
|
||||
display:inline;
|
||||
}
|
||||
div.jp-interface ul.jp-controls a {
|
||||
position: absolute;
|
||||
overflow:hidden;
|
||||
text-indent:-9999px;
|
||||
}
|
||||
a.jp-play,
|
||||
a.jp-pause {
|
||||
width:40px;
|
||||
height:40px;
|
||||
z-index:1;
|
||||
}
|
||||
div.jp-audio div.jp-type-single a.jp-play,
|
||||
div.jp-audio div.jp-type-single a.jp-pause {
|
||||
top:20px;
|
||||
left:40px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist a.jp-play,
|
||||
div.jp-audio div.jp-type-playlist a.jp-pause {
|
||||
top:20px;
|
||||
left:48px;
|
||||
}
|
||||
div.jp-video a.jp-play,
|
||||
div.jp-video a.jp-pause {
|
||||
top:15px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-single a.jp-play,
|
||||
div.jp-video-270p div.jp-type-single a.jp-pause {
|
||||
left:195px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-play,
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-pause {
|
||||
left:220px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-single a.jp-play,
|
||||
div.jp-video-360p div.jp-type-single a.jp-pause {
|
||||
left:275px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-play,
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-pause {
|
||||
left:300px;
|
||||
}
|
||||
a.jp-play {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 0 no-repeat;
|
||||
}
|
||||
a.jp-play:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -41px 0 no-repeat;
|
||||
}
|
||||
a.jp-pause {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -42px no-repeat;
|
||||
display: none;
|
||||
}
|
||||
a.jp-pause:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -41px -42px no-repeat;
|
||||
}
|
||||
div.jp-audio div.jp-type-single a.jp-stop {
|
||||
top:26px;
|
||||
left:90px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist a.jp-stop {
|
||||
top:26px;
|
||||
left:126px;
|
||||
}
|
||||
div.jp-video a.jp-stop {
|
||||
top:21px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-single a.jp-stop {
|
||||
left:245px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-stop {
|
||||
left:298px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-single a.jp-stop {
|
||||
left:325px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-stop {
|
||||
left:378px;
|
||||
}
|
||||
a.jp-stop {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -83px no-repeat;
|
||||
width:28px;
|
||||
height:28px;
|
||||
z-index:1;
|
||||
}
|
||||
a.jp-stop:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -29px -83px no-repeat;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist a.jp-previous {
|
||||
left:20px;
|
||||
top:26px;
|
||||
}
|
||||
div.jp-video div.jp-type-playlist a.jp-previous {
|
||||
top:21px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-previous {
|
||||
left:192px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-previous {
|
||||
left:272px;
|
||||
}
|
||||
a.jp-previous {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -112px no-repeat;
|
||||
width:28px;
|
||||
height:28px;
|
||||
}
|
||||
a.jp-previous:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -29px -112px no-repeat;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist a.jp-next {
|
||||
left:88px;
|
||||
top:26px;
|
||||
}
|
||||
div.jp-video div.jp-type-playlist a.jp-next {
|
||||
top:21px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-next {
|
||||
left:260px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-next {
|
||||
left:340px;
|
||||
}
|
||||
a.jp-next {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -141px no-repeat;
|
||||
width:28px;
|
||||
height:28px;
|
||||
}
|
||||
a.jp-next:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -29px -141px no-repeat;
|
||||
}
|
||||
div.jp-progress {
|
||||
position: absolute;
|
||||
overflow:hidden;
|
||||
background-color: #ddd;
|
||||
}
|
||||
div.jp-audio div.jp-type-single div.jp-progress {
|
||||
top:32px;
|
||||
left:130px;
|
||||
width:122px;
|
||||
height:15px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist div.jp-progress {
|
||||
top:32px;
|
||||
left:164px;
|
||||
width:122px;
|
||||
height:15px;
|
||||
}
|
||||
div.jp-video div.jp-progress {
|
||||
top:0px;
|
||||
left:0px;
|
||||
width:100%;
|
||||
height:10px;
|
||||
}
|
||||
div.jp-seek-bar {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -202px repeat-x;
|
||||
width:0px;
|
||||
/* height:15px; */
|
||||
height:100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
div.jp-play-bar {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -218px repeat-x ;
|
||||
width:0px;
|
||||
/* height:15px; */
|
||||
height:100%;
|
||||
}
|
||||
|
||||
/* The seeking class is added/removed inside jPlayer */
|
||||
div.jp-seeking-bg {
|
||||
background: url("../img/pbar-ani.gif");
|
||||
}
|
||||
|
||||
a.jp-mute,
|
||||
a.jp-unmute {
|
||||
width:18px;
|
||||
height:15px;
|
||||
}
|
||||
div.jp-audio div.jp-type-single a.jp-mute,
|
||||
div.jp-audio div.jp-type-single a.jp-unmute {
|
||||
top:32px;
|
||||
left:274px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist a.jp-mute,
|
||||
div.jp-audio div.jp-type-playlist a.jp-unmute {
|
||||
top:32px;
|
||||
left:296px;
|
||||
}
|
||||
div.jp-video a.jp-mute,
|
||||
div.jp-video a.jp-unmute {
|
||||
top:27px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-single a.jp-mute,
|
||||
div.jp-video-270p div.jp-type-single a.jp-unmute {
|
||||
left:304px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-unmute,
|
||||
div.jp-video-270p div.jp-type-playlist a.jp-mute {
|
||||
left:363px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-single a.jp-mute,
|
||||
div.jp-video-360p div.jp-type-single a.jp-unmute {
|
||||
left:384px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-mute,
|
||||
div.jp-video-360p div.jp-type-playlist a.jp-unmute {
|
||||
left:443px;
|
||||
}
|
||||
a.jp-mute {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -186px no-repeat;
|
||||
}
|
||||
a.jp-mute:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -19px -170px no-repeat;
|
||||
}
|
||||
a.jp-unmute {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -170px no-repeat;
|
||||
display: none;
|
||||
}
|
||||
a.jp-unmute:hover {
|
||||
background: url("../img/jplayer.blue.monday.jpg") -19px -186px no-repeat;
|
||||
}
|
||||
div.jp-volume-bar {
|
||||
position: absolute;
|
||||
overflow:hidden;
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -250px repeat-x;
|
||||
width:46px;
|
||||
height:5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
div.jp-audio div.jp-type-single div.jp-volume-bar {
|
||||
top:37px;
|
||||
left:302px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist div.jp-volume-bar {
|
||||
top:37px;
|
||||
left:324px;
|
||||
}
|
||||
div.jp-video div.jp-volume-bar {
|
||||
top:32px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-single div.jp-volume-bar {
|
||||
left:332px;
|
||||
}
|
||||
div.jp-video-270p div.jp-type-playlist div.jp-volume-bar {
|
||||
left:391px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-single div.jp-volume-bar {
|
||||
left:412px;
|
||||
}
|
||||
div.jp-video-360p div.jp-type-playlist div.jp-volume-bar {
|
||||
left:471px;
|
||||
}
|
||||
div.jp-volume-bar-value {
|
||||
background: url("../img/jplayer.blue.monday.jpg") 0 -256px repeat-x;
|
||||
width:0px;
|
||||
height:5px;
|
||||
}
|
||||
div.jp-current-time,
|
||||
div.jp-duration {
|
||||
position: absolute;
|
||||
font-size:.64em;
|
||||
font-style:oblique;
|
||||
}
|
||||
div.jp-duration {
|
||||
text-align: right;
|
||||
}
|
||||
div.jp-audio div.jp-type-single div.jp-current-time,
|
||||
div.jp-audio div.jp-type-single div.jp-duration {
|
||||
top:49px;
|
||||
left:130px;
|
||||
width:122px;
|
||||
}
|
||||
div.jp-audio div.jp-type-playlist div.jp-current-time,
|
||||
div.jp-audio div.jp-type-playlist div.jp-duration {
|
||||
top:49px;
|
||||
left:164px;
|
||||
width:122px;
|
||||
}
|
||||
div.jp-video div.jp-current-time,
|
||||
div.jp-video div.jp-duration {
|
||||
top:10px;
|
||||
left:0px;
|
||||
width:98%;
|
||||
padding:0 1%;
|
||||
}
|
||||
div.jp-playlist {
|
||||
/* width:418px; */
|
||||
width:100%;
|
||||
background-color:#ccc;
|
||||
border:1px solid #009be3;
|
||||
border-top:none;
|
||||
}
|
||||
div.jp-playlist ul {
|
||||
list-style-type:none;
|
||||
margin:0;
|
||||
padding:0 20px;
|
||||
/* background-color:#ccc; */
|
||||
/* border:1px solid #009be3; */
|
||||
/* border-top:none; */
|
||||
/* width:378px; */
|
||||
font-size:.72em;
|
||||
}
|
||||
|
||||
|
||||
div.jp-type-single div.jp-playlist li {
|
||||
padding:5px 0 5px 20px;
|
||||
font-weight:bold;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist li {
|
||||
padding:5px 0 4px 20px;
|
||||
border-bottom:1px solid #eee;
|
||||
}
|
||||
/*
|
||||
div.jp-video div.jp-playlist li {
|
||||
padding:5px 0 5px 20px;
|
||||
font-weight:bold;
|
||||
}
|
||||
*/
|
||||
div.jp-type-playlist div.jp-playlist li.jp-playlist-last {
|
||||
padding:5px 0 5px 20px;
|
||||
border-bottom:none;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist li.jp-playlist-current {
|
||||
list-style-type:square;
|
||||
list-style-position:inside;
|
||||
padding-left:8px;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist a:hover {
|
||||
color:#0d88c1;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist a.jp-playlist-current {
|
||||
color:#0d88c1;
|
||||
}
|
||||
div.jp-type-playlist div.jp-playlist div.jp-free-media {
|
||||
display:inline;
|
||||
margin-left:20px;
|
||||
}
|
||||
|
||||
div.jp-video div.jp-video-play {
|
||||
background: transparent url("../img/jplayer.blue.monday.video.play.png") no-repeat center;
|
||||
/* position: relative; */
|
||||
position: absolute;
|
||||
cursor:pointer;
|
||||
z-index:2;
|
||||
}
|
||||
div.jp-video div.jp-video-play:hover {
|
||||
background: transparent url("../img/jplayer.blue.monday.video.play.hover.png") no-repeat center;
|
||||
}
|
||||
div.jp-video-270p div.jp-video-play {
|
||||
top:-270px;
|
||||
width:480px;
|
||||
height:270px;
|
||||
}
|
||||
div.jp-video-360p div.jp-video-play {
|
||||
top:-360px;
|
||||
width:640px;
|
||||
height:360px;
|
||||
}
|
||||
|
||||
div.jp-jplayer {
|
||||
width:0px;
|
||||
height:0px;
|
||||
}
|
||||
div.jp-video div.jp-jplayer {
|
||||
border:1px solid #009be3;
|
||||
border-bottom:none;
|
||||
z-index:1;
|
||||
}
|
||||
div.jp-video-270p div.jp-jplayer {
|
||||
width:480px;
|
||||
height:270px;
|
||||
}
|
||||
div.jp-video-360p div.jp-jplayer {
|
||||
width:640px;
|
||||
height:360px;
|
||||
}
|
||||
div.jp-jplayer {
|
||||
background-color: #000000;
|
||||
}
|
189
soundmap/css/jquery.datepicker.css
Normal file
@ -0,0 +1,189 @@
|
||||
div.datepicker {
|
||||
position: relative;
|
||||
width: 196px;
|
||||
height: 147px;
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
}
|
||||
.datepickerContainer {
|
||||
background: white;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
.datepickerBorderT {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_t.png);
|
||||
}
|
||||
.datepickerBorderB {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
bottom: 0;
|
||||
right: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_b.png);
|
||||
}
|
||||
.datepickerBorderL {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 10px;
|
||||
top: 10px;
|
||||
width: 10px;
|
||||
background: url(../img/datepicker_l.png);
|
||||
}
|
||||
.datepickerBorderR {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 10px;
|
||||
top: 10px;
|
||||
width: 10px;
|
||||
background: url(../img/datepicker_r.png);
|
||||
}
|
||||
.datepickerBorderTL {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_tl.png);
|
||||
}
|
||||
.datepickerBorderTR {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_tr.png);
|
||||
}
|
||||
.datepickerBorderBL {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_bl.png);
|
||||
}
|
||||
.datepickerBorderBR {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../img/datepicker_br.png);
|
||||
}
|
||||
.datepickerHidden {
|
||||
display: none;
|
||||
}
|
||||
div.datepicker table {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
div.datepicker a {
|
||||
color: #222;
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
outline: none;
|
||||
}
|
||||
div.datepicker table td {
|
||||
text-align: right;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
div.datepicker th {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
div.datepicker tbody th {
|
||||
text-align: left;
|
||||
}
|
||||
div.datepicker tbody a {
|
||||
display: block;
|
||||
}
|
||||
.datepickerDays a {
|
||||
width: 20px;
|
||||
line-height: 16px;
|
||||
height: 16px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.datepickerYears a,
|
||||
.datepickerMonths a{
|
||||
width: 44px;
|
||||
line-height: 36px;
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
td.datepickerNotInMonth a {
|
||||
color: #eee;
|
||||
}
|
||||
tbody.datepickerDays td.datepickerSelected{
|
||||
background: #ccc;
|
||||
}
|
||||
tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected {
|
||||
background: #17384d;
|
||||
}
|
||||
tbody.datepickerYears td.datepickerSelected,
|
||||
tbody.datepickerMonths td.datepickerSelected{
|
||||
background: #17384d;
|
||||
}
|
||||
div.datepicker a:hover,
|
||||
div.datepicker a:hover {
|
||||
color: red;
|
||||
}
|
||||
div.datepicker td.datepickerNotInMonth a:hover {
|
||||
color: #999;
|
||||
}
|
||||
div.datepicker tbody th {
|
||||
text-align: left;
|
||||
}
|
||||
.datepickerSpace div {
|
||||
width: 20px;
|
||||
}
|
||||
.datepickerGoNext a,
|
||||
.datepickerGoPrev a,
|
||||
.datepickerMonth a {
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.datepickerGoNext a {
|
||||
float: right;
|
||||
width: 20px;
|
||||
}
|
||||
.datepickerGoPrev a {
|
||||
float: left;
|
||||
width: 20px;
|
||||
}
|
||||
table.datepickerViewDays tbody.datepickerMonths,
|
||||
table.datepickerViewDays tbody.datepickerYears {
|
||||
display: none;
|
||||
}
|
||||
table.datepickerViewMonths tbody.datepickerDays,
|
||||
table.datepickerViewMonths tbody.datepickerYears,
|
||||
table.datepickerViewMonths tr.datepickerDoW {
|
||||
display: none;
|
||||
}
|
||||
table.datepickerViewYears tbody.datepickerDays,
|
||||
table.datepickerViewYears tbody.datepickerMonths,
|
||||
table.datepickerViewYears tr.datepickerDoW {
|
||||
display: none;
|
||||
}
|
||||
td.datepickerDisabled a,
|
||||
td.datepickerDisabled.datepickerNotInMonth a{
|
||||
color: #333;
|
||||
}
|
||||
td.datepickerDisabled a:hover {
|
||||
color: #333;
|
||||
}
|
||||
td.datepickerSpecial a {
|
||||
background: #700;
|
||||
}
|
||||
td.datepickerSpecial.datepickerSelected a {
|
||||
background: #a00;
|
||||
}
|
@ -1,2 +1,7 @@
|
||||
|
||||
#map_canvas{width:100%; height:400px};
|
||||
#map_canvas{width:100%; height:400px;}
|
||||
#sound-att-table {width:100%; table-layout: fixed; word-break: break-word; border-collapse: collapse;}
|
||||
#sound-att-table th{text-align:left;}
|
||||
#sound-att-table .soundmap-att-left{width:60%; padding-right:6px}
|
||||
#sound-att-table tr {border-bottom:1px solid #666;}
|
||||
#sound-att-table td {padding: 3px 0;}
|
||||
|
BIN
soundmap/img/datepicker_b.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
soundmap/img/datepicker_bl.png
Normal file
After Width: | Height: | Size: 177 B |
BIN
soundmap/img/datepicker_br.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
soundmap/img/datepicker_l.png
Normal file
After Width: | Height: | Size: 116 B |
BIN
soundmap/img/datepicker_r.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
soundmap/img/datepicker_t.png
Normal file
After Width: | Height: | Size: 113 B |
BIN
soundmap/img/datepicker_tl.png
Normal file
After Width: | Height: | Size: 169 B |
BIN
soundmap/img/datepicker_tr.png
Normal file
After Width: | Height: | Size: 179 B |
BIN
soundmap/img/field.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
soundmap/img/pbar-ani.gif
Normal file
After Width: | Height: | Size: 297 KiB |
891
soundmap/js/jquery.datepicker.js
Normal file
@ -0,0 +1,891 @@
|
||||
/**
|
||||
*
|
||||
* Date picker
|
||||
* Author: Stefan Petre www.eyecon.ro
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses
|
||||
*
|
||||
*/
|
||||
(function ($) {
|
||||
var DatePicker = function () {
|
||||
var ids = {},
|
||||
views = {
|
||||
years: 'datepickerViewYears',
|
||||
moths: 'datepickerViewMonths',
|
||||
days: 'datepickerViewDays'
|
||||
},
|
||||
tpl = {
|
||||
wrapper: '<div class="datepicker"><div class="datepickerBorderT" /><div class="datepickerBorderB" /><div class="datepickerBorderL" /><div class="datepickerBorderR" /><div class="datepickerBorderTL" /><div class="datepickerBorderTR" /><div class="datepickerBorderBL" /><div class="datepickerBorderBR" /><div class="datepickerContainer"><table cellspacing="0" cellpadding="0"><tbody><tr></tr></tbody></table></div></div>',
|
||||
head: [
|
||||
'<td>',
|
||||
'<table cellspacing="0" cellpadding="0">',
|
||||
'<thead>',
|
||||
'<tr>',
|
||||
'<th class="datepickerGoPrev"><a href="#"><span><%=prev%></span></a></th>',
|
||||
'<th colspan="6" class="datepickerMonth"><a href="#"><span></span></a></th>',
|
||||
'<th class="datepickerGoNext"><a href="#"><span><%=next%></span></a></th>',
|
||||
'</tr>',
|
||||
'<tr class="datepickerDoW">',
|
||||
'<th><span><%=week%></span></th>',
|
||||
'<th><span><%=day1%></span></th>',
|
||||
'<th><span><%=day2%></span></th>',
|
||||
'<th><span><%=day3%></span></th>',
|
||||
'<th><span><%=day4%></span></th>',
|
||||
'<th><span><%=day5%></span></th>',
|
||||
'<th><span><%=day6%></span></th>',
|
||||
'<th><span><%=day7%></span></th>',
|
||||
'</tr>',
|
||||
'</thead>',
|
||||
'</table></td>'
|
||||
],
|
||||
space : '<td class="datepickerSpace"><div></div></td>',
|
||||
days: [
|
||||
'<tbody class="datepickerDays">',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[0].week%></span></a></th>',
|
||||
'<td class="<%=weeks[0].days[0].classname%>"><a href="#"><span><%=weeks[0].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[1].classname%>"><a href="#"><span><%=weeks[0].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[2].classname%>"><a href="#"><span><%=weeks[0].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[3].classname%>"><a href="#"><span><%=weeks[0].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[4].classname%>"><a href="#"><span><%=weeks[0].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[5].classname%>"><a href="#"><span><%=weeks[0].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[0].days[6].classname%>"><a href="#"><span><%=weeks[0].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[1].week%></span></a></th>',
|
||||
'<td class="<%=weeks[1].days[0].classname%>"><a href="#"><span><%=weeks[1].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[1].classname%>"><a href="#"><span><%=weeks[1].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[2].classname%>"><a href="#"><span><%=weeks[1].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[3].classname%>"><a href="#"><span><%=weeks[1].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[4].classname%>"><a href="#"><span><%=weeks[1].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[5].classname%>"><a href="#"><span><%=weeks[1].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[1].days[6].classname%>"><a href="#"><span><%=weeks[1].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[2].week%></span></a></th>',
|
||||
'<td class="<%=weeks[2].days[0].classname%>"><a href="#"><span><%=weeks[2].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[1].classname%>"><a href="#"><span><%=weeks[2].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[2].classname%>"><a href="#"><span><%=weeks[2].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[3].classname%>"><a href="#"><span><%=weeks[2].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[4].classname%>"><a href="#"><span><%=weeks[2].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[5].classname%>"><a href="#"><span><%=weeks[2].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[2].days[6].classname%>"><a href="#"><span><%=weeks[2].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[3].week%></span></a></th>',
|
||||
'<td class="<%=weeks[3].days[0].classname%>"><a href="#"><span><%=weeks[3].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[1].classname%>"><a href="#"><span><%=weeks[3].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[2].classname%>"><a href="#"><span><%=weeks[3].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[3].classname%>"><a href="#"><span><%=weeks[3].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[4].classname%>"><a href="#"><span><%=weeks[3].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[5].classname%>"><a href="#"><span><%=weeks[3].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[3].days[6].classname%>"><a href="#"><span><%=weeks[3].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[4].week%></span></a></th>',
|
||||
'<td class="<%=weeks[4].days[0].classname%>"><a href="#"><span><%=weeks[4].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[1].classname%>"><a href="#"><span><%=weeks[4].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[2].classname%>"><a href="#"><span><%=weeks[4].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[3].classname%>"><a href="#"><span><%=weeks[4].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[4].classname%>"><a href="#"><span><%=weeks[4].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[5].classname%>"><a href="#"><span><%=weeks[4].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[4].days[6].classname%>"><a href="#"><span><%=weeks[4].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<th class="datepickerWeek"><a href="#"><span><%=weeks[5].week%></span></a></th>',
|
||||
'<td class="<%=weeks[5].days[0].classname%>"><a href="#"><span><%=weeks[5].days[0].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[1].classname%>"><a href="#"><span><%=weeks[5].days[1].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[2].classname%>"><a href="#"><span><%=weeks[5].days[2].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[3].classname%>"><a href="#"><span><%=weeks[5].days[3].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[4].classname%>"><a href="#"><span><%=weeks[5].days[4].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[5].classname%>"><a href="#"><span><%=weeks[5].days[5].text%></span></a></td>',
|
||||
'<td class="<%=weeks[5].days[6].classname%>"><a href="#"><span><%=weeks[5].days[6].text%></span></a></td>',
|
||||
'</tr>',
|
||||
'</tbody>'
|
||||
],
|
||||
months: [
|
||||
'<tbody class="<%=className%>">',
|
||||
'<tr>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[0]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[1]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[2]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[3]%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[4]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[5]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[6]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[7]%></span></a></td>',
|
||||
'</tr>',
|
||||
'<tr>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[8]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[9]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[10]%></span></a></td>',
|
||||
'<td colspan="2"><a href="#"><span><%=data[11]%></span></a></td>',
|
||||
'</tr>',
|
||||
'</tbody>'
|
||||
]
|
||||
},
|
||||
defaults = {
|
||||
flat: false,
|
||||
starts: 1,
|
||||
prev: '◀',
|
||||
next: '▶',
|
||||
lastSel: false,
|
||||
mode: 'single',
|
||||
view: 'days',
|
||||
calendars: 1,
|
||||
format: 'Y-m-d',
|
||||
position: 'bottom',
|
||||
eventName: 'click',
|
||||
onRender: function(){return {};},
|
||||
onChange: function(){return true;},
|
||||
onShow: function(){return true;},
|
||||
onBeforeShow: function(){return true;},
|
||||
onHide: function(){return true;},
|
||||
locale: {
|
||||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||||
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
weekMin: 'wk'
|
||||
}
|
||||
},
|
||||
fill = function(el) {
|
||||
var options = $(el).data('datepicker');
|
||||
var cal = $(el);
|
||||
var currentCal = Math.floor(options.calendars/2), date, data, dow, month, cnt = 0, week, days, indic, indic2, html, tblCal;
|
||||
cal.find('td>table tbody').remove();
|
||||
for (var i = 0; i < options.calendars; i++) {
|
||||
date = new Date(options.current);
|
||||
date.addMonths(-currentCal + i);
|
||||
tblCal = cal.find('table').eq(i+1);
|
||||
switch (tblCal[0].className) {
|
||||
case 'datepickerViewDays':
|
||||
dow = formatDate(date, 'B, Y');
|
||||
break;
|
||||
case 'datepickerViewMonths':
|
||||
dow = date.getFullYear();
|
||||
break;
|
||||
case 'datepickerViewYears':
|
||||
dow = (date.getFullYear()-6) + ' - ' + (date.getFullYear()+5);
|
||||
break;
|
||||
}
|
||||
tblCal.find('thead tr:first th:eq(1) span').text(dow);
|
||||
dow = date.getFullYear()-6;
|
||||
data = {
|
||||
data: [],
|
||||
className: 'datepickerYears'
|
||||
}
|
||||
for ( var j = 0; j < 12; j++) {
|
||||
data.data.push(dow + j);
|
||||
}
|
||||
html = tmpl(tpl.months.join(''), data);
|
||||
date.setDate(1);
|
||||
data = {weeks:[], test: 10};
|
||||
month = date.getMonth();
|
||||
var dow = (date.getDay() - options.starts) % 7;
|
||||
date.addDays(-(dow + (dow < 0 ? 7 : 0)));
|
||||
week = -1;
|
||||
cnt = 0;
|
||||
while (cnt < 42) {
|
||||
indic = parseInt(cnt/7,10);
|
||||
indic2 = cnt%7;
|
||||
if (!data.weeks[indic]) {
|
||||
week = date.getWeekNumber();
|
||||
data.weeks[indic] = {
|
||||
week: week,
|
||||
days: []
|
||||
};
|
||||
}
|
||||
data.weeks[indic].days[indic2] = {
|
||||
text: date.getDate(),
|
||||
classname: []
|
||||
};
|
||||
if (month != date.getMonth()) {
|
||||
data.weeks[indic].days[indic2].classname.push('datepickerNotInMonth');
|
||||
}
|
||||
if (date.getDay() == 0) {
|
||||
data.weeks[indic].days[indic2].classname.push('datepickerSunday');
|
||||
}
|
||||
if (date.getDay() == 6) {
|
||||
data.weeks[indic].days[indic2].classname.push('datepickerSaturday');
|
||||
}
|
||||
var fromUser = options.onRender(date);
|
||||
var val = date.valueOf();
|
||||
if (fromUser.selected || options.date == val || $.inArray(val, options.date) > -1 || (options.mode == 'range' && val >= options.date[0] && val <= options.date[1])) {
|
||||
data.weeks[indic].days[indic2].classname.push('datepickerSelected');
|
||||
}
|
||||
if (fromUser.disabled) {
|
||||
data.weeks[indic].days[indic2].classname.push('datepickerDisabled');
|
||||
}
|
||||
if (fromUser.className) {
|
||||
data.weeks[indic].days[indic2].classname.push(fromUser.className);
|
||||
}
|
||||
data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' ');
|
||||
cnt++;
|
||||
date.addDays(1);
|
||||
}
|
||||
html = tmpl(tpl.days.join(''), data) + html;
|
||||
data = {
|
||||
data: options.locale.monthsShort,
|
||||
className: 'datepickerMonths'
|
||||
};
|
||||
html = tmpl(tpl.months.join(''), data) + html;
|
||||
tblCal.append(html);
|
||||
}
|
||||
},
|
||||
parseDate = function (date, format) {
|
||||
if (date.constructor == Date) {
|
||||
return new Date(date);
|
||||
}
|
||||
var parts = date.split(/\W+/);
|
||||
var against = format.split(/\W+/), d, m, y, h, min, now = new Date();
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
switch (against[i]) {
|
||||
case 'd':
|
||||
case 'e':
|
||||
d = parseInt(parts[i],10);
|
||||
break;
|
||||
case 'm':
|
||||
m = parseInt(parts[i], 10)-1;
|
||||
break;
|
||||
case 'Y':
|
||||
case 'y':
|
||||
y = parseInt(parts[i], 10);
|
||||
y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
|
||||
break;
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'k':
|
||||
case 'l':
|
||||
h = parseInt(parts[i], 10);
|
||||
break;
|
||||
case 'P':
|
||||
case 'p':
|
||||
if (/pm/i.test(parts[i]) && h < 12) {
|
||||
h += 12;
|
||||
} else if (/am/i.test(parts[i]) && h >= 12) {
|
||||
h -= 12;
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
min = parseInt(parts[i], 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Date(
|
||||
y === undefined ? now.getFullYear() : y,
|
||||
m === undefined ? now.getMonth() : m,
|
||||
d === undefined ? now.getDate() : d,
|
||||
h === undefined ? now.getHours() : h,
|
||||
min === undefined ? now.getMinutes() : min,
|
||||
0
|
||||
);
|
||||
},
|
||||
formatDate = function(date, format) {
|
||||
var m = date.getMonth();
|
||||
var d = date.getDate();
|
||||
var y = date.getFullYear();
|
||||
var wn = date.getWeekNumber();
|
||||
var w = date.getDay();
|
||||
var s = {};
|
||||
var hr = date.getHours();
|
||||
var pm = (hr >= 12);
|
||||
var ir = (pm) ? (hr - 12) : hr;
|
||||
var dy = date.getDayOfYear();
|
||||
if (ir == 0) {
|
||||
ir = 12;
|
||||
}
|
||||
var min = date.getMinutes();
|
||||
var sec = date.getSeconds();
|
||||
var parts = format.split(''), part;
|
||||
for ( var i = 0; i < parts.length; i++ ) {
|
||||
part = parts[i];
|
||||
switch (parts[i]) {
|
||||
case 'a':
|
||||
part = date.getDayName();
|
||||
break;
|
||||
case 'A':
|
||||
part = date.getDayName(true);
|
||||
break;
|
||||
case 'b':
|
||||
part = date.getMonthName();
|
||||
break;
|
||||
case 'B':
|
||||
part = date.getMonthName(true);
|
||||
break;
|
||||
case 'C':
|
||||
part = 1 + Math.floor(y / 100);
|
||||
break;
|
||||
case 'd':
|
||||
part = (d < 10) ? ("0" + d) : d;
|
||||
break;
|
||||
case 'e':
|
||||
part = d;
|
||||
break;
|
||||
case 'H':
|
||||
part = (hr < 10) ? ("0" + hr) : hr;
|
||||
break;
|
||||
case 'I':
|
||||
part = (ir < 10) ? ("0" + ir) : ir;
|
||||
break;
|
||||
case 'j':
|
||||
part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
|
||||
break;
|
||||
case 'k':
|
||||
part = hr;
|
||||
break;
|
||||
case 'l':
|
||||
part = ir;
|
||||
break;
|
||||
case 'm':
|
||||
part = (m < 9) ? ("0" + (1+m)) : (1+m);
|
||||
break;
|
||||
case 'M':
|
||||
part = (min < 10) ? ("0" + min) : min;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
part = pm ? "PM" : "AM";
|
||||
break;
|
||||
case 's':
|
||||
part = Math.floor(date.getTime() / 1000);
|
||||
break;
|
||||
case 'S':
|
||||
part = (sec < 10) ? ("0" + sec) : sec;
|
||||
break;
|
||||
case 'u':
|
||||
part = w + 1;
|
||||
break;
|
||||
case 'w':
|
||||
part = w;
|
||||
break;
|
||||
case 'y':
|
||||
part = ('' + y).substr(2, 2);
|
||||
break;
|
||||
case 'Y':
|
||||
part = y;
|
||||
break;
|
||||
}
|
||||
parts[i] = part;
|
||||
}
|
||||
return parts.join('');
|
||||
},
|
||||
extendDate = function(options) {
|
||||
if (Date.prototype.tempDate) {
|
||||
return;
|
||||
}
|
||||
Date.prototype.tempDate = null;
|
||||
Date.prototype.months = options.months;
|
||||
Date.prototype.monthsShort = options.monthsShort;
|
||||
Date.prototype.days = options.days;
|
||||
Date.prototype.daysShort = options.daysShort;
|
||||
Date.prototype.getMonthName = function(fullName) {
|
||||
return this[fullName ? 'months' : 'monthsShort'][this.getMonth()];
|
||||
};
|
||||
Date.prototype.getDayName = function(fullName) {
|
||||
return this[fullName ? 'days' : 'daysShort'][this.getDay()];
|
||||
};
|
||||
Date.prototype.addDays = function (n) {
|
||||
this.setDate(this.getDate() + n);
|
||||
this.tempDate = this.getDate();
|
||||
};
|
||||
Date.prototype.addMonths = function (n) {
|
||||
if (this.tempDate == null) {
|
||||
this.tempDate = this.getDate();
|
||||
}
|
||||
this.setDate(1);
|
||||
this.setMonth(this.getMonth() + n);
|
||||
this.setDate(Math.min(this.tempDate, this.getMaxDays()));
|
||||
};
|
||||
Date.prototype.addYears = function (n) {
|
||||
if (this.tempDate == null) {
|
||||
this.tempDate = this.getDate();
|
||||
}
|
||||
this.setDate(1);
|
||||
this.setFullYear(this.getFullYear() + n);
|
||||
this.setDate(Math.min(this.tempDate, this.getMaxDays()));
|
||||
};
|
||||
Date.prototype.getMaxDays = function() {
|
||||
var tmpDate = new Date(Date.parse(this)),
|
||||
d = 28, m;
|
||||
m = tmpDate.getMonth();
|
||||
d = 28;
|
||||
while (tmpDate.getMonth() == m) {
|
||||
d ++;
|
||||
tmpDate.setDate(d);
|
||||
}
|
||||
return d - 1;
|
||||
};
|
||||
Date.prototype.getFirstDay = function() {
|
||||
var tmpDate = new Date(Date.parse(this));
|
||||
tmpDate.setDate(1);
|
||||
return tmpDate.getDay();
|
||||
};
|
||||
Date.prototype.getWeekNumber = function() {
|
||||
var tempDate = new Date(this);
|
||||
tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3);
|
||||
var dms = tempDate.valueOf();
|
||||
tempDate.setMonth(0);
|
||||
tempDate.setDate(4);
|
||||
return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1;
|
||||
};
|
||||
Date.prototype.getDayOfYear = function() {
|
||||
var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
||||
var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
|
||||
var time = now - then;
|
||||
return Math.floor(time / 24*60*60*1000);
|
||||
};
|
||||
},
|
||||
layout = function (el) {
|
||||
var options = $(el).data('datepicker');
|
||||
var cal = $('#' + options.id);
|
||||
if (!options.extraHeight) {
|
||||
var divs = $(el).find('div');
|
||||
options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight;
|
||||
options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth;
|
||||
}
|
||||
var tbl = cal.find('table:first').get(0);
|
||||
var width = tbl.offsetWidth;
|
||||
var height = tbl.offsetHeight;
|
||||
cal.css({
|
||||
width: width + options.extraWidth + 'px',
|
||||
height: height + options.extraHeight + 'px'
|
||||
}).find('div.datepickerContainer').css({
|
||||
width: width + 'px',
|
||||
height: height + 'px'
|
||||
});
|
||||
},
|
||||
click = function(ev) {
|
||||
if ($(ev.target).is('span')) {
|
||||
ev.target = ev.target.parentNode;
|
||||
}
|
||||
var el = $(ev.target);
|
||||
if (el.is('a')) {
|
||||
ev.target.blur();
|
||||
if (el.hasClass('datepickerDisabled')) {
|
||||
return false;
|
||||
}
|
||||
var options = $(this).data('datepicker');
|
||||
var parentEl = el.parent();
|
||||
var tblEl = parentEl.parent().parent().parent();
|
||||
var tblIndex = $('table', this).index(tblEl.get(0)) - 1;
|
||||
var tmp = new Date(options.current);
|
||||
var changed = false;
|
||||
var fillIt = false;
|
||||
if (parentEl.is('th')) {
|
||||
if (parentEl.hasClass('datepickerWeek') && options.mode == 'range' && !parentEl.next().hasClass('datepickerDisabled')) {
|
||||
var val = parseInt(parentEl.next().text(), 10);
|
||||
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
||||
if (parentEl.next().hasClass('datepickerNotInMonth')) {
|
||||
tmp.addMonths(val > 15 ? -1 : 1);
|
||||
}
|
||||
tmp.setDate(val);
|
||||
options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
|
||||
tmp.setHours(23,59,59,0);
|
||||
tmp.addDays(6);
|
||||
options.date[1] = tmp.valueOf();
|
||||
fillIt = true;
|
||||
changed = true;
|
||||
options.lastSel = false;
|
||||
} else if (parentEl.hasClass('datepickerMonth')) {
|
||||
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
||||
switch (tblEl.get(0).className) {
|
||||
case 'datepickerViewDays':
|
||||
tblEl.get(0).className = 'datepickerViewMonths';
|
||||
el.find('span').text(tmp.getFullYear());
|
||||
break;
|
||||
case 'datepickerViewMonths':
|
||||
tblEl.get(0).className = 'datepickerViewYears';
|
||||
el.find('span').text((tmp.getFullYear()-6) + ' - ' + (tmp.getFullYear()+5));
|
||||
break;
|
||||
case 'datepickerViewYears':
|
||||
tblEl.get(0).className = 'datepickerViewDays';
|
||||
el.find('span').text(formatDate(tmp, 'B, Y'));
|
||||
break;
|
||||
}
|
||||
} else if (parentEl.parent().parent().is('thead')) {
|
||||
switch (tblEl.get(0).className) {
|
||||
case 'datepickerViewDays':
|
||||
options.current.addMonths(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
|
||||
break;
|
||||
case 'datepickerViewMonths':
|
||||
options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
|
||||
break;
|
||||
case 'datepickerViewYears':
|
||||
options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -12 : 12);
|
||||
break;
|
||||
}
|
||||
fillIt = true;
|
||||
}
|
||||
} else if (parentEl.is('td') && !parentEl.hasClass('datepickerDisabled')) {
|
||||
switch (tblEl.get(0).className) {
|
||||
case 'datepickerViewMonths':
|
||||
options.current.setMonth(tblEl.find('tbody.datepickerMonths td').index(parentEl));
|
||||
options.current.setFullYear(parseInt(tblEl.find('thead th.datepickerMonth span').text(), 10));
|
||||
options.current.addMonths(Math.floor(options.calendars/2) - tblIndex);
|
||||
tblEl.get(0).className = 'datepickerViewDays';
|
||||
break;
|
||||
case 'datepickerViewYears':
|
||||
options.current.setFullYear(parseInt(el.text(), 10));
|
||||
tblEl.get(0).className = 'datepickerViewMonths';
|
||||
break;
|
||||
default:
|
||||
var val = parseInt(el.text(), 10);
|
||||
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
||||
if (parentEl.hasClass('datepickerNotInMonth')) {
|
||||
tmp.addMonths(val > 15 ? -1 : 1);
|
||||
}
|
||||
tmp.setDate(val);
|
||||
switch (options.mode) {
|
||||
case 'multiple':
|
||||
val = (tmp.setHours(0,0,0,0)).valueOf();
|
||||
if ($.inArray(val, options.date) > -1) {
|
||||
$.each(options.date, function(nr, dat){
|
||||
if (dat == val) {
|
||||
options.date.splice(nr,1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
options.date.push(val);
|
||||
}
|
||||
break;
|
||||
case 'range':
|
||||
if (!options.lastSel) {
|
||||
options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
|
||||
}
|
||||
val = (tmp.setHours(23,59,59,0)).valueOf();
|
||||
if (val < options.date[0]) {
|
||||
options.date[1] = options.date[0] + 86399000;
|
||||
options.date[0] = val - 86399000;
|
||||
} else {
|
||||
options.date[1] = val;
|
||||
}
|
||||
options.lastSel = !options.lastSel;
|
||||
break;
|
||||
default:
|
||||
options.date = tmp.valueOf();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fillIt = true;
|
||||
changed = true;
|
||||
}
|
||||
if (fillIt) {
|
||||
fill(this);
|
||||
}
|
||||
if (changed) {
|
||||
options.onChange.apply(this, prepareDate(options));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
prepareDate = function (options) {
|
||||
var tmp;
|
||||
if (options.mode == 'single') {
|
||||
tmp = new Date(options.date);
|
||||
return [formatDate(tmp, options.format), tmp, options.el];
|
||||
} else {
|
||||
tmp = [[],[], options.el];
|
||||
$.each(options.date, function(nr, val){
|
||||
var date = new Date(val);
|
||||
tmp[0].push(formatDate(date, options.format));
|
||||
tmp[1].push(date);
|
||||
});
|
||||
return tmp;
|
||||
}
|
||||
},
|
||||
getViewport = function () {
|
||||
var m = document.compatMode == 'CSS1Compat';
|
||||
return {
|
||||
l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
|
||||
t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
|
||||
w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
|
||||
h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
|
||||
};
|
||||
},
|
||||
isChildOf = function(parentEl, el, container) {
|
||||
if (parentEl == el) {
|
||||
return true;
|
||||
}
|
||||
if (parentEl.contains) {
|
||||
return parentEl.contains(el);
|
||||
}
|
||||
if ( parentEl.compareDocumentPosition ) {
|
||||
return !!(parentEl.compareDocumentPosition(el) & 16);
|
||||
}
|
||||
var prEl = el.parentNode;
|
||||
while(prEl && prEl != container) {
|
||||
if (prEl == parentEl)
|
||||
return true;
|
||||
prEl = prEl.parentNode;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
show = function (ev) {
|
||||
var cal = $('#' + $(this).data('datepickerId'));
|
||||
if (!cal.is(':visible')) {
|
||||
var calEl = cal.get(0);
|
||||
fill(calEl);
|
||||
var options = cal.data('datepicker');
|
||||
options.onBeforeShow.apply(this, [cal.get(0)]);
|
||||
var pos = $(this).offset();
|
||||
var viewPort = getViewport();
|
||||
var top = pos.top;
|
||||
var left = pos.left;
|
||||
var oldDisplay = $.curCSS(calEl, 'display');
|
||||
cal.css({
|
||||
visibility: 'hidden',
|
||||
display: 'block'
|
||||
});
|
||||
layout(calEl);
|
||||
switch (options.position){
|
||||
case 'top':
|
||||
top -= calEl.offsetHeight;
|
||||
break;
|
||||
case 'left':
|
||||
left -= calEl.offsetWidth;
|
||||
break;
|
||||
case 'right':
|
||||
left += this.offsetWidth;
|
||||
break;
|
||||
case 'bottom':
|
||||
top += this.offsetHeight;
|
||||
break;
|
||||
}
|
||||
if (top + calEl.offsetHeight > viewPort.t + viewPort.h) {
|
||||
top = pos.top - calEl.offsetHeight;
|
||||
}
|
||||
if (top < viewPort.t) {
|
||||
top = pos.top + this.offsetHeight + calEl.offsetHeight;
|
||||
}
|
||||
if (left + calEl.offsetWidth > viewPort.l + viewPort.w) {
|
||||
left = pos.left - calEl.offsetWidth;
|
||||
}
|
||||
if (left < viewPort.l) {
|
||||
left = pos.left + this.offsetWidth
|
||||
}
|
||||
cal.css({
|
||||
visibility: 'visible',
|
||||
display: 'block',
|
||||
top: top + 'px',
|
||||
left: left + 'px'
|
||||
});
|
||||
if (options.onShow.apply(this, [cal.get(0)]) != false) {
|
||||
cal.show();
|
||||
}
|
||||
$(document).bind('mousedown', {cal: cal, trigger: this}, hide);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
hide = function (ev) {
|
||||
if (ev.target != ev.data.trigger && !isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
|
||||
if (ev.data.cal.data('datepicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
|
||||
ev.data.cal.hide();
|
||||
}
|
||||
$(document).unbind('mousedown', hide);
|
||||
}
|
||||
};
|
||||
return {
|
||||
init: function(options){
|
||||
options = $.extend({}, defaults, options||{});
|
||||
extendDate(options.locale);
|
||||
options.calendars = Math.max(1, parseInt(options.calendars,10)||1);
|
||||
options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single';
|
||||
return this.each(function(){
|
||||
if (!$(this).data('datepicker')) {
|
||||
options.el = this;
|
||||
if (options.date.constructor == String) {
|
||||
options.date = parseDate(options.date, options.format);
|
||||
options.date.setHours(0,0,0,0);
|
||||
}
|
||||
if (options.mode != 'single') {
|
||||
if (options.date.constructor != Array) {
|
||||
options.date = [options.date.valueOf()];
|
||||
if (options.mode == 'range') {
|
||||
options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < options.date.length; i++) {
|
||||
options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
|
||||
}
|
||||
if (options.mode == 'range') {
|
||||
options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
options.date = options.date.valueOf();
|
||||
}
|
||||
if (!options.current) {
|
||||
options.current = new Date();
|
||||
} else {
|
||||
options.current = parseDate(options.current, options.format);
|
||||
}
|
||||
options.current.setDate(1);
|
||||
options.current.setHours(0,0,0,0);
|
||||
var id = 'datepicker_' + parseInt(Math.random() * 1000), cnt;
|
||||
options.id = id;
|
||||
$(this).data('datepickerId', options.id);
|
||||
var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options);
|
||||
if (options.className) {
|
||||
cal.addClass(options.className);
|
||||
}
|
||||
var html = '';
|
||||
for (var i = 0; i < options.calendars; i++) {
|
||||
cnt = options.starts;
|
||||
if (i > 0) {
|
||||
html += tpl.space;
|
||||
}
|
||||
html += tmpl(tpl.head.join(''), {
|
||||
week: options.locale.weekMin,
|
||||
prev: options.prev,
|
||||
next: options.next,
|
||||
day1: options.locale.daysMin[(cnt++)%7],
|
||||
day2: options.locale.daysMin[(cnt++)%7],
|
||||
day3: options.locale.daysMin[(cnt++)%7],
|
||||
day4: options.locale.daysMin[(cnt++)%7],
|
||||
day5: options.locale.daysMin[(cnt++)%7],
|
||||
day6: options.locale.daysMin[(cnt++)%7],
|
||||
day7: options.locale.daysMin[(cnt++)%7]
|
||||
});
|
||||
}
|
||||
cal
|
||||
.find('tr:first').append(html)
|
||||
.find('table').addClass(views[options.view]);
|
||||
fill(cal.get(0));
|
||||
if (options.flat) {
|
||||
cal.appendTo(this).show().css('position', 'relative');
|
||||
layout(cal.get(0));
|
||||
} else {
|
||||
cal.appendTo(document.body);
|
||||
$(this).bind(options.eventName, show);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
showPicker: function() {
|
||||
return this.each( function () {
|
||||
if ($(this).data('datepickerId')) {
|
||||
show.apply(this);
|
||||
}
|
||||
});
|
||||
},
|
||||
hidePicker: function() {
|
||||
return this.each( function () {
|
||||
if ($(this).data('datepickerId')) {
|
||||
$('#' + $(this).data('datepickerId')).hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
setDate: function(date, shiftTo){
|
||||
return this.each(function(){
|
||||
if ($(this).data('datepickerId')) {
|
||||
var cal = $('#' + $(this).data('datepickerId'));
|
||||
var options = cal.data('datepicker');
|
||||
options.date = date;
|
||||
if (options.date.constructor == String) {
|
||||
options.date = parseDate(options.date, options.format);
|
||||
options.date.setHours(0,0,0,0);
|
||||
}
|
||||
if (options.mode != 'single') {
|
||||
if (options.date.constructor != Array) {
|
||||
options.date = [options.date.valueOf()];
|
||||
if (options.mode == 'range') {
|
||||
options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < options.date.length; i++) {
|
||||
options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
|
||||
}
|
||||
if (options.mode == 'range') {
|
||||
options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
options.date = options.date.valueOf();
|
||||
}
|
||||
if (shiftTo) {
|
||||
options.current = new Date (options.mode != 'single' ? options.date[0] : options.date);
|
||||
}
|
||||
fill(cal.get(0));
|
||||
}
|
||||
});
|
||||
},
|
||||
getDate: function(formated) {
|
||||
if (this.size() > 0) {
|
||||
return prepareDate($('#' + $(this).data('datepickerId')).data('datepicker'))[formated ? 0 : 1];
|
||||
}
|
||||
},
|
||||
clear: function(){
|
||||
return this.each(function(){
|
||||
if ($(this).data('datepickerId')) {
|
||||
var cal = $('#' + $(this).data('datepickerId'));
|
||||
var options = cal.data('datepicker');
|
||||
if (options.mode != 'single') {
|
||||
options.date = [];
|
||||
fill(cal.get(0));
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
fixLayout: function(){
|
||||
return this.each(function(){
|
||||
if ($(this).data('datepickerId')) {
|
||||
var cal = $('#' + $(this).data('datepickerId'));
|
||||
var options = cal.data('datepicker');
|
||||
if (options.flat) {
|
||||
layout(cal.get(0));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}();
|
||||
$.fn.extend({
|
||||
DatePicker: DatePicker.init,
|
||||
DatePickerHide: DatePicker.hidePicker,
|
||||
DatePickerShow: DatePicker.showPicker,
|
||||
DatePickerSetDate: DatePicker.setDate,
|
||||
DatePickerGetDate: DatePicker.getDate,
|
||||
DatePickerClear: DatePicker.clear,
|
||||
DatePickerLayout: DatePicker.fixLayout
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
(function(){
|
||||
var cache = {};
|
||||
|
||||
this.tmpl = function tmpl(str, data){
|
||||
// Figure out if we're getting a template, or if we need to
|
||||
// load the template - and be sure to cache the result.
|
||||
var fn = !/\W/.test(str) ?
|
||||
cache[str] = cache[str] ||
|
||||
tmpl(document.getElementById(str).innerHTML) :
|
||||
|
||||
// Generate a reusable function that will serve as a template
|
||||
// generator (and which will be cached).
|
||||
new Function("obj",
|
||||
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
||||
|
||||
// Introduce the data as local variables using with(){}
|
||||
"with(obj){p.push('" +
|
||||
|
||||
// Convert the template into pure JavaScript
|
||||
str
|
||||
.replace(/[\r\t\n]/g, " ")
|
||||
.split("<%").join("\t")
|
||||
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
||||
.replace(/\t=(.*?)%>/g, "',$1,'")
|
||||
.split("\t").join("');")
|
||||
.split("%>").join("p.push('")
|
||||
.split("\r").join("\\'")
|
||||
+ "');}return p.join('');");
|
||||
|
||||
// Provide some basic currying to the user
|
||||
return data ? fn( data ) : fn;
|
||||
};
|
||||
})();
|
@ -1,229 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 2.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010-2011 Johan Säll Larsson
|
||||
*
|
||||
* Microdatajs
|
||||
* http://gitorious.org/microdatajs/microdatajs
|
||||
* Copyright (c) 2009-2011 Philip Jägenstedt
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.map.js
|
||||
*/
|
||||
|
||||
( function($) {
|
||||
|
||||
jQuery.fn.extend({
|
||||
|
||||
items: getItems,
|
||||
itemScope: itemScope,
|
||||
itemType: itemType,
|
||||
itemId: itemId,
|
||||
itemProp: tokenList('itemprop'),
|
||||
itemRef: tokenList('itemref'),
|
||||
itemValue: itemValue
|
||||
|
||||
});
|
||||
|
||||
function itemValue() {
|
||||
var elm = this.get(0);
|
||||
if (this.attr('itemprop') === undefined) {
|
||||
return null;
|
||||
}
|
||||
if (this.itemScope()) {
|
||||
return elm;
|
||||
}
|
||||
switch (elm.tagName.toUpperCase()) {
|
||||
case 'META':
|
||||
return this.attr('content') || '';
|
||||
case 'AUDIO':
|
||||
case 'EMBED':
|
||||
case 'IFRAME':
|
||||
case 'IMG':
|
||||
case 'SOURCE':
|
||||
case 'VIDEO':
|
||||
return resolve(this.attr('src'));
|
||||
case 'A':
|
||||
case 'AREA':
|
||||
case 'LINK':
|
||||
return resolve(this.attr('href'));
|
||||
case 'OBJECT':
|
||||
return resolve(this.attr('data'));
|
||||
case 'TIME':
|
||||
var datetime = this.attr('datetime');
|
||||
if (!(datetime === undefined))
|
||||
return datetime;
|
||||
default:
|
||||
return this.text();
|
||||
}
|
||||
}
|
||||
|
||||
function itemId() {
|
||||
return resolve(this.attr('itemid'));
|
||||
}
|
||||
|
||||
function itemScope() {
|
||||
return this.attr('itemscope') != undefined;
|
||||
}
|
||||
|
||||
function itemType() {
|
||||
return this.attr('itemtype') || '';
|
||||
}
|
||||
|
||||
function splitTokens(s) {
|
||||
if (s && /\S/.test(s))
|
||||
return s.replace(/^\s+|\s+$/g,'').split(/\s+/);
|
||||
return [];
|
||||
}
|
||||
|
||||
function resolve(url) {
|
||||
if (!url)
|
||||
return '';
|
||||
var img = document.createElement('img');
|
||||
img.setAttribute('src', url);
|
||||
return img.src;
|
||||
}
|
||||
|
||||
function getItems(types) {
|
||||
var selector = jQuery.map(splitTokens(types), function(t) {
|
||||
return '[itemtype~="'+t.replace(/"/g, '\\"')+'"]';
|
||||
}).join(',') || '*';
|
||||
// filter results to only match top-level items
|
||||
// because [attr] selector doesn't work in IE we have to
|
||||
// filter the elements. http://dev.jquery.com/ticket/5637
|
||||
return jQuery(selector, this).filter(function() {
|
||||
return (this.getAttribute('itemscope') != null && this.getAttribute('itemprop') == null);
|
||||
});
|
||||
}
|
||||
|
||||
function tokenList(attr) {
|
||||
return function() {
|
||||
var tokens = [];
|
||||
jQuery.each(splitTokens(this.attr(attr)), function(i, token) {
|
||||
if (jQuery.inArray(token, tokens) == -1)
|
||||
tokens.push(token);
|
||||
});
|
||||
return jQuery(tokens);
|
||||
};
|
||||
}
|
||||
|
||||
function getItem($item, list, key, latlngs) {
|
||||
|
||||
var result = {};
|
||||
|
||||
if ( $item.itemType() ) {
|
||||
result.type = $item.itemType();
|
||||
}
|
||||
|
||||
if ( $item.itemId() ) {
|
||||
result.id = $item.itemId();
|
||||
}
|
||||
|
||||
result.properties = {};
|
||||
result.list = list;
|
||||
|
||||
$item.children().each(function() {
|
||||
|
||||
var $elem = jQuery(this);
|
||||
|
||||
var value;
|
||||
|
||||
if ( $elem.itemScope() ) {
|
||||
value = getItem($elem, list, key, latlngs);
|
||||
} else {
|
||||
value = $elem.itemValue();
|
||||
}
|
||||
|
||||
$elem.itemProp().each(function() {
|
||||
|
||||
if (!result.properties[this]) {
|
||||
result.properties[this] = [];
|
||||
}
|
||||
|
||||
if ( typeof value != "object" ) {
|
||||
result.list[this] = value;
|
||||
}
|
||||
|
||||
result.properties[this].push(value);
|
||||
|
||||
});
|
||||
|
||||
if ( latlngs.length > 0 ) {
|
||||
var t = $elem.itemType();
|
||||
if ( typeof t == "string" && t.toLowerCase().indexOf('geo') > -1 ) {
|
||||
result.properties['geo'][0].properties = latlngs[key];
|
||||
result.list['geo'] = new google.maps.LatLng(latlngs[key].latitude[0],latlngs[key].longitude[0]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
function getMetaTag() {
|
||||
var latlng = [];
|
||||
if ( $.browser.mozilla ) {
|
||||
var lats = [];
|
||||
var lngs = [];
|
||||
var metas = document.getElementsByTagName('meta');
|
||||
for ( i = 0; i < metas.length; i++ ) {
|
||||
var meta = $(metas[i]);
|
||||
if ( meta.attr('itemprop') == 'latitude' ) {
|
||||
lats.push(meta.attr('content'));
|
||||
}
|
||||
if ( meta.attr('itemprop') == 'longitude' ) {
|
||||
lngs.push(meta.attr('content'));
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < lats.length; i++ ) {
|
||||
latlng.push({ 'latitude': [lats[i]], 'longitude': [lngs[i]] });
|
||||
}
|
||||
}
|
||||
return latlng;
|
||||
}
|
||||
|
||||
$.extend($.ui.gmap, {
|
||||
|
||||
version: '1.0',
|
||||
|
||||
microdata: function(ns, callback) {
|
||||
|
||||
// Mozilla/Firefox adds meta tags in header
|
||||
var latlngs = getMetaTag();
|
||||
var items = jQuery(document).items(ns);
|
||||
|
||||
items.each(function(i, value) {
|
||||
var item = $(value);
|
||||
if (item.itemScope()) {
|
||||
$.ui.gmap._trigger(callback, i, item, getItem(item, [], i, latlngs));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} (jQuery) );
|
34
soundmap/js/jquery.ui.gmap.microdata.min.js
vendored
@ -1,34 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 2.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010-2011 Johan Säll Larsson
|
||||
*
|
||||
* Microdatajs
|
||||
* http://gitorious.org/microdatajs/microdatajs
|
||||
* Copyright (c) 2009-2011 Philip Jägenstedt
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.map.js
|
||||
*/
|
||||
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(4($){b.1l.16({z:15,e:e,j:j,o:o,U:I(\'m\'),1m:I(\'1n\'),x:x});4 x(){5 D=3.1k(0);6(3.7(\'m\')===T){2 J}6(3.e()){2 D}1j(D.1f.1g()){9\'1h\':2 3.7(\'N\')||\'\';9\'1i\':9\'1o\':9\'1p\':9\'1v\':9\'1w\':9\'1x\':2 p(3.7(\'E\'));9\'A\':9\'1e\':9\'1t\':2 p(3.7(\'1q\'));9\'1r\':2 p(3.7(\'1s\'));9\'1y\':5 v=3.7(\'v\');6(!(v===T))2 v;1d:2 3.1c()}}4 o(){2 p(3.7(\'1b\'))}4 e(){2 3.7(\'W\')!=T}4 j(){2 3.7(\'13\')||\'\'}4 C(s){6(s&&/\\S/.1a(s))2 s.17(/^\\s+|\\s+$/g,\'\').1u(/\\s+/);2[]}4 p(K){6(!K)2\'\';5 r=F.1Q(\'r\');r.1O(\'E\',K);2 r.E}4 15(14){5 19=b.1N(C(14),4(t){2\'[13~="\'+t.17(/"/g,\'\\\\"\')+\'"]\'}).1S(\',\')||\'*\';2 b(19,3).1z(4(){2(3.Z(\'W\')!=J&&3.Z(\'m\')==J)})}4 I(7){2 4(){5 u=[];b.y(C(3.7(7)),4(i,H){6(b.1W(H,u)==-1)u.n(H)});2 b(u)}}4 B($a,f,q,d){5 8={};6($a.j()){8.1T=$a.j()}6($a.o()){8.1U=$a.o()}8.k={};8.f=f;$a.1L().y(4(){5 $l=b(3);5 c;6($l.e()){c=B($l,f,q,d)}1K{c=$l.x()}$l.U().y(4(){6(!8.k[3]){8.k[3]=[]}6(11 c!="1D"){8.f[3]=c}8.k[3].n(c)});6(d.M>0){5 t=$l.j();6(11 t=="1B"&&t.1A().1E(\'L\')>-1){8.k[\'L\'][0].k=d[q];8.f[\'L\']=1J 1I.1H.1G(d[q].R[0],d[q].G[0])}}});2 8}4 12(){5 O=[];6($.1C.1V){5 w=[];5 P=[];5 Q=F.1R(\'h\');V(i=0;i<Q.M;i++){5 h=$(Q[i]);6(h.7(\'m\')==\'R\'){w.n(h.7(\'N\'))}6(h.7(\'m\')==\'G\'){P.n(h.7(\'N\'))}}V(i=0;i<w.M;i++){O.n({\'R\':[w[i]],\'G\':[P[i]]})}}2 O}$.16($.Y.10,{1P:\'1.0\',1F:4(X,18){5 d=12();5 z=b(F).z(X);z.y(4(i,c){5 a=$(c);6(a.e()){$.Y.10.1M(18,i,a,B(a,[],i,d))}})}})}(b));',62,121,'||return|this|function|var|if|attr|result|case|item|jQuery|value|latlngs|itemScope|list||meta||itemType|properties|elem|itemprop|push|itemId|resolve|key|img|||tokens|datetime|lats|itemValue|each|items||getItem|splitTokens|elm|src|document|longitude|token|tokenList|null|url|geo|length|content|latlng|lngs|metas|latitude||undefined|itemProp|for|itemscope|ns|ui|getAttribute|gmap|typeof|getMetaTag|itemtype|types|getItems|extend|replace|callback|selector|test|itemid|text|default|AREA|tagName|toUpperCase|META|AUDIO|switch|get|fn|itemRef|itemref|EMBED|IFRAME|href|OBJECT|data|LINK|split|IMG|SOURCE|VIDEO|TIME|filter|toLowerCase|string|browser|object|indexOf|microdata|LatLng|maps|google|new|else|children|_trigger|map|setAttribute|version|createElement|getElementsByTagName|join|type|id|mozilla|inArray'.split('|'),0,{}))
|
@ -1,152 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 2.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010-2011 Johan Säll Larsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.map.js
|
||||
*/
|
||||
|
||||
( function($) {
|
||||
|
||||
/* see http://en.wikipedia.org/wiki/XHTML_Friends_Network */
|
||||
var XFN = [
|
||||
'friend',
|
||||
'contact',
|
||||
'acquaintance'
|
||||
];
|
||||
|
||||
/* Supported properties */
|
||||
var properties = [
|
||||
'summary',
|
||||
'description',
|
||||
'url',
|
||||
'photo',
|
||||
'street-address',
|
||||
'postal-code',
|
||||
'locality',
|
||||
'region',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'startDate',
|
||||
'dtstart',
|
||||
'endDate',
|
||||
'dtend',
|
||||
'duration',
|
||||
'eventType',
|
||||
'category',
|
||||
'fn',
|
||||
'name',
|
||||
'nickname',
|
||||
'title',
|
||||
'role',
|
||||
'org',
|
||||
'tel',
|
||||
'reviewer',
|
||||
'dtreviewed',
|
||||
'rating'
|
||||
];
|
||||
|
||||
|
||||
$.extend($.ui.gmap, {
|
||||
|
||||
version: '1.0',
|
||||
|
||||
microformat: function(ns, callback) {
|
||||
$('.'+ns).each(function(i, node) {
|
||||
$.ui.gmap._trigger(callback, i, $(node), getItem($(node), []));
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function hasProperty(property) {
|
||||
for( var i = 0; i < properties.length; i++) {
|
||||
if ( properties[i] === property ) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasXFN(xfn) {
|
||||
for( var i = 0; i < XFN.length; i++) {
|
||||
if ( XFN[i] === xfn ) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
function getItem(node, list) {
|
||||
|
||||
node.children().each(function() {
|
||||
|
||||
var childNode = $(this);
|
||||
|
||||
if ( childNode.attr('class') != undefined ) {
|
||||
$.each(childNode.attr('class').split(' '), function(i, c) {
|
||||
if ( c.length > 0 && hasProperty(c) ) {
|
||||
if ( !list[c] ) {
|
||||
list[c] = {};
|
||||
}
|
||||
if ( childNode.attr('id') != '' ) {
|
||||
list[c].id = childNode.attr('id');
|
||||
}
|
||||
if ( childNode.attr('title') != '' ) {
|
||||
list[c].title = childNode.attr('title');
|
||||
}
|
||||
if ( childNode.attr('href') != undefined ) {
|
||||
list[c].href = childNode.attr('href');
|
||||
}
|
||||
if ( childNode.attr('src') != undefined ) {
|
||||
list[c].src = childNode.attr('src');
|
||||
}
|
||||
if ( childNode.text() != '' ) {
|
||||
list[c].text = childNode.text();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( childNode.attr('rel') != undefined ) {
|
||||
$.each(childNode.attr('rel').split(' '), function(i, c) {
|
||||
if ( c.length > 0 && hasXFN(c) ) {
|
||||
if (!list[c]) {
|
||||
list[c] = [];
|
||||
}
|
||||
list[c].push({ 'text': childNode.text(), 'href': childNode.attr('href') });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getItem(childNode, list);
|
||||
|
||||
});
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
} (jQuery) );
|
29
soundmap/js/jquery.ui.gmap.microformat.min.js
vendored
@ -1,29 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 1.0.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010 Johan Säll Larsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(6($){9 m=[\'O\',\'L\',\'R\'];9 j=[\'M\',\'N\',\'U\',\'Q\',\'T-S\',\'V-I\',\'E\',\'D\',\'C\',\'F\',\'G\',\'J\',\'K\',\'H\',\'B\',\'P\',\'Z\',\'18\',\'17\',\'16\',\'g\',\'1a\',\'1b\',\'1c\',\'1d\',\'19\',\'14\'];$.15($.s.t,{Y:\'1.0\',X:6(r,u){$(\'.\'+r).d(6(i,8){$.s.t.W(u,i,$(8),k($(8),[]))})}});6 w(q){n(9 i=0;i<j.f;i++){5(j[i]===q){a v}};a o}6 y(p){n(9 i=0;i<m.f;i++){5(m[i]===p){a v}};a o}6 k(8,3){8.11().d(6(){9 2=$(13);5(2.4(\'z\')!=e){$.d(2.4(\'z\').A(\' \'),6(i,c){5(c.f>0&&w(c)){5(!3[c]){3[c]={}}5(2.4(\'l\')!=\'\'){3[c].l=2.4(\'l\')}5(2.4(\'g\')!=\'\'){3[c].g=2.4(\'g\')}5(2.4(\'b\')!=e){3[c].b=2.4(\'b\')}5(2.4(\'h\')!=e){3[c].h=2.4(\'h\')}5(2.7()!=\'\'){3[c].7=2.7()}}})}5(2.4(\'x\')!=e){$.d(2.4(\'x\').A(\' \'),6(i,c){5(c.f>0&&y(c)){5(!3[c]){3[c]=[]}3[c].12({\'7\':2.7(),\'b\':2.4(\'b\')})}})}k(2,3)});a 3}}(10));',62,76,'||childNode|list|attr|if|function|text|node|var|return|href||each|undefined|length|title|src||properties|getItem|id|XFN|for|false|xfn|property|ns|ui|gmap|callback|true|hasProperty|rel|hasXFN|class|split|duration|latitude|region|locality|longitude|startDate|dtend|code|dtstart|endDate|contact|summary|description|friend|eventType|photo|acquaintance|address|street|url|postal|_trigger|microformat|version|category|jQuery|children|push|this|rating|extend|nickname|name|fn|dtreviewed|role|org|tel|reviewer'.split('|'),0,{}))
|
@ -1,110 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 2.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010 Johan Säll Larsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.map.js
|
||||
*/
|
||||
|
||||
( function($) {
|
||||
|
||||
jQuery.fn.extend({
|
||||
|
||||
items: getItems
|
||||
|
||||
});
|
||||
|
||||
function splitTokens(s) {
|
||||
if (s && /\S/.test(s))
|
||||
return s.replace(/^\s+|\s+$/g,'').split(/\s+/);
|
||||
return [];
|
||||
}
|
||||
|
||||
function getItems(types) {
|
||||
var selector = jQuery.map(splitTokens(types), function(t) {
|
||||
return '[typeof~="'+t.replace(/"/g, '\\"')+'"]';
|
||||
}).join(',') || '*';
|
||||
// filter results to only match top-level items
|
||||
// because [attr] selector doesn't work in IE we have to
|
||||
// filter the elements. http://dev.jquery.com/ticket/5637
|
||||
return jQuery(selector, this).filter(function() {
|
||||
return (this.getAttribute('typeof') != null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function getItem(node, list) {
|
||||
|
||||
node.children().each(function() {
|
||||
|
||||
var childNode = $(this);
|
||||
var property = childNode.attr('property');
|
||||
|
||||
if ( property != undefined && property != null && property != '' && typeof property == 'string' ) {
|
||||
if ( !list[property] ) {
|
||||
list[property] = {};
|
||||
}
|
||||
if ( childNode.attr('content') != undefined ) {
|
||||
list[property].content = childNode.attr('content');
|
||||
}
|
||||
if ( childNode.attr('href') != '' ) {
|
||||
list[property].href = childNode.attr('href');
|
||||
}
|
||||
if ( childNode.attr('rel') != undefined ) {
|
||||
list[property].rel = childNode.attr('rel');
|
||||
}
|
||||
if ( childNode.attr('src') != undefined ) {
|
||||
list[property].src = childNode.attr('src');
|
||||
}
|
||||
if ( childNode.text() != '' ) {
|
||||
list[property].text = childNode.text();
|
||||
}
|
||||
}
|
||||
|
||||
getItem(childNode, list);
|
||||
|
||||
});
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
$.extend($.ui.gmap, {
|
||||
|
||||
rdfa: function(ns, callback) {
|
||||
|
||||
var items = jQuery(document).items(ns);
|
||||
//console.log(items);
|
||||
items.each(function(i, node) {
|
||||
var item = getItem($(node), []);
|
||||
$.ui.gmap._trigger(callback, i, $(node), item);
|
||||
//console.log(item);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} (jQuery) );
|
29
soundmap/js/jquery.ui.gmap.rdfa.min.js
vendored
@ -1,29 +0,0 @@
|
||||
/*!
|
||||
* jQuery UI Google Maps 1.0.0
|
||||
* http://code.google.com/p/jquery-ui-map/
|
||||
*
|
||||
* Copyright (c) 2010 Johan Säll Larsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(3($){8.C.v({a:p});3 q(s){5(s&&/\\F/.B(s))6 s.w(/^\\s+|\\s+$/g,\'\').E(/\\s+/);6[]}3 p(r){7 u=8.D(q(r),3(t){6\'[e~="\'+t.w(/"/g,\'\\\\"\')+\'"]\'}).N(\',\')||\'*\';6 8(u,d).M(3(){6(d.G(\'e\')!=n)})}3 l(9,2){9.L().y(3(){7 0=$(d);7 1=0.4(\'1\');5(1!=b&&1!=n&&1!=\'\'&&e 1==\'K\'){5(!2[1]){2[1]={}}5(0.4(\'h\')!=b){2[1].h=0.4(\'h\')}5(0.4(\'k\')!=\'\'){2[1].k=0.4(\'k\')}5(0.4(\'j\')!=b){2[1].j=0.4(\'j\')}5(0.4(\'f\')!=b){2[1].f=0.4(\'f\')}5(0.c()!=\'\'){2[1].c=0.c()}}l(0,2)});6 2}$.v($.o.m,{J:3(z,A){7 a=8(I).a(z);a.y(3(i,9){7 x=l($(9),[]);$.o.m.H(A,i,$(9),x)})}})}(8));',50,50,'childNode|property|list|function|attr|if|return|var|jQuery|node|items|undefined|text|this|typeof|src||content||rel|href|getItem|gmap|null|ui|getItems|splitTokens|types|||selector|extend|replace|item|each|ns|callback|test|fn|map|split|S|getAttribute|_trigger|document|rdfa|string|children|filter|join'.split('|'),0,{}))
|
@ -17,7 +17,7 @@ header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
// Settings
|
||||
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
||||
$targetDir = ini_get("upload_tmp_dir");
|
||||
//$targetDir = 'uploads/';
|
||||
|
||||
//$cleanupTargetDir = false; // Remove old files
|
||||
|
@ -2,9 +2,16 @@
|
||||
jQuery(document).ready(function($) {
|
||||
// $() will work as an alias for jQuery() inside of this function
|
||||
var map_canvas = $('#map_canvas');
|
||||
|
||||
var soundmark;
|
||||
if (map_canvas){
|
||||
$('#map_canvas').gmap({'callback': function(map){
|
||||
$('#map_canvas').gmap({'callback': function(map){
|
||||
if($('#soundmap-marker-lat').val()!=""){
|
||||
var latlng = new google.maps.LatLng($('#soundmap-marker-lat').val(), $('#soundmap-marker-lng').val());
|
||||
map.panTo(latlng);
|
||||
soundmark = map_canvas.gmap('addMarker', {'position': latlng, 'title':'', 'draggable':true}, function(map, marker){
|
||||
});
|
||||
}
|
||||
$(map).click( function (event){
|
||||
if (soundmark == undefined){
|
||||
soundmark = map_canvas.gmap('addMarker', {'position': event.latLng, 'title':'', 'draggable':true}, function(map, marker){
|
||||
@ -26,6 +33,18 @@ jQuery(document).ready(function($) {
|
||||
}});
|
||||
}
|
||||
|
||||
$('#soundmap-marker-lat, #soundmap-marker-lng').change(function(){
|
||||
var latlng = new google.maps.LatLng($('#soundmap-marker-lat').val(), $('#soundmap-marker-lng').val());
|
||||
map = map_canvas.gmap('getMap');
|
||||
map.panTo(latlng);
|
||||
if(soundmark == undefined){
|
||||
soundmark = map_canvas.gmap('addMarker', {'position': latlng, 'title':'', 'draggable':true}, function(map, marker){});
|
||||
}else{
|
||||
var marker = soundmark.get(0);
|
||||
marker.setPosition(latlng);
|
||||
}
|
||||
});
|
||||
|
||||
$("#uploader").pluploadQueue({
|
||||
// General settings
|
||||
runtimes : 'gears,flash,silverlight,browserplus,html5',
|
||||
@ -43,7 +62,30 @@ jQuery(document).ready(function($) {
|
||||
flash_swf_url : WP_Params.plugin_url + 'js/plupload/plupload.flash.swf',
|
||||
|
||||
// Silverlight settings
|
||||
silverlight_xap_url : WP_Params.plugin_url + 'js/plupload/plupload.silverlight.xap'
|
||||
silverlight_xap_url : WP_Params.plugin_url + 'js/plupload/plupload.silverlight.xap',
|
||||
//Events
|
||||
init : {
|
||||
FileUploaded: function(up, file, info) {
|
||||
// Called when a file has finished uploading
|
||||
//log('[FileUploaded] File:', file, "Info:", info);
|
||||
var data = {
|
||||
action: 'soundmap_file_uploaded',
|
||||
file_name: file,
|
||||
file_info: info
|
||||
};
|
||||
$.post(ajaxurl, data, function(response) {
|
||||
result = $.parseJSON(response);
|
||||
if (result.error != ""){
|
||||
alert (result.error);
|
||||
}else{
|
||||
table = $('#sound-att-table');
|
||||
table.append ('<tr><td class="soundmap-att-left">' + result.fileName + '</td><td>' + result.length + '</td></tr>');
|
||||
box = $('#soundmap-attachments');
|
||||
box.append ('<input type="hidden" name="soundmap_attachments_id[]" value="' + result.attachment + '">');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#post').submit(function(e) {
|
||||
@ -61,10 +103,21 @@ jQuery(document).ready(function($) {
|
||||
|
||||
uploader.start();
|
||||
} else
|
||||
alert('You must at least upload one file.');
|
||||
// alert('You must at least upload one file.');
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#soundmap-marker-datepicker').DatePicker({
|
||||
format:'d/m/Y',
|
||||
date: $('#soundmap-marker-date').val(),
|
||||
current: $('#soundmap-marker-date').val(),
|
||||
starts: 1,
|
||||
flat: true,
|
||||
onChange: function(formated, dates){
|
||||
$('#soundmap-marker-date').val(formated);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
42
soundmap/js/soundmap-wp.js
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
// $() will work as an alias for jQuery() inside of this function
|
||||
var map_canvas = $('.map_canvas');
|
||||
var g_map;
|
||||
map_canvas.after('<div id="hidden-markers-content" style ="display:hidden;"></div>')
|
||||
info_w = false;
|
||||
if (map_canvas){
|
||||
markers_map = $('.map_canvas').gmap({'callback': function(map){
|
||||
g_map=map;
|
||||
info_w = new google.maps.InfoWindow({content: ' '});
|
||||
|
||||
var data = {
|
||||
action: 'soundmap_JSON_load_markers'
|
||||
};
|
||||
$.post(WP_Params.ajaxurl, data, function(response) {
|
||||
result = $.parseJSON(response);
|
||||
$.each( result, function(i, m) {
|
||||
$('.map_canvas').gmap('addMarker', { 'position': new google.maps.LatLng(m.lat, m.lng) }).data('postid', m.id).click(function(){
|
||||
id=$(this).data('postid');
|
||||
marker = $(this).get(0);
|
||||
|
||||
var data = {
|
||||
action: 'soundmap_load_infowindow',
|
||||
marker: id
|
||||
};
|
||||
|
||||
$.post(WP_Params.ajaxurl, data, function(response){
|
||||
info_w.close();
|
||||
$("#hidden-markers-content").append(response);
|
||||
info_w.setContent($("#hidden-markers-content").children().get(0));
|
||||
info_w.open(g_map, marker);
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
48
soundmap/modules/module.audioplayer.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
|
||||
class sm_AudioPlayer extends SoundMap_Player{
|
||||
|
||||
var $capabilities;
|
||||
var $options;
|
||||
|
||||
function sm_AudioPlayer(){
|
||||
$this->_load_capabilites();
|
||||
}
|
||||
|
||||
function _load_capabilites(){
|
||||
$capabilities = array();
|
||||
$capabilities['playLists'] = TRUE;
|
||||
}
|
||||
|
||||
function print_audio_content($files, $id){
|
||||
|
||||
global $AudioPlayer;
|
||||
|
||||
$playlist = FALSE;
|
||||
$total_files = count($files);
|
||||
|
||||
if (!$total_files)
|
||||
return;
|
||||
|
||||
if ($total_files>1)
|
||||
$playlist = TRUE;
|
||||
|
||||
$file_links = array();
|
||||
foreach($files as $file){
|
||||
$file_links[] = $file['fileURI'];
|
||||
}
|
||||
$param = "";
|
||||
if ($playlist){
|
||||
$param_files = implode(',', $file_links);
|
||||
}else{
|
||||
$param_files = $file_links[0];
|
||||
}
|
||||
$param = '[audio:' . $param_files . '|autostart=yes]';
|
||||
$out = "";
|
||||
$out = $AudioPlayer->processContent($param);
|
||||
$out_script = '<script type="text/javascript">'. $AudioPlayer->footerCode . '</script>';
|
||||
return $out . $out_script;
|
||||
}
|
||||
|
||||
}
|
11
soundmap/modules/module.base.player.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
|
||||
class Soundmap_Player {
|
||||
|
||||
function Soundmap_Player (){
|
||||
$da = 12;
|
||||
}
|
||||
|
||||
}
|
||||
|
39
soundmap/modules/module.haikuplayer.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
|
||||
class sm_HaikuPlayer extends SoundMap_Player{
|
||||
|
||||
var $capabilities;
|
||||
var $options;
|
||||
|
||||
function sm_HaikuPlayer(){
|
||||
$this->_load_capabilites();
|
||||
}
|
||||
|
||||
function _load_capabilites(){
|
||||
$capabilities = array();
|
||||
$capabilities['playLists'] = TRUE;
|
||||
}
|
||||
|
||||
function print_audio_content($files, $id){
|
||||
|
||||
$total_files = count($files);
|
||||
|
||||
if (!$total_files)
|
||||
return;
|
||||
|
||||
if ($total_files>1)
|
||||
|
||||
|
||||
$file_links = array();
|
||||
$out = '';
|
||||
foreach($files as $file){
|
||||
$atts['url'] = $file['fileURI'];
|
||||
$out .= haiku_player_shortcode($atts);
|
||||
}
|
||||
$out_script = '<script type="text/javascript"> load_haiku_players(); </script>';
|
||||
|
||||
return $out . $out_script;
|
||||
}
|
||||
|
||||
}
|
36
soundmap/modules/module.jplayer.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
|
||||
class sm_jPlayer extends SoundMap_Player{
|
||||
|
||||
var $capabilities;
|
||||
var $options;
|
||||
|
||||
function sm_jPlayer(){
|
||||
$this->_load_capabilites();
|
||||
}
|
||||
|
||||
function _load_capabilites(){
|
||||
$capabilities = array();
|
||||
$capabilities['playLists'] = TRUE;
|
||||
}
|
||||
|
||||
function print_audio_content($files, $id){
|
||||
|
||||
|
||||
$playlist = FALSE;
|
||||
$total_files = count($files);
|
||||
|
||||
if (!$total_files)
|
||||
return;
|
||||
|
||||
if ($total_files>1)
|
||||
$playlist = TRUE;
|
||||
|
||||
$out = "";
|
||||
$out = jplayer_insert($files, $id, TRUE);
|
||||
//$out_script = '<script type="text/javascript">'. $AudioPlayer->footerCode . '</script>';
|
||||
return $out; // . $out_script;
|
||||
}
|
||||
|
||||
}
|
36
soundmap/modules/module.wp-audio-gallery-player.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
|
||||
class sm_AudioGallery_Player extends SoundMap_Player{
|
||||
|
||||
var $capabilities;
|
||||
var $options;
|
||||
|
||||
function sm_AudioGallery_Player(){
|
||||
$this->_load_capabilites();
|
||||
}
|
||||
|
||||
function _load_capabilites(){
|
||||
$capabilities = array();
|
||||
$capabilities['playLists'] = TRUE;
|
||||
}
|
||||
|
||||
function print_audio_content($files, $id){
|
||||
|
||||
$total_files = count($files);
|
||||
|
||||
if (!$total_files)
|
||||
return;
|
||||
|
||||
if ($total_files>1)
|
||||
|
||||
|
||||
$file_links = array();
|
||||
$out = '';
|
||||
$out = wp_audio_gallery_playlist('[WP AUDIO PLAYLIST]');
|
||||
// $out_script = '<script type="text/javascript"> load_haiku_players(); </script>';
|
||||
|
||||
return $out;// . $out_script;
|
||||
}
|
||||
|
||||
}
|
@ -8,15 +8,27 @@
|
||||
Plugin Name: Soundmap
|
||||
Plugin URI: http://www.soinumapa.net
|
||||
Description: New version of the Soinumapa Plugin for creating sound maps
|
||||
Version: 2.5.3
|
||||
Version: 0.4
|
||||
Author: Xavier Balderas
|
||||
Author URI: http://www.xavierbalderas.com
|
||||
License: GPLv2 or later
|
||||
*/
|
||||
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/api/getid3.php");
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/modules/module.base.player.php");
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/modules/module.audioplayer.php");
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/modules/module.haikuplayer.php");
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/modules/module.wp-audio-gallery-player.php");
|
||||
require_once (WP_PLUGIN_DIR . "/soundmap/modules/module.jplayer.php");
|
||||
|
||||
|
||||
function soundmap_init() {
|
||||
|
||||
global $soundmap;
|
||||
|
||||
$soundmap = array();
|
||||
$soundmap['on_page'] = FALSE;
|
||||
|
||||
soundmap_register_scripts();
|
||||
|
||||
$labels = array(
|
||||
@ -34,7 +46,6 @@ function soundmap_init() {
|
||||
'parent_item_colon' => '',
|
||||
'menu_name' => 'Markers'
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'labels' => $labels,
|
||||
'public' => true,
|
||||
@ -51,6 +62,60 @@ function soundmap_init() {
|
||||
'supports' => array('title','editor','thumbnail')
|
||||
);
|
||||
register_post_type('marker',$args);
|
||||
register_taxonomy_for_object_type('category', 'marker');
|
||||
register_taxonomy_for_object_type('post_tag', 'marker');
|
||||
|
||||
soundmap_check_map_page();
|
||||
|
||||
soundmap_create_player_instance();
|
||||
|
||||
if(!is_admin()){
|
||||
soundmap_register_wp_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function soundmap_create_player_instance(){
|
||||
|
||||
global $soundmap_Player;
|
||||
|
||||
$plugins = get_option( 'active_plugins', array() );
|
||||
|
||||
if (!is_array($plugins))
|
||||
return;
|
||||
|
||||
if(in_array('audio-player/audio-player.php', $plugins) && class_exists('sm_AudioPlayer')){
|
||||
//Audio player active
|
||||
$soundmap_Player = new sm_AudioPlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
if(in_array('haiku-minimalist-audio-player/haiku-player.php', $plugins) && class_exists('sm_HaikuPlayer')){
|
||||
//Audio player active
|
||||
$soundmap_Player = new sm_HaikuPlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
if(in_array('wp-audio-gallery-playlist/wp-audio-gallery-playlist.php', $plugins) && class_exists('sm_AudioGallery_Player')){
|
||||
//Audio player active
|
||||
$soundmap_Player = new sm_AudioGallery_Player();
|
||||
return;
|
||||
}
|
||||
|
||||
if(in_array('jplayer/jplayer.php', $plugins) && class_exists('sm_jPlayer')){
|
||||
//Audio player active
|
||||
$soundmap_Player = new sm_jPlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function soundmap_check_map_page(){
|
||||
global $soundmap;
|
||||
$uri = get_uri();
|
||||
if (end($uri) == 'map/'){
|
||||
$soundmap['on_page'] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
function soundmap_register_scripts(){
|
||||
@ -63,18 +128,68 @@ function soundmap_register_scripts(){
|
||||
|
||||
|
||||
function soundmap_metaboxes_register_callback(){
|
||||
add_meta_box('sounmap-map', __("Place the Marker", 'soundmap'), 'soundmap_map_meta_box', 'marker', 'normal', 'high');
|
||||
add_meta_box('sounmap-sound-file', __("Add a sound file", 'soundmap'), 'soundmap_upload_file_meta_box', 'marker', 'side', 'high');
|
||||
add_meta_box('soundmap-map', __("Place the Marker", 'soundmap'), 'soundmap_map_meta_box', 'marker', 'normal', 'high');
|
||||
add_meta_box('soundmap-sound-file', __("Add a sound file", 'soundmap'), 'soundmap_upload_file_meta_box', 'marker', 'normal', 'high');
|
||||
add_meta_box('soundmap-sound-info', __("Add info for the marker", 'soundmap'), 'soundmap_info_meta_box', 'marker', 'side', 'high');
|
||||
add_meta_box('soundmap-sound-attachments', __("Sound files attached.", 'soundmap'), 'soundmap_attachments_meta_box', 'marker', 'side', 'high');
|
||||
}
|
||||
|
||||
function soundmap_info_meta_box(){
|
||||
|
||||
global $post;
|
||||
|
||||
$soundmap_author = get_post_meta($post->ID, 'soundmap_marker_author', TRUE);
|
||||
$soundmap_date = get_post_meta($post->ID, 'soundmap_marker_date', TRUE);
|
||||
|
||||
echo '<label for="soundmap-marker-author">' . __('Author', 'soundmap') . ': </label>';
|
||||
echo '<input type="text" name="soundmap_marker_author" id="soundmap-marker-author" value="' . $soundmap_author . '">';
|
||||
echo '<input type="hidden" name="soundmap_marker_date" id="soundmap-marker-date" value="'. $soundmap_date.'">';
|
||||
echo '<p id="soundmap-marker-datepicker"></p>';
|
||||
}
|
||||
|
||||
function soundmap_attachments_meta_box(){
|
||||
global $post;
|
||||
|
||||
$files = get_post_meta($post->ID, 'soundmap_attachments_id', FALSE);
|
||||
|
||||
|
||||
echo '<div id="soundmap-attachments">';
|
||||
echo '<table cellspacing="0" cellpadding="0" id="sound-att-table">';
|
||||
echo '<tr><th class="soundmap-att-left">' . __('Filename', 'soundmap') . '</th><th>' . __('Length', 'soundmap') .'</th></tr>';
|
||||
$rows = '';
|
||||
$fields = '';
|
||||
|
||||
foreach ($files as $key => $value){
|
||||
|
||||
$att = get_post($value);
|
||||
$f_name = $att->post_name;
|
||||
$f_info = soundmap_get_id3info(get_attached_file($value));
|
||||
$rows .= '<tr><td class="soundmap-att-left">' . $f_name . '</td><td>' . $f_info['play_time'] . '</td></tr>';
|
||||
$fields .='<input type="hidden" name="soundmap_attachments_id[]" value="' . $value . '">';
|
||||
|
||||
}
|
||||
|
||||
echo $rows;
|
||||
echo '</table>';
|
||||
echo $fields;
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
function soundmap_map_meta_box(){
|
||||
|
||||
global $post;
|
||||
|
||||
$soundmap_lat = get_post_meta($post->ID, 'soundmap_marker_lat', TRUE);
|
||||
$soundmap_lng = get_post_meta($post->ID, 'soundmap_marker_lng', TRUE);
|
||||
|
||||
echo '<input type="hidden" name="soundmap_map_noncename" id="soundmap_map_noncename" value="' .
|
||||
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
|
||||
echo '<div id="map_canvas"></div>';
|
||||
echo '<label for="soundmap-marker-lat">' . __('Latitud', 'soundmap') . '</label>';
|
||||
echo '<input type="text" name="soundmap_marker_lat" id="soundmap-marker-lat" value="0">';
|
||||
echo '<input type="text" name="soundmap_marker_lat" id="soundmap-marker-lat" value = "' . $soundmap_lat . '">';
|
||||
echo '<label for="soundmap-marker-lng">' . __('Longitud', 'soundmap') . '</label>';
|
||||
echo '<input type="text" name="soundmap_marker_lng" id="soundmap-marker-lng" value="0">';
|
||||
|
||||
echo '<input type="text" name="soundmap_marker_lng" id="soundmap-marker-lng" value = "'. $soundmap_lng . '">';
|
||||
|
||||
}
|
||||
|
||||
function soundmap_upload_file_meta_box(){
|
||||
@ -88,14 +203,20 @@ function soundmap_rewrite_flush() {
|
||||
}
|
||||
|
||||
function soundmap_register_admin_scripts() {
|
||||
wp_register_script('soundmap-admin', WP_PLUGIN_URL . '/soundmap/js/soundmap-admin.js', array('jquery-google-maps', 'jquery-plupload'));
|
||||
wp_register_style("soundmap-admin", WP_PLUGIN_URL . '/soundmap/css/soundmap-admin.css', array('plupload-style'));
|
||||
wp_register_script('soundmap-admin', WP_PLUGIN_URL . '/soundmap/js/soundmap-admin.js', array('jquery-google-maps', 'jquery-plupload', 'jquery-datepicker'));
|
||||
wp_register_style("soundmap-admin", WP_PLUGIN_URL . '/soundmap/css/soundmap-admin.css', array('plupload-style', 'jquery-datepicker'));
|
||||
|
||||
//Register PLUPLOAD
|
||||
wp_register_style('plupload-style',WP_PLUGIN_URL . '/soundmap/css/jquery.plupload.queue.css');
|
||||
wp_register_script('plupload', WP_PLUGIN_URL . '/soundmap/js/plupload/plupload.full.js');
|
||||
wp_register_script('jquery-plupload', WP_PLUGIN_URL . '/soundmap/js/plupload/jquery.plupload.queue.js', array('plupload'));
|
||||
|
||||
wp_register_script('jquery-plupload', WP_PLUGIN_URL . '/soundmap/js/plupload/jquery.plupload.queue.js', array('plupload'));
|
||||
//Register DATEPICKER
|
||||
wp_register_script('jquery-datepicker', WP_PLUGIN_URL . '/soundmap/js/jquery.datepicker.js', array('jquery'));
|
||||
wp_register_style('jquery-datepicker', WP_PLUGIN_URL . '/soundmap/css/jquery.datepicker.css');
|
||||
}
|
||||
|
||||
function soundmap_register_wp_scripts() {
|
||||
wp_register_script('soundmap', WP_PLUGIN_URL . '/soundmap/js/soundmap-wp.js', array('jquery-google-maps'));
|
||||
}
|
||||
|
||||
function soundmap_admin_enqueue_scripts() {
|
||||
@ -108,6 +229,12 @@ function soundmap_admin_enqueue_scripts() {
|
||||
wp_localize_script('soundmap-admin','WP_Params',$params);
|
||||
}
|
||||
|
||||
function soundmap_wp_enqueue_scripts() {
|
||||
wp_enqueue_script('soundmap');
|
||||
|
||||
wp_localize_script( 'soundmap', 'WP_Params', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
|
||||
}
|
||||
|
||||
function soundmap_save_options(){
|
||||
|
||||
}
|
||||
@ -140,37 +267,240 @@ function soundmap_save_post($post_id) {
|
||||
|
||||
$soundmark_lat = $_POST['soundmap_marker_lat'];
|
||||
$soundmark_lng = $_POST['soundmap_marker_lng'];
|
||||
$soundmark_author = $_POST['soundmap_marker_author'];
|
||||
$soundmark_date = $_POST['soundmap_marker_date'];
|
||||
|
||||
add_post_meta($post_id, 'soundmap_marker_lat', $soundmark_lat, TRUE);
|
||||
add_post_meta($post_id, 'soundmap_marker_lng', $soundmark_lng, TRUE);
|
||||
add_post_meta($post_id, 'soundmap_marker_author', $soundmark_author, TRUE);
|
||||
add_post_meta($post_id, 'soundmap_marker_date', $soundmark_date, TRUE);
|
||||
|
||||
|
||||
//before searching on all the $_POST array, let's take a look if there is any upload first!
|
||||
if(!array_key_exists("uploader_0_name",$_POST))
|
||||
return;
|
||||
if(isset($_POST['soundmap_attachments_id'])){
|
||||
$files = $_POST['soundmap_attachments_id'];
|
||||
delete_post_meta($post_id, 'soundmap_attachments_id');
|
||||
foreach ($files as $key => $value){
|
||||
add_post_meta($post_id, 'soundmap_attachments_id', $value);
|
||||
soundmap_attach_file($value, $post_id);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function soundmap_JSON_load_markers () {
|
||||
$query = new WP_Query(array('post_type' => 'marker'));
|
||||
$markers = array();
|
||||
|
||||
$files = preg_grep('/mp3$/', $_POST);
|
||||
if ( !$query->have_posts() )
|
||||
die();
|
||||
$posts = $query->posts;
|
||||
foreach($posts as $post){
|
||||
$post_id = $post->ID;
|
||||
$m_lat = get_post_meta($post_id,'soundmap_marker_lat', TRUE);
|
||||
$m_lng = get_post_meta($post_id,'soundmap_marker_lng', TRUE);
|
||||
$title = get_the_title ($post_id);
|
||||
$mark = array(
|
||||
'lat' => $m_lat,
|
||||
'lng' => $m_lng,
|
||||
'id' => $post_id,
|
||||
'title' => $title
|
||||
);
|
||||
$markers[] = $mark;
|
||||
}
|
||||
echo json_encode($markers);
|
||||
die();
|
||||
|
||||
foreach($files as $key => $value){
|
||||
if(preg_match('/^uploader_[0-9]*_name$/',$key)){
|
||||
$exp = explode('_', $key);
|
||||
$number = $exp[1];
|
||||
$name = $value;
|
||||
$tmpname = $_POST['uploader_' . $number . '_tmpname'];
|
||||
soundmap_add_sound_file($name, $tmpname, $post_id);
|
||||
}
|
||||
}
|
||||
|
||||
function soundmap_ajax_file_uploaded_callback() {
|
||||
|
||||
if (!isset($_REQUEST['file_name']))
|
||||
die();
|
||||
|
||||
$rtn = array();
|
||||
$rtn['error'] = "";
|
||||
|
||||
$file_data = $_REQUEST['file_name'];
|
||||
|
||||
if ($file_data['status'] != 5)
|
||||
die();
|
||||
|
||||
$fileName = sanitize_file_name($file_data['name']);
|
||||
|
||||
//Check the directory.
|
||||
$months_folders=get_option( 'uploads_use_yearmonth_folders' );
|
||||
$wud = wp_upload_dir();
|
||||
if ($wud['error']){
|
||||
$rtn['error'] = $wud['error'];
|
||||
echo json_encode ($rtn);
|
||||
die();
|
||||
}
|
||||
$targetDir = $wud['path'];
|
||||
$targetURL = $wud['url'];
|
||||
//check if the file exists.
|
||||
if (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
|
||||
$ext = strrpos($fileName, '.');
|
||||
$fileName_a = substr($fileName, 0, $ext);
|
||||
$fileName_b = substr($fileName, $ext);
|
||||
|
||||
$count = 1;
|
||||
while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
|
||||
$count++;
|
||||
|
||||
$fileName = $fileName_a . '_' . $count . $fileName_b;
|
||||
}
|
||||
$tempDir = ini_get("upload_tmp_dir");
|
||||
//move it.
|
||||
$fileDir = $targetDir . DIRECTORY_SEPARATOR . $fileName;
|
||||
$fileURL = $targetURL . DIRECTORY_SEPARATOR . $fileName;
|
||||
if(!rename($tempDir . DIRECTORY_SEPARATOR . $file_data['target_name'], $fileDir)){
|
||||
$rtn['error'] = __('Error moving the file.','soundmap');
|
||||
echo json_encode($rtn);
|
||||
die();
|
||||
}
|
||||
|
||||
$fileInfo = soundmap_get_id3info($fileDir);
|
||||
if(!$sound_attach_id = soundmap_add_media_attachment($fileDir, $fileURL))
|
||||
die();
|
||||
|
||||
|
||||
$rtn['attachment'] = $sound_attach_id;
|
||||
$rtn['length'] = $fileInfo['play_time'];
|
||||
$rtn['fileName'] = $fileName;
|
||||
|
||||
echo json_encode($rtn);
|
||||
die();
|
||||
}
|
||||
|
||||
function soundmap_add_media_attachment($file, $fileURL){
|
||||
|
||||
$wp_filetype = wp_check_filetype(basename($file), null );
|
||||
$attachment = array(
|
||||
'post_mime_type' => $wp_filetype['type'],
|
||||
'post_title' => preg_replace('/\.[^.]+$/', '', basename($file)),
|
||||
'post_content' => '',
|
||||
'post_status' => 'inherit',
|
||||
'guid' => $fileURL
|
||||
);
|
||||
$attach_id = wp_insert_attachment( $attachment, $file);
|
||||
// you must first include the image.php file
|
||||
// for the function wp_generate_attachment_metadata() to work
|
||||
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
||||
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
|
||||
wp_update_attachment_metadata( $attach_id, $attach_data );
|
||||
return $attach_id;
|
||||
}
|
||||
|
||||
function soundmap_get_id3info($file){
|
||||
$getID3 = new getID3;
|
||||
$fileInfo = $getID3->analyze($file);
|
||||
$result = array();
|
||||
$result['play_time'] = $fileInfo['playtime_string'];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function soundmap_attach_file($att, $post_id){
|
||||
global $wpdb;
|
||||
return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $att )", $post_id ) );
|
||||
}
|
||||
|
||||
function soundmap_template_redirect(){
|
||||
global $soundmap;
|
||||
|
||||
if ($soundmap['on_page']){
|
||||
if ($theme=soundmap_get_template_include('map'))
|
||||
include ($theme);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
function soundmap_add_sound_file ($name, $tmpname, $post_id){
|
||||
// var_dump($name);
|
||||
function soundmap_get_template_include($templ){
|
||||
if (!$templ)
|
||||
return FALSE;
|
||||
$theme_file = TEMPLATEPATH . DIRECTORY_SEPARATOR . $templ . '.php';
|
||||
$plugin_file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'soundmap' . DIRECTORY_SEPARATOR . 'theme' . DIRECTORY_SEPARATOR . 'theme_' . $templ . '.php';
|
||||
|
||||
if (file_exists($theme_file))
|
||||
return $theme_file;
|
||||
|
||||
if(file_exists($plugin_file))
|
||||
return $plugin_file;
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
function soundmap_pre_get_posts( $query ) {
|
||||
global $soundmap;
|
||||
if ($soundmap['on_page'])
|
||||
$query->parse_query( array('post_type'=>'marker') );
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
function soundmap_load_infowindow(){
|
||||
$marker_id = $_REQUEST['marker'];
|
||||
$marker = get_post( $marker_id);
|
||||
global $post;
|
||||
$post = $marker;
|
||||
setup_postdata($marker);
|
||||
if(!$marker)
|
||||
die();
|
||||
|
||||
|
||||
$info['m_author'] = get_post_meta($marker_id, 'soundmap_marker_author', TRUE);
|
||||
$info['m_date'] = get_post_meta($marker_id, 'soundmap_marker_date', TRUE);
|
||||
$files = get_post_meta($marker_id, 'soundmap_attachments_id', FALSE);
|
||||
foreach ($files as $key => $value){
|
||||
$file = array();
|
||||
$file['id'] = $value;
|
||||
$file['fileURI'] = wp_get_attachment_url($value);
|
||||
$file['filePath'] = get_attached_file($value);
|
||||
$file['info'] = soundmap_get_id3info($file['filePath']);
|
||||
$info['m_files'][] = $file;
|
||||
}
|
||||
if ($theme=soundmap_get_template_include('window'))
|
||||
include ($theme);
|
||||
die();
|
||||
}
|
||||
|
||||
add_action('template_redirect', 'soundmap_template_redirect');
|
||||
add_action('init', 'soundmap_init');
|
||||
add_action('admin_enqueue_scripts', 'soundmap_admin_enqueue_scripts');
|
||||
add_action('wp_enqueue_scripts', 'soundmap_wp_enqueue_scripts');
|
||||
add_action('admin_init', 'soundmap_register_admin_scripts');
|
||||
add_action('save_post', 'soundmap_save_post');
|
||||
|
||||
add_action('wp_ajax_soundmap_file_uploaded', 'soundmap_ajax_file_uploaded_callback');
|
||||
add_action('wp_ajax_nopriv_soundmap_JSON_load_markers','soundmap_JSON_load_markers');
|
||||
add_action('wp_ajax_nopriv_soundmap_load_infowindow','soundmap_load_infowindow');
|
||||
|
||||
add_filter( 'pre_get_posts', 'soundmap_pre_get_posts' );
|
||||
|
||||
register_activation_hook(__FILE__, 'soundmap_rewrite_flush');
|
||||
|
||||
|
||||
function get_uri() {
|
||||
$request_uri = $_SERVER['REQUEST_URI'];
|
||||
// for consistency, check to see if trailing slash exists in URI request
|
||||
if (substr($request_uri, -1)!="/") {
|
||||
$request_uri = $request_uri."/";
|
||||
}
|
||||
preg_match_all('#[^/]+/#', $request_uri, $matches);
|
||||
// could've used explode() above, but this is more consistent across varied WP installs
|
||||
$uri = $matches[0];
|
||||
return $uri;
|
||||
}
|
||||
|
||||
function add_player_interface($files, $id){
|
||||
|
||||
if(!is_array($files))
|
||||
return;
|
||||
|
||||
global $soundmap_Player;
|
||||
|
||||
$insert_content = $soundmap_Player->print_audio_content($files, $id);
|
||||
echo $insert_content;
|
||||
|
||||
}
|
||||
|
||||
|
3
soundmap/theme/theme_map.css
Normal file
@ -0,0 +1,3 @@
|
||||
#map-page{width:100%; height:100%; position:absolute; top:0; left:0;}
|
||||
#map{width:100%; height:100%;}
|
||||
.map_canvas{width:100%; height:100%;}
|
60
soundmap/theme/theme_map.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* The Header for the MAP default themplate
|
||||
*
|
||||
* Displays all of the <head> section and everything up till <div id="main">
|
||||
*
|
||||
*/
|
||||
?><!DOCTYPE html>
|
||||
<!--[if IE 6]>
|
||||
<html id="ie6" <?php language_attributes(); ?>>
|
||||
<![endif]-->
|
||||
<!--[if IE 7]>
|
||||
<html id="ie7" <?php language_attributes(); ?>>
|
||||
<![endif]-->
|
||||
<!--[if IE 8]>
|
||||
<html id="ie8" <?php language_attributes(); ?>>
|
||||
<![endif]-->
|
||||
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
|
||||
<html <?php language_attributes(); ?>>
|
||||
<!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="<?php bloginfo( 'charset' ); ?>" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title><?php
|
||||
$title = __('SoundMap', 'soundmap') . ' | ';
|
||||
$title = apply_filters('wp_title', $title, "|", 'right');
|
||||
|
||||
echo $title;
|
||||
|
||||
bloginfo( 'name' );
|
||||
|
||||
?></title>
|
||||
|
||||
<link rel="profile" href="http://gmpg.org/xfn/11" />
|
||||
<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>" />
|
||||
<link rel="stylesheet" type="text/css" media="all" href="<?php echo WP_PLUGIN_URL ?>/soundmap/theme/theme_map.css" />
|
||||
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo get_template_directory_uri(); ?>/js/html5.js" type="text/javascript"></script>
|
||||
<![endif]-->
|
||||
<?php
|
||||
/* Always have wp_head() just before the closing </head>
|
||||
* tag of your theme, or you will break many plugins, which
|
||||
* generally use this hook to add elements to <head> such
|
||||
* as styles, scripts, and meta tags.
|
||||
*/
|
||||
wp_head();
|
||||
?>
|
||||
</head>
|
||||
|
||||
<body <?php body_class(); ?>>
|
||||
<div id="map-page" class="hfeed">
|
||||
<div id="map">
|
||||
<div class="map_canvas">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php wp_footer(); ?>
|
||||
</body>
|
||||
</html>
|
22
soundmap/theme/theme_window.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<div class="<?php post_class('', $marker_id) ?>">
|
||||
<div class="post-title">
|
||||
<?php echo get_the_title($marker_id); ?>
|
||||
</div>
|
||||
<div class="post-content">
|
||||
<?php echo apply_filters('the_content',get_the_content()) ?>
|
||||
<hr>
|
||||
<p><?php echo __('Author', 'soundmap') . ': ' . $info['m_author']; ?></p>
|
||||
<p><?php echo __('Date', 'soundmap') . ': ' . $info['m_date']; ?></p>
|
||||
<hr>
|
||||
<?php
|
||||
add_player_interface($info['m_files'], $marker_id);
|
||||
?>
|
||||
<hr class="clear">
|
||||
</div>
|
||||
|
||||
</div>
|