From 5e4ce5bd4f71442faf4dafa41482722f7a45be23 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 9 Dec 2010 15:42:05 -0500 Subject: [PATCH 1/3] Added new audio samples. Removed old files that are no longer in use. --- backend/.htaccess | 12 - backend/AccessRecur.php | 184 - backend/Alib.php | 622 --- backend/Backup.php | 487 --- backend/BasicStor.php | 2186 ---------- backend/GreenBox.php | 1726 -------- backend/LocStor.php | 1749 -------- backend/M3uPlaylist.php | 352 -- backend/Playlist.php | 1497 ------- backend/Prefs.php | 442 -- backend/Renderer.php | 290 -- backend/Restore.php | 436 -- backend/Schedule.php | 560 --- backend/SmilPlaylist.php | 313 -- backend/StoredFile.php | 1729 -------- backend/Subjects.php | 683 --- backend/Transport.php | 1833 -------- backend/TransportRecord.php | 419 -- backend/Validator.php | 385 -- backend/XmlParser.php | 398 -- backend/audioClipFormat.php | 328 -- backend/configure | 47 - backend/cron/Cron.php | 214 - backend/cron/CronJob.php | 17 - backend/cron/Crontab.php | 284 -- backend/cron/croncall.php | 9 - backend/cron/transportCron.php | 21 - backend/cron/transportCronJob.php | 42 - backend/etc/Makefile.in | 259 -- backend/etc/configure.ac | 220 - backend/genres.xml | 136 - backend/index.php | 17 - backend/playlistFormat.php | 117 - backend/propel-db/build.properties | 7 - .../build/classes/campcaster/CcAccess.php | 18 - .../build/classes/campcaster/CcAccessPeer.php | 18 - .../classes/campcaster/CcAccessQuery.php | 18 - .../build/classes/campcaster/CcBackup.php | 18 - .../build/classes/campcaster/CcBackupPeer.php | 18 - .../classes/campcaster/CcBackupQuery.php | 18 - .../build/classes/campcaster/CcFiles.php | 31 - .../build/classes/campcaster/CcFilesPeer.php | 18 - .../build/classes/campcaster/CcFilesQuery.php | 18 - .../build/classes/campcaster/CcPerms.php | 18 - .../build/classes/campcaster/CcPermsPeer.php | 18 - .../build/classes/campcaster/CcPermsQuery.php | 18 - .../build/classes/campcaster/CcPlaylist.php | 48 - .../classes/campcaster/CcPlaylistPeer.php | 18 - .../classes/campcaster/CcPlaylistQuery.php | 18 - .../classes/campcaster/CcPlaylistcontents.php | 78 - .../campcaster/CcPlaylistcontentsPeer.php | 18 - .../campcaster/CcPlaylistcontentsQuery.php | 18 - .../build/classes/campcaster/CcPref.php | 18 - .../build/classes/campcaster/CcPrefPeer.php | 18 - .../build/classes/campcaster/CcPrefQuery.php | 18 - .../build/classes/campcaster/CcSchedule.php | 18 - .../classes/campcaster/CcSchedulePeer.php | 18 - .../classes/campcaster/CcScheduleQuery.php | 18 - .../build/classes/campcaster/CcSess.php | 18 - .../build/classes/campcaster/CcSessPeer.php | 18 - .../build/classes/campcaster/CcSessQuery.php | 18 - .../build/classes/campcaster/CcSmemb.php | 18 - .../build/classes/campcaster/CcSmembPeer.php | 18 - .../build/classes/campcaster/CcSmembQuery.php | 18 - .../build/classes/campcaster/CcSubjs.php | 18 - .../build/classes/campcaster/CcSubjsPeer.php | 18 - .../build/classes/campcaster/CcSubjsQuery.php | 18 - .../build/classes/campcaster/CcTrans.php | 18 - .../build/classes/campcaster/CcTransPeer.php | 18 - .../build/classes/campcaster/CcTransQuery.php | 18 - .../build/classes/campcaster/Common.php | 19 - .../campcaster/map/CcAccessTableMap.php | 61 - .../campcaster/map/CcBackupTableMap.php | 55 - .../campcaster/map/CcFilesTableMap.php | 107 - .../campcaster/map/CcPermsTableMap.php | 56 - .../campcaster/map/CcPlaylistTableMap.php | 61 - .../map/CcPlaylistcontentsTableMap.php | 62 - .../classes/campcaster/map/CcPrefTableMap.php | 56 - .../campcaster/map/CcScheduleTableMap.php | 61 - .../classes/campcaster/map/CcSessTableMap.php | 55 - .../campcaster/map/CcSmembTableMap.php | 55 - .../campcaster/map/CcSubjsTableMap.php | 63 - .../campcaster/map/CcTransTableMap.php | 75 - .../classes/campcaster/om/BaseCcAccess.php | 1236 ------ .../campcaster/om/BaseCcAccessPeer.php | 1008 ----- .../campcaster/om/BaseCcAccessQuery.php | 477 -- .../classes/campcaster/om/BaseCcBackup.php | 956 ---- .../campcaster/om/BaseCcBackupPeer.php | 750 ---- .../campcaster/om/BaseCcBackupQuery.php | 292 -- .../classes/campcaster/om/BaseCcFiles.php | 3643 ---------------- .../classes/campcaster/om/BaseCcFilesPeer.php | 1236 ------ .../campcaster/om/BaseCcFilesQuery.php | 1733 -------- .../classes/campcaster/om/BaseCcPerms.php | 945 ---- .../classes/campcaster/om/BaseCcPermsPeer.php | 984 ----- .../campcaster/om/BaseCcPermsQuery.php | 355 -- .../classes/campcaster/om/BaseCcPlaylist.php | 1365 ------ .../campcaster/om/BaseCcPlaylistPeer.php | 1006 ----- .../campcaster/om/BaseCcPlaylistQuery.php | 510 --- .../campcaster/om/BaseCcPlaylistcontents.php | 1540 ------- .../om/BaseCcPlaylistcontentsPeer.php | 1395 ------ .../om/BaseCcPlaylistcontentsQuery.php | 581 --- .../classes/campcaster/om/BaseCcPref.php | 905 ---- .../classes/campcaster/om/BaseCcPrefPeer.php | 983 ----- .../classes/campcaster/om/BaseCcPrefQuery.php | 320 -- .../classes/campcaster/om/BaseCcSchedule.php | 1560 ------- .../campcaster/om/BaseCcSchedulePeer.php | 780 ---- .../campcaster/om/BaseCcScheduleQuery.php | 515 --- .../classes/campcaster/om/BaseCcSess.php | 949 ---- .../classes/campcaster/om/BaseCcSessPeer.php | 979 ----- .../classes/campcaster/om/BaseCcSessQuery.php | 334 -- .../classes/campcaster/om/BaseCcSmemb.php | 891 ---- .../classes/campcaster/om/BaseCcSmembPeer.php | 750 ---- .../campcaster/om/BaseCcSmembQuery.php | 305 -- .../classes/campcaster/om/BaseCcSubjs.php | 1969 --------- .../classes/campcaster/om/BaseCcSubjsPeer.php | 769 ---- .../campcaster/om/BaseCcSubjsQuery.php | 747 ---- .../classes/campcaster/om/BaseCcTrans.php | 1903 -------- .../classes/campcaster/om/BaseCcTransPeer.php | 849 ---- .../campcaster/om/BaseCcTransQuery.php | 826 ---- .../propel-db/build/conf/campcaster-conf.php | 20 - .../build/conf/classmap-campcaster-conf.php | 88 - backend/propel-db/build/sql/schema.sql | 388 -- backend/propel-db/build/sql/sequences.sql | 3 - backend/propel-db/build/sql/sqldb.map | 5 - backend/propel-db/build/sql/triggers.sql | 23 - backend/propel-db/build/sql/views.sql | 11 - backend/propel-db/runtime-conf.xml | 13 - backend/propel-db/schema.xml | 269 -- backend/propel-db/test.php | 14 - backend/tests/0000000000010001 | Bin 179013 -> 0 bytes backend/tests/0000000000010002 | Bin 194816 -> 0 bytes backend/tests/AllTests.php | 24 - backend/tests/PlaylistTests.php | 181 - backend/tests/SchedulerExportTests.php | 42 - backend/tests/SchedulerTests.php | 128 - backend/tests/StoredFileTests.php | 87 - backend/tests/analyze.php | 25 - backend/tests/ex1.mp3 | Bin 48611 -> 0 bytes backend/tests/ex2.ogg | Bin 5354 -> 0 bytes backend/tests/ex2.wav | Bin 19564 -> 0 bytes backend/tests/ex3.wav | Bin 19564 -> 0 bytes backend/tests/exportedPl_lspl.tar | Bin 573440 -> 0 bytes backend/tests/index.php | 4 - backend/tests/pdoTest.php | 22 - backend/tests/plistEmbedded.xml | 26 - backend/tests/pypoTester.php | 85 - backend/tests/question.wav | Bin 4189 -> 0 bytes backend/tests/test10001.mp3 | Bin 179802 -> 0 bytes backend/tests/test10002.mp3 | Bin 195589 -> 0 bytes backend/tests/test10003.mp3 | Bin 184830 -> 0 bytes backend/tests/transTest.php | 143 - backend/tests/webstreamTest.php | 62 - backend/tests/wstream1.xml | 14 - backend/webstreamFormat.php | 345 -- backend/xmlrpc/XR_LocStor.php | 3833 ----------------- backend/xmlrpc/index.php | 4 - backend/xmlrpc/put.php | 99 - backend/xmlrpc/schedulerPhpClient.php | 511 --- backend/xmlrpc/simpleGet.php | 128 - backend/xmlrpc/urldecode | 7 - backend/xmlrpc/xrLocStor.php | 172 - backend/xmlrpc/xr_cli_test.php | 368 -- backend/xmlrpc/xr_web_test.php | 373 -- utils/backup.sh | 18 - utils/createDatabase.sh | 211 - utils/dumpDbSchema.php | 9 - utils/dumpDbSchema.sh | 85 - utils/getStorPath.php | 6 - utils/getUrl.sh | 40 - utils/renderer.sh | 113 - utils/setupDirs.sh | 88 - 171 files changed, 63991 deletions(-) delete mode 100644 backend/.htaccess delete mode 100644 backend/AccessRecur.php delete mode 100644 backend/Alib.php delete mode 100755 backend/Backup.php delete mode 100644 backend/BasicStor.php delete mode 100644 backend/GreenBox.php delete mode 100644 backend/LocStor.php delete mode 100644 backend/M3uPlaylist.php delete mode 100644 backend/Playlist.php delete mode 100644 backend/Prefs.php delete mode 100644 backend/Renderer.php delete mode 100644 backend/Restore.php delete mode 100644 backend/Schedule.php delete mode 100644 backend/SmilPlaylist.php delete mode 100644 backend/StoredFile.php delete mode 100644 backend/Subjects.php delete mode 100644 backend/Transport.php delete mode 100644 backend/TransportRecord.php delete mode 100644 backend/Validator.php delete mode 100644 backend/XmlParser.php delete mode 100644 backend/audioClipFormat.php delete mode 100755 backend/configure delete mode 100755 backend/cron/Cron.php delete mode 100755 backend/cron/CronJob.php delete mode 100755 backend/cron/Crontab.php delete mode 100755 backend/cron/croncall.php delete mode 100755 backend/cron/transportCron.php delete mode 100755 backend/cron/transportCronJob.php delete mode 100644 backend/etc/Makefile.in delete mode 100644 backend/etc/configure.ac delete mode 100644 backend/genres.xml delete mode 100644 backend/index.php delete mode 100644 backend/playlistFormat.php delete mode 100644 backend/propel-db/build.properties delete mode 100644 backend/propel-db/build/classes/campcaster/CcAccess.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcAccessPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcAccessQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcBackup.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcBackupPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcBackupQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcFiles.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcFilesPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcFilesQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPerms.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPermsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPermsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylist.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylistPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylistQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylistcontents.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylistcontentsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPlaylistcontentsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPref.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPrefPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcPrefQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSchedule.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSchedulePeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcScheduleQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSess.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSessPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSessQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSmemb.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSmembPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSmembQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSubjs.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSubjsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcSubjsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcTrans.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcTransPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/CcTransQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/Common.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcAccessTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcBackupTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcFilesTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcPermsTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcPlaylistTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcPlaylistcontentsTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcPrefTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcScheduleTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcSessTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcSmembTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcSubjsTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/map/CcTransTableMap.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcAccess.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcAccessPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcAccessQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcBackup.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcBackupPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcBackupQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcFiles.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcFilesPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcFilesQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPerms.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPermsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPermsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylist.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontents.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPref.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPrefPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcPrefQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSchedule.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSchedulePeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcScheduleQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSess.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSessPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSessQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSmemb.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSmembPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSmembQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSubjs.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSubjsPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcSubjsQuery.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcTrans.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcTransPeer.php delete mode 100644 backend/propel-db/build/classes/campcaster/om/BaseCcTransQuery.php delete mode 100644 backend/propel-db/build/conf/campcaster-conf.php delete mode 100644 backend/propel-db/build/conf/classmap-campcaster-conf.php delete mode 100644 backend/propel-db/build/sql/schema.sql delete mode 100644 backend/propel-db/build/sql/sequences.sql delete mode 100644 backend/propel-db/build/sql/sqldb.map delete mode 100644 backend/propel-db/build/sql/triggers.sql delete mode 100644 backend/propel-db/build/sql/views.sql delete mode 100644 backend/propel-db/runtime-conf.xml delete mode 100644 backend/propel-db/schema.xml delete mode 100644 backend/propel-db/test.php delete mode 100644 backend/tests/0000000000010001 delete mode 100644 backend/tests/0000000000010002 delete mode 100644 backend/tests/AllTests.php delete mode 100644 backend/tests/PlaylistTests.php delete mode 100644 backend/tests/SchedulerExportTests.php delete mode 100644 backend/tests/SchedulerTests.php delete mode 100644 backend/tests/StoredFileTests.php delete mode 100755 backend/tests/analyze.php delete mode 100644 backend/tests/ex1.mp3 delete mode 100644 backend/tests/ex2.ogg delete mode 100644 backend/tests/ex2.wav delete mode 100644 backend/tests/ex3.wav delete mode 100644 backend/tests/exportedPl_lspl.tar delete mode 100644 backend/tests/index.php delete mode 100644 backend/tests/pdoTest.php delete mode 100644 backend/tests/plistEmbedded.xml delete mode 100644 backend/tests/pypoTester.php delete mode 100644 backend/tests/question.wav delete mode 100644 backend/tests/test10001.mp3 delete mode 100644 backend/tests/test10002.mp3 delete mode 100644 backend/tests/test10003.mp3 delete mode 100644 backend/tests/transTest.php delete mode 100644 backend/tests/webstreamTest.php delete mode 100644 backend/tests/wstream1.xml delete mode 100644 backend/webstreamFormat.php delete mode 100644 backend/xmlrpc/XR_LocStor.php delete mode 100644 backend/xmlrpc/index.php delete mode 100644 backend/xmlrpc/put.php delete mode 100644 backend/xmlrpc/schedulerPhpClient.php delete mode 100644 backend/xmlrpc/simpleGet.php delete mode 100755 backend/xmlrpc/urldecode delete mode 100644 backend/xmlrpc/xrLocStor.php delete mode 100644 backend/xmlrpc/xr_cli_test.php delete mode 100644 backend/xmlrpc/xr_web_test.php delete mode 100755 utils/backup.sh delete mode 100755 utils/createDatabase.sh delete mode 100644 utils/dumpDbSchema.php delete mode 100755 utils/dumpDbSchema.sh delete mode 100644 utils/getStorPath.php delete mode 100755 utils/getUrl.sh delete mode 100755 utils/renderer.sh delete mode 100755 utils/setupDirs.sh diff --git a/backend/.htaccess b/backend/.htaccess deleted file mode 100644 index ba3404cb8..000000000 --- a/backend/.htaccess +++ /dev/null @@ -1,12 +0,0 @@ -DirectoryIndex index.php -Options +FollowSymLinks -Indexes - - - - AddType application/x-httpd-php .php - - php_flag magic_quotes_gpc On - php_flag register_globals Off - - - diff --git a/backend/AccessRecur.php b/backend/AccessRecur.php deleted file mode 100644 index ae78c8807..000000000 --- a/backend/AccessRecur.php +++ /dev/null @@ -1,184 +0,0 @@ -ls =& $ls; - $this->sessid = $sessid; - } - - - public static function accessPlaylist(&$ls, $sessid, $plid, $parent='0') - { - $ppa = new AccessRecur($ls, $sessid); - $r = $ls->accessPlaylist($sessid, $plid, FALSE, $parent); - if (PEAR::isError($r)) { - return $r; - } - $plRes = $r; - $r = StoredFile::RecallByGunid($plid); - if (is_null($r) || PEAR::isError($r)) { - return $r; - } - $ac = $r; - $r = $ac->md->genPhpArray(); - if (PEAR::isError($r)) { - return $r; - } - $pla = $r; - $r = $ppa->processPlaylist($pla, $plRes['token']); - if (PEAR::isError($r)) { - return $r; - } - $plRes['content'] = $r; - return $plRes; - } - - - public static function releasePlaylist(&$ls, $sessid, $token) - { - global $CC_CONFIG, $CC_DBC; - $ppa = new AccessRecur($ls, $sessid); - $r = $CC_DBC->getAll(" - SELECT to_hex(token)as token2, to_hex(gunid)as gunid - FROM ".$CC_CONFIG['accessTable']." - WHERE parent=x'{$token}'::bigint - "); - if (PEAR::isError($r)) { - return $r; - } - $arr = $r; - foreach ($arr as $i => $item) { - extract($item); // token2, gunid - $r = BasicStor::GetType($gunid); - if (PEAR::isError($r)) { - return $r; - } - $ftype = $r; - # echo "$ftype/$token2\n"; - switch (strtolower($ftype)) { - case "audioclip": - $r = $ppa->ls->releaseRawAudioData($ppa->sessid, $token2); - if (PEAR::isError($r)) { - return $r; - } - # var_dump($r); - break; - case "playlist": - $r = $ppa->releasePlaylist($ppa->ls, $ppa->sessid, $token2); - if (PEAR::isError($r)) { - return $r; - } - # var_dump($r); - break; - default: - } - } - $r = $ppa->ls->releasePlaylist($ppa->sessid, $token, FALSE); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - private function processPlaylist($pla, $parent) - { - $res = array(); - foreach ($pla['children'] as $ple) { - switch ($ple['elementname']) { - case "playlistElement": - $r = $this->processPlaylistElement($ple, $parent); - if (PEAR::isError($r)) { - return $r; - } - // $res = array_merge($res, $r); - $res[] = $r; - break; - default: - } - } - return $res; - } - - - private function processAudioClip($gunid, $parent) - { - $r = $this->ls->accessRawAudioData($this->sessid, $gunid, $parent); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - private function processPlaylistElement($ple, $parent='0') - { - foreach ($ple['children'] as $ac) { - switch ($ac['elementname']) { - case "audioClip": - $r = $this->processAudioClip($ac['attrs']['id'], $parent); - if (PEAR::isError($r)) { - return $r; - } - return $r; - case "playlist": - // if(empty($ac['children'])){ - $r = $this->accessPlaylist($this->ls, $this->sessid, - $ac['attrs']['id'], $parent); - if (PEAR::isError($r)) { - if ($r->getCode() != GBERR_NOTF) { - return $r; - } else { - $r = $this->processPlaylist($ac, $parent); - if (PEAR::isError($r)) { - return $r; - } - $r = array( - 'content' => $r, - 'url' => NULL, - 'token' => NULL, - 'chsum' => NULL, - 'size' => NULL, - 'warning' => 'inline playlist?', - ); - } - } - return $r; - /* - }else{ - $r = $this->processPlaylist($ac, $parent); - if(PEAR::isError($r)) return $r; - $res = array( - 'content' => $r, - 'url' => NULL, - 'token' => NULL, - 'chsum' => NULL, - 'size' => NULL, - 'warning' => 'inline playlist', - ); - return $res; - } - */ - break; - default: - } - } - return array(); - } - -} // class AccessRecur -?> \ No newline at end of file diff --git a/backend/Alib.php b/backend/Alib.php deleted file mode 100644 index b9e16d6ca..000000000 --- a/backend/Alib.php +++ /dev/null @@ -1,622 +0,0 @@ -query($sql); - if (PEAR::isError($r)) { - return $r; - } - Subjects::SetTimeStamp($login, FALSE); - return $sessid; - } // fn login - - - /** - * Logout and destroy session - * - * @param string $sessid - * @return true|PEAR_Error - */ - public static function Logout($sessid) - { - global $CC_CONFIG, $CC_DBC; - $ct = Alib::CheckAuthToken($sessid); - if ($ct === FALSE) { - return PEAR::raiseError("Alib::logout: not logged ($sessid)", - ALIBERR_NOTLOGGED, PEAR_ERROR_RETURN); - } elseif (PEAR::isError($ct)) { - return $ct; - } else { - $sql = "DELETE FROM ".$CC_CONFIG['sessTable'] - ." WHERE sessid='$sessid'"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - } // fn logout - - - /** - * Return true if the token is valid - * - * @param string $sessid - * @return boolean|PEAR_Error - */ - private static function CheckAuthToken($sessid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT count(*) as cnt FROM ".$CC_CONFIG['sessTable'] - ." WHERE sessid='$sessid'"; - $c = $CC_DBC->getOne($sql); - return ($c == 1 ? TRUE : (PEAR::isError($c) ? $c : FALSE )); - } //fn checkAuthToken - - - /** - * Set valid token in alib object - * - * @param string $sessid - * @return TRUE|PEAR_Error - */ - // public function setAuthToken($sessid) - // { - // $r = $this->checkAuthToken($sessid); - // if (PEAR::isError($r)) { - // return $r; - // } - // if (!$r) { - // return PEAR::raiseError("ALib::setAuthToken: invalid token ($sessid)"); - // } - // //$this->sessid = $sessid; - // return TRUE; - // } // fn setAuthToken - - - /* -------------------------------------------------------- authorization */ - /** - * Insert permission record - * - * @param int $sid - * local user/group id - * @param string $action - * @param int $oid - * local object id - * @param string $type - * 'A'|'D' (allow/deny) - * @return int - * local permission id - */ - public static function AddPerm($sid, $action, $oid, $type='A') - { - global $CC_CONFIG, $CC_DBC; - $permid = $CC_DBC->nextId($CC_CONFIG['permSequence']); - $sql = "INSERT INTO ".$CC_CONFIG['permTable']." (permid, subj, action, obj, type)" - ." VALUES ($permid, $sid, '$action', $oid, '$type')"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return($r); - } - return $permid; - } // fn addPerm - - - /** - * Remove permission record - * - * @param int $permid - * local permission id - * @param int $subj - * local user/group id - * @param int $obj - * local object id - * @return boolean|PEAR_Error - */ - public static function RemovePerm($permid=NULL, $subj=NULL, $obj=NULL) - { - global $CC_CONFIG, $CC_DBC; - $ca = array(); - if ($permid) { - $ca[] = "permid=$permid"; - } - if ($subj) { - $ca[] = "subj=$subj"; - } - if ($obj) { - $ca[] = "obj=$obj"; - } - $cond = join(" AND ", $ca); - if (!$cond) { - return TRUE; - } - $sql = "DELETE FROM ".$CC_CONFIG['permTable']." WHERE $cond"; - return $CC_DBC->query($sql); - } // fn removePerm - - - /** - * Return object related with permission record - * - * @param int $permid - * local permission id - * @return int - * local object id - */ - public static function GetPermOid($permid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT obj FROM ".$CC_CONFIG['permTable']." WHERE permid=$permid"; - $res = $CC_DBC->getOne($sql); - return $res; - } // fn GetPermOid - - - /** - * Check if specified subject have permission to specified action - * on specified object - * - * Look for sequence of corresponding permissions and order it by - * relevence, then test the most relevant for result. - * High relevence have direct permission (directly for specified subject - * and object. Relevance order is done by level distance in the object - * tree, level distance in subjects (user/group system). - * Similar way is used for permissions related to object classes. - * But class-related permissions have lower priority then - * object-tree-related. - * Support for object classes can be disabled by USE_ALIB_CLASSES const. - * - * @param int $sid - * subject id (user or group id) - * @param string $action - * from set defined in config - * @param int $oid - * object id (default: root node) - * @return boolean|PEAR_Error - */ - public static function CheckPerm($sid, $action, $oid=NULL) - { - return TRUE; - // global $CC_DBC; - // global $CC_CONFIG; - // if (!is_numeric($sid)) { - // return FALSE; - // } - //// if (is_null($oid) or $oid=='') { - //// $oid = M2tree::GetRootNode(); - //// } - //// if (PEAR::isError($oid)) { - //// return $oid; - //// } - // if (!is_numeric($oid)) { - // return FALSE; - // } - // // query construction - // // shortcuts: - // // p: permTable, - // // s: subjTable, m smembTable, - // // t: treeTable ts: structTable, - // // c: classTable, cm: cmembTable - // // main query elements: - // $q_flds = "m.level , p.subj, s.login, action, p.type, p.obj"; - // $q_from = $CC_CONFIG['permTable']." p "; - // // joins for solving users/groups: - // $q_join = "LEFT JOIN ".$CC_CONFIG['subjTable']." s ON s.id=p.subj "; - // $q_join .= "LEFT JOIN ".$CC_CONFIG['smembTable']." m ON m.gid=p.subj "; - // $q_cond = "p.action in('_all', '$action') AND - // (s.id=$sid OR m.uid=$sid) "; - // // coalesce -1 for higher priority of nongroup rows: - // // action DESC order for lower priority of '_all': - // $q_ordb = "ORDER BY coalesce(m.level,-1), action DESC, p.type DESC"; - // $q_flds0 = $q_flds; - // $q_from0 = $q_from; - // $q_join0 = $q_join; - // $q_cond0 = $q_cond; - // $q_ordb0 = $q_ordb; - // // joins for solving object tree: - // $q_flds .= ", t.name, ts.level as tlevel"; - // //$q_join .= "LEFT JOIN ".$CC_CONFIG['treeTable']." t ON t.id=p.obj "; - // //$q_join .= "LEFT JOIN ".$CC_CONFIG['structTable']." ts ON ts.parid=p.obj "; - // //$q_cond .= " AND (t.id=$oid OR ts.objid=$oid)"; - // // action DESC order is hack for lower priority of '_all': - // $q_ordb = "ORDER BY coalesce(ts.level,0), m.level, action DESC, p.type DESC"; - // // query by tree: - // $query1 = "SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb"; - // $r1 = $CC_DBC->getAll($query1); - // if (PEAR::isError($r1)) { - // return($r1); - // } - // // if there is row with type='A' on the top => permit - // //$AllowedByTree = - // // (is_array($r1) && count($r1)>0 && $r1[0]['type']=='A'); - // //$DeniedByTree = - // // (is_array($r1) && count($r1)>0 && $r1[0]['type']=='D'); - // - // if (!USE_ALIB_CLASSES) { - // return $AllowedbyTree; - // } - // - // // joins for solving object classes: - // $q_flds = $q_flds0.", c.cname "; - // $q_join = $q_join0."LEFT JOIN ".$CC_CONFIG['classTable']." c ON c.id=p.obj "; - // $q_join .= "LEFT JOIN ".$CC_CONFIG['cmembTable']." cm ON cm.cid=p.obj "; - // $q_cond = $q_cond0." AND (c.id=$oid OR cm.objid=$oid)"; - // $q_ordb = $q_ordb0; - // // query by class: - // $query2 = "SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb"; - // $r2 = $CC_DBC->getAll($query2); - // if (PEAR::isError($r2)) { - // return $r2; - // } - // $AllowedByClass = - // (is_array($r2) && count($r2)>0 && $r2[0]['type']=='A'); - // // not used now: - // // $DeniedByClass = - // // (is_array($r2) && count($r2)>0 && $r2[0]['type']=='D'); - // $res = ($AllowedByTree || (!$DeniedByTree && $AllowedByClass)); - // return $res; - } // fn CheckPerm - - - /* ---------------------------------------------------------- object tree */ - - /** - * Remove all permissions on object and then remove object itself - * - * @param int $id - * @return void|PEAR_Error - */ - public static function RemoveObj($id) - { - $r = Alib::RemovePerm(NULL, NULL, $id); - return $r; - } // fn removeObj - - /* --------------------------------------------------------- users/groups */ - - /** - * Remove all permissions of subject and then remove subject itself - * - * @param string $login - * @return void|PEAR_Error - */ - public static function RemoveSubj($login) - { - global $CC_CONFIG, $CC_DBC; - $uid = Subjects::GetSubjId($login); - if (PEAR::isError($uid)) { - return $uid; - } - if (is_null($uid)){ - return $CC_DBC->raiseError("Alib::removeSubj: Subj not found ($login)", - ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN); - } - $r = Alib::RemovePerm(NULL, $uid); - if (PEAR::isError($r)) { - return $r; - } - return Subjects::RemoveSubj($login, $uid); - } // fn RemoveSubj - - - /* ------------------------------------------------------------- sessions */ - /** - * Get login from session id (token) - * - * @param string $sessid - * @return string|PEAR_Error - */ - public static function GetSessLogin($sessid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT login FROM ".$CC_CONFIG['sessTable']." WHERE sessid='$sessid'"; - $r = $CC_DBC->getOne($sql); - if (PEAR::isError($r)) { - return $r; - } - if (is_null($r)){ - return PEAR::raiseError("Alib::GetSessLogin:". - " invalid session id ($sessid)", - ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN); - } - return $r; - } // fn GetSessLogin - - - /** - * Get user id from session id. - * - * @param string $p_sessid - * @return int|PEAR_Error - */ - public static function GetSessUserId($p_sessid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT userid FROM ".$CC_CONFIG['sessTable']." WHERE sessid='$p_sessid'"; - $r = $CC_DBC->getOne($sql); - if (PEAR::isError($r)) { - return $r; - } - if (is_null($r)) { - return PEAR::raiseError("Alib::getSessUserId:". - " invalid session id ($p_sessid)", - ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN); - } - return $r; - } // fn getSessUserId - - - /* --------------------------------------------------------- info methods */ - /** - * Get all permissions on object. - * - * @param int $id - * @return array|null|PEAR_Error - */ - public static function GetObjPerms($id) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT s.login, p.* FROM ".$CC_CONFIG['permTable']." p, ".$CC_CONFIG['subjTable']." s" - ." WHERE s.id=p.subj AND p.obj=$id"; - return $CC_DBC->getAll($sql); - } // fn GetObjPerms - - - /** - * Get all permissions of subject. - * - * @param int $sid - * @return array - */ - public static function GetSubjPerms($sid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT *" - ." FROM ".$CC_CONFIG['permTable'] - ." WHERE p.subj=$sid"; - // $sql = "SELECT t.name, t.type as otype , p.*" - // ." FROM ".$CC_CONFIG['permTable']." p, ".$CC_CONFIG['treeTable']." t" - // ." WHERE t.id=p.obj AND p.subj=$sid"; - $a1 = $CC_DBC->getAll($sql); - return $a1; - } // fn GetSubjPerms - - - /* ------------------------ info methods related to application structure */ - /* (this part should be added/rewritten to allow defining/modifying/using - * application structure) - * (only very simple structure definition - in $CC_CONFIG - supported now) - */ - - /** - * Get all actions - * - * @return array - */ - public static function GetAllActions() - { - global $CC_CONFIG; - return $CC_CONFIG['allActions']; - } // fn GetAllActions - - - /** - * Get all allowed actions on specified object type. - * - * @param string $type - * @return array - */ - public static function GetAllowedActions($type) - { - global $CC_CONFIG; - return $CC_CONFIG['allowedActions'][$type]; - } // fn GetAllowedActions - - - /* ====================================================== private methods */ - - /** - * Create new session id. Return the new session ID. - * - * @return string - */ - private static function _createSessid() - { - global $CC_CONFIG, $CC_DBC; - for ($c = 1; $c > 0; ){ - $sessid = md5(uniqid(rand())); - $sql = "SELECT count(*) FROM ".$CC_CONFIG['sessTable'] - ." WHERE sessid='$sessid'"; - $c = $CC_DBC->getOne($sql); - if (PEAR::isError($c)) { - return $c; - } - } - return $sessid; - } // fn _createSessid - - - /* =============================================== test and debug methods */ - - /** - * Dump all permissions for debug - * - * @param string $indstr - * indentation string - * @param string $ind - * actual indentation - * @return string - */ - public static function DumpPerms($indstr=' ', $ind='') - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT s.login, p.action, p.type" - ." FROM ".$CC_CONFIG['permTable']." p, ".$CC_CONFIG['subjTable']." s" - ." WHERE s.id=p.subj" - ." ORDER BY p.permid"; - $arr = $CC_DBC->getAll($sql); - if (PEAR::isError($arr)) { - return $arr; - } - $r = $ind.join(', ', array_map(create_function('$v', - 'return "{$v[\'login\']}/{$v[\'action\']}/{$v[\'type\']}";' - ), - $arr - ))."\n"; - return $r; - } // fn dumpPerms - - - /** - * Delete everything form the permission table and session table. - * - * @return void - */ - public static function DeleteData() - { - global $CC_CONFIG, $CC_DBC; - $CC_DBC->query("DELETE FROM ".$CC_CONFIG['permTable']); - $CC_DBC->query("DELETE FROM ".$CC_CONFIG['sessTable']); - Subjects::DeleteData(); - } // fn deleteData - - - /** - * Insert test permissions - * - * @return array - */ - public static function TestData() - { - global $CC_CONFIG, $CC_DBC; - $tdata = Subjects::TestData(); - $t =& $tdata['tree']; - $c =& $tdata['classes']; - $s =& $tdata['subjects']; - $CC_DBC->setErrorHandling(PEAR_ERROR_PRINT); - $perms = array( - array($s['root'], '_all', $t['root'], 'A'), - array($s['test1'], '_all', $t['pa'], 'A'), - array($s['test1'], 'read', $t['s2b'], 'D'), - array($s['test2'], 'addChilds', $t['pa'], 'D'), - array($s['test2'], 'read', $t['i2'], 'A'), - array($s['test2'], 'edit', $t['s1a'], 'A'), - array($s['test1'], 'addChilds', $t['s2a'], 'D'), - array($s['test1'], 'addChilds', $t['s2c'], 'D'), - array($s['gr2'], 'addChilds', $t['i2'], 'A'), - array($s['test3'], '_all', $t['t1'], 'D'), - ); - if (USE_ALIB_CLASSES){ - $perms[] = array($s['test3'], 'read', $c['cl_sa'], 'D'); - $perms[] = array($s['test4'], 'editPerms', $c['cl2'], 'A'); - } - foreach ($perms as $p){ - $o[] = $r = Alib::AddPerm($p[0], $p[1], $p[2], $p[3]); - if (PEAR::isError($r)) { - return $r; - } - } - $tdata['perms'] = $o; - return $tdata; - } // fn testData - - - /** - * Make basic test - * - * @return boolean|PEAR_Error - */ - public static function Test() - { - $p = Subjects::test(); - if (PEAR::isError($p)) { - return $p; - } - Alib::DeleteData(); - $tdata = Alib::TestData(); - if (PEAR::isError($tdata)) { - return $tdata; - } - $test_correct = "root/_all/A, test1/_all/A, test1/read/D,". - " test2/addChilds/D, test2/read/A, test2/edit/A,". - " test1/addChilds/D, test1/addChilds/D, gr2/addChilds/A,". - " test3/_all/D"; - if (USE_ALIB_CLASSES){ - $test_correct .= ", test3/read/D, test4/editPerms/A"; - } - $test_correct .= "\nno, yes\n"; - $r = Alib::DumpPerms(); - if (PEAR::isError($r)) { - return $r; - } - $test_dump = $r. - (Alib::CheckPerm( - $tdata['subjects']['test1'], 'read', - $tdata['tree']['t1'] - )? 'yes':'no').", ". - (Alib::CheckPerm( - $tdata['subjects']['test1'], 'addChilds', - $tdata['tree']['i2'] - )? 'yes':'no')."\n" - ; - Alib::RemovePerm($tdata['perms'][1]); - Alib::RemovePerm($tdata['perms'][3]); - $test_correct .= "root/_all/A, test1/read/D,". - " test2/read/A, test2/edit/A,". - " test1/addChilds/D, test1/addChilds/D, gr2/addChilds/A,". - " test3/_all/D"; - if (USE_ALIB_CLASSES) { - $test_correct .= ", test3/read/D, test4/editPerms/A"; - } - $test_correct .= "\n"; - $test_dump .= Alib::DumpPerms(); - Alib::DeleteData(); - if ($test_dump == $test_correct) { - $test_log .= "alib: OK\n"; - return TRUE; - } else { - return PEAR::raiseError('Alib::test', 1, PEAR_ERROR_DIE, '%s'. - "
\ncorrect:\n{$test_correct}\n".
-                "dump:\n{$test_dump}\n
\n"); - } - } // fn test - -} // class Alib -?> \ No newline at end of file diff --git a/backend/Backup.php b/backend/Backup.php deleted file mode 100755 index c05500264..000000000 --- a/backend/Backup.php +++ /dev/null @@ -1,487 +0,0 @@ -gb =& $gb; - $this->token = null; - $this->logFile = $CC_CONFIG['bufferDir'].'/'.ACCESS_TYPE.'.log'; - $this->addLogItem("-I- ".date("Ymd-H:i:s")." construct\n"); - } - - - /** - * Open a backup - * Create a backup file (tarball) - * - * @param string $sessid - * @param array $criteria - * struct - see search criteria - * @return array - * hasharray with field: - * token string: backup token - */ - public function openBackup($sessid, $criteria='') - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." openBackup - sessid:$sessid\n"); - } - $this->sessid = $sessid; - $this->criteria = $criteria; - - // get ids (and real filenames) which files match with criteria - $srch = $this->gb->localSearch($this->criteria,$this->sessid); - if (PEAR::isError($srch)) { - return $srch; - } - $this->setIDs($srch); - - // get real filenames - if (is_array($this->ids)) { - $this->setFilenames(); - - $this->setEnviroment(true); - - // write a status file - file_put_contents($this->statusFile, 'working'); - - // save the metafile to tmpdir - $hostname = trim(`hostname`); - $ctime = time(); - $ctime_f = date("Ymd-H:i:s"); - file_put_contents("{$this->tmpDirMeta}/storage.xml", - "\n". - "\n" - ); - - // copy all file to tmpdir - $this->copyAllFiles(); - - // do everything - $this->doIt(); - - return array('token'=>$this->token); - } else { - return false; - } - } - - - /** - * Check the status of backup. - * - * @param unknown $token - * @return array - * status : string - susccess | working | fault - * faultString: string - description of fault - * token : stirng - backup token - * url : string - access url - * tmpfile : string - access filename - */ - public function checkBackup($token) - { - global $CC_CONFIG; - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n"); - } - $this->token = $token; - $this->setEnviroment(); - $status = file_get_contents($this->statusFile); - if (strpos($status,'fault')!==false) { - list($status,$faultString) = explode('|',$status); - } - switch ($status) { - case 'success': - $r['url'] = BasicStor::GetUrlPart()."access/$token.".BACKUP_EXT; - $r['tmpfile'] = $CC_CONFIG['accessDir']."/$token.".BACKUP_EXT; - case 'working': - case 'fault': - $r['status'] = $status; - $r['faultString'] = $faultString; - $r['token'] = $token; - break; - } - return $r; - } - - - /** - * Close a backup - * - * @param unknown $token - * @return boolean - */ - public function closeBackup($token) - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." closeBackup - token:$token\n"); - } - # post procedures - $this->token = $token; - $this->setEnviroment(); - BasicStor::bsRelease($token, ACCESS_TYPE); - Backup::rRmDir($this->tmpDir); - unlink($this->statusFile); - unlink($this->tmpFile); - if (is_file($this->tmpName)) { - unlink($this->tmpName); - } - return !is_file($this->tmpFile); - } - - - /** - * list of unclosed backups - * - * @param string $stat - * if this parameter is not set, then return with all unclosed backups - * @return array of hasharray with field: - * status : string - susccess | working | fault - * token : stirng - backup token - * url : string - access url - */ - public function listBackups($stat='') - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." listBackups - stat:$stat\n"); - } - // open temporary dir - $tokens = BasicStor::GetTokensByType(ACCESS_TYPE); - // echo 'tokens:'; print_r($tokens); echo ''; - foreach ($tokens as $token) { - $st = $this->checkBackup($token); - if ($stat=='' || $st['status']==$stat) { - $r[] = $st; - } - } - return $r; - } - - - /** - * Set the ids from searchResult - * - * @param array $searchResult : array of gunids - */ - private function setIDs($searchResult) - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." setIDs\n"); - } - if (is_array($searchResult['results'])) { - $this->ids = $searchResult['results']; - } else { - $this->addLogItem("-E- ".date("Ymd-H:i:s")." setIDs - the parameter is not array!\n"); - return PEAR::raiseError('The IDs variable isn\'t array.'); - } - } - - - /** - * Set the filenames from ids. - * - */ - private function setFilenames() - { - // if ($this->loglevel=='debug') { - // $this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames\n"); - // } - // if (is_array($this->ids)) { - // foreach ($this->ids as $i => $item) { - // $gunid = $item['gunid']; - // // get a stored file object of this gunid - // $sf = StoredFile::RecallByGunid($gunid); - // if (is_null($sf) || PEAR::isError($sf)) { - // return $sf; - // } - // $lid = BasicStor::IdFromGunid($gunid); - // if (($res = BasicStor::Authorize('read', $lid, $this->sessid)) !== TRUE) { - // $this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - authorize gunid:$gunid\n"); - // return PEAR::raiseError('Backup::setFilenames : Authorize ... error.'); - // } - // // if the file is a playlist then it has only a meta file - // if (strtolower($sf->md->format) != 'playlist') { - // $this->filenames[] = array( - // 'filename' => $sf->getRealFileName(), - // 'format' => $sf->md->format - // ); - // } - // $this->filenames[] = array( - // 'filename' => $sf->getRealMetadataFileName(), - // 'format' => $sf->md->format - // ); - // if ($this->loglevel=='debug') { - // $this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames - add file: {$sf->md->format}|".$sf->getRealMetadataFileName()."\n"); - // } - // } - // return $this->filenames; - // } else { - // $this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - The IDs variable isn't array.\n"); - // return PEAR::raiseError('Backup::setFilenames : The IDs variable isn\'t array.'); - // } - } - - - /** - * Create the tarball - call the shell script - * - */ - private function doIt() - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt\n"); - } - $command = dirname(__FILe__)."/../bin/backup.sh" - ." {$this->tmpDir}" - ." {$this->tmpFile}" - ." {$this->statusFile}" - ." >> {$this->logFile} &"; - $res = system("$command"); - sleep(2); - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt - command:$command\n"); - } - } - - - /** - * Copy the real files into the tmp dirs to tar they. - * - */ - private function copyAllFiles() - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." copyAllFiles\n"); - } - //echo 'this->filenames:'; print_r($this->filenames); echo ''; - if (is_array($this->filenames)) { - foreach ($this->filenames as $v) { - # get the filename from full path - $fn = substr($v['filename'],strrpos($v['filename'],'/')); - switch (strtolower($v['format'])) { - case 'playlist': - # if playlist then copy to the playlist dir - copy($v['filename'],$this->tmpDirPlaylist.$fn); - break; - case 'audioclip': - # if audioclip then copy to the audioclip dir - copy($v['filename'],$this->tmpDirClip.$fn); - break; - } - } - } - } - - - /** - * Figure out the enviroment to the backup - * - */ - private function setEnviroment($createDir=false) - { - global $CC_CONFIG; - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." setEnviroment - createDirs:$createDir\n"); - } - // create temporary directories - if (is_null($this->token) && $createDir) { - $this->tmpName = tempnam($CC_CONFIG['bufferDir'], ACCESS_TYPE.'_'); - $this->tmpFile = $this->tmpName.'.'.BACKUP_EXT; - $this->tmpDir = $this->tmpName.'.dir'; - $this->tmpDirPlaylist = $this->tmpDir. '/playlist'; - $this->tmpDirClip = $this->tmpDir. '/audioClip'; - $this->tmpDirMeta = $this->tmpDir. '/meta-inf'; - touch($this->tmpFile); - mkdir($this->tmpDir); - mkdir($this->tmpDirPlaylist); - mkdir($this->tmpDirClip); - mkdir($this->tmpDirMeta); - $this->genToken(); - } else { - $symlink = $CC_CONFIG['accessDir'].'/'.$this->token.'.'.BACKUP_EXT; - if (is_link($symlink) && is_file(readlink($symlink))) { - $this->tmpName = str_replace('.tar','',readlink($symlink)); - $this->tmpFile = $this->tmpName.'.'.BACKUP_EXT; - $this->tmpDir = $this->tmpName.'.dir'; - $this->tmpDirPlaylist = $this->tmpDir. '/playlist'; - $this->tmpDirClip = $this->tmpDir. '/audioClip'; - $this->tmpDirMeta = $this->tmpDir. '/meta-inf'; - } else { - $this->addLogItem("-E- ".date("Ymd-H:i:s")." setEnviroment - Corrupt symbolic link.\n"); - return false; - } - } - $this->statusFile = $CC_CONFIG['accessDir'].'/'.$this->token.'.'.BACKUP_EXT.'.status'; - if ($this->loglevel=='debug') { - $this->addLogItem("this->tmpName: $this->tmpName\n"); - $this->addLogItem("this->tmpFile: $this->tmpFile\n"); - $this->addLogItem("this->tmpDir: $this->tmpDir\n"); - $this->addLogItem("this->tmpDirPlaylist: $this->tmpDirPlaylist\n"); - $this->addLogItem("this->tmpDirClip: $this->tmpDirClip\n"); - $this->addLogItem("this->tmpDirMeta: $this->tmpDirMeta\n"); - $this->addLogItem("this->token: $this->token\n"); - $this->addLogItem("this->statusFile: $this->statusFile\n"); - } - } - - - /** - * Generate a new token. - * @return void - */ - private function genToken() - { - $acc = BasicStor::bsAccess($this->tmpFile, BACKUP_EXT, null, ACCESS_TYPE); - if (PEAR::isError($acc)) { - return $acc; - } - $this->token = $acc['token']; - } - - - /** - * Add a line to the logfile. - * - * @param string $item - * the new row of log file - */ - private function addLogItem($item) - { - $f = fopen($this->logFile,'a'); - fwrite($f,$item); - fclose($f); - } - - - /** - * Delete a directory recursive - * - * @param string $dirname - * path of dir. - */ - private static function rRmDir($dirname) - { - if (is_dir($dirname)) { - $dir_handle = opendir($dirname); - } - while ($file = readdir($dir_handle)) { - if ( ($file != ".") && ($file != "..") ) { - if (!is_dir($dirname."/".$file)) { - unlink ($dirname."/".$file); - } else { - Backup::rRmDir($dirname."/".$file); - } - } - } - closedir($dir_handle); - rmdir($dirname); - return true; - } - -} // classs Backup -?> diff --git a/backend/BasicStor.php b/backend/BasicStor.php deleted file mode 100644 index ed517eabd..000000000 --- a/backend/BasicStor.php +++ /dev/null @@ -1,2186 +0,0 @@ - - * - *

- * Format of search/browse results: hash, with following structure:
- *

- * - */ -define('GBERR_DENY', 40); -define('GBERR_FILEIO', 41); -define('GBERR_FILENEX', 42); -define('GBERR_FOBJNEX', 43); -define('GBERR_WRTYPE', 44); -define('GBERR_NONE', 45); -define('GBERR_AOBJNEX', 46); -define('GBERR_NOTF', 47); -define('GBERR_SESS', 48); -define('GBERR_PREF', 49); -define('GBERR_TOKEN', 50); -define('GBERR_PUT', 51); -define('GBERR_LOCK', 52); -define('GBERR_GUNID', 53); -define('GBERR_BGERR', 54); -define('GBERR_NOTIMPL', 69); - -require_once(dirname(__FILE__)."/Alib.php"); -require_once(dirname(__FILE__)."/StoredFile.php"); -require_once(dirname(__FILE__)."/Transport.php"); -require_once(dirname(__FILE__)."/Playlist.php"); - -//$g_metadata_xml_to_db_mapping = array( -// "dc:format" => "format", -// "ls:bitrate" => "bit_rate", -// "ls:samplerate" => "sample_rate", -// "dcterms:extent" => "length", -// "dc:title" => "track_title", -// "dc:description" => "comments", -// "dc:type" => "genre", -// "dc:creator" => "artist_name", -// "dc:source" => "album_title", -// "ls:channels" => "channels", -// "ls:filename" => "name", -// "ls:year" => "year", -// "ls:url" => "url", -// "ls:track_num" => "track_number", -// "ls:mood" => "mood", -// "ls:bpm" => "bpm", -// "ls:disc_num" => "disc_number", -// "ls:rating" => "rating", -// "ls:encoded_by" => "encoded_by", -// "dc:publisher" => "label", -// "ls:composer" => "composer", -// "ls:encoder" => "encoder", -// "ls:crc" => "checksum", -// "ls:lyrics" => "lyrics", -// "ls:orchestra" => "orchestra", -// "ls:conductor" => "conductor", -// "ls:lyricist" => "lyricist", -// "ls:originallyricist" => "original_lyricist", -// "ls:radiostationname" => "radio_station_name", -// "ls:audiofileinfourl" => "info_url", -// "ls:artisturl" => "artist_url", -// "ls:audiosourceurl" => "audio_source_url", -// "ls:radiostationurl" => "radio_station_url", -// "ls:buycdurl" => "buy_this_url", -// "ls:isrcnumber" => "isrc_number", -// "ls:catalognumber" => "catalog_number", -// "ls:originalartist" => "original_artist", -// "dc:rights" => "copyright", -// "dcterms:temporal" => "report_datetime", -// "dcterms:spatial" => "report_location", -// "dcterms:entity" => "report_organization", -// "dc:subject" => "subject", -// "dc:contributor" => "contributor", -// "dc:language" => "language"); - -/** - * Core of Campcaster file storage module - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @see Alib - */ -class BasicStor { - public $storId; - private $fileTypes; - - public function __construct() - { - $this->filetypes = array( - 'all'=>NULL, - 'audioclip'=>'audioclip', - 'webstream'=>'webstream', - 'playlist'=>'playlist', - ); - } - - - /** - * Store new file in the storage - * - * @param array $p_values - * See StoredFile::Insert() for details. - * @param boolean $copyMedia - * copy the media file if true, make symlink if false - * @return StoredFile|PEAR_Error - * The StoredFile that was created. - */ - // public function bsPutFile($p_values, $p_copyMedia=TRUE) - // { - // $storedFile = StoredFile::Insert($p_values, $p_copyMedia); - // return $storedFile; - // } - - - /** - * Rename file - * - * @param int $id - * Virtual file's local id - * @param string $newName - * @return boolean|PEAR_Error - */ - // public function bsRenameFile($id, $newName) - // { - // switch (BasicStor::GetObjType($id)) { - // case "audioclip": - // case "playlist": - // case "webstream": - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // // catch nonerror exception: - // //if($storedFile->getCode() != GBERR_FOBJNEX) - // return $storedFile; - // } - // $res = $storedFile->setName($newName); - // if (PEAR::isError($res)) { - // return $res; - // } - // break; - // case "File": - // default: - // } - // return TRUE; - // } - - - /** - * Replace file. Doesn't change filetype! - * - * @param int $id - * Virtual file's local id - * @param string $localFilePath - * Local path of media file - * @param string $metadataFilePath - * Local path of metadata file - * @param string $mdataLoc - * 'file'|'string' - * @return true|PEAR_Error - * @exception PEAR::error - */ - // public function bsReplaceFile($id, $localFilePath, $metadataFilePath, $mdataLoc='file') - // { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // if (!empty($metadataFilePath) && - // ($mdataLoc!='file' || file_exists($metadataFilePath))) { - // $r = $storedFile->setMetadata($metadataFilePath, $mdataLoc); - // if (PEAR::isError($r)) { - // return $r; - // } - // } - // if (!empty($localFilePath) && file_exists($localFilePath)) { - // $r = $storedFile->setRawMediaData($localFilePath); - // if (PEAR::isError($r)) { - // return $r; - // } - // } - // return TRUE; - // } - - - /** - * Delete file - * - * @param int $id - * Virtual file's local id - * @param boolean $forced - * If true don't use trash - * @return true|PEAR_Error - */ - // public function bsDeleteFile($id, $forced=FALSE) - // { - // global $CC_CONFIG; - // // full delete: - // if (!$CC_CONFIG['useTrash'] || $forced) { - // $res = BasicStor::RemoveObj($id, $forced); - // return $res; - // } - // - // $storedFile = StoredFile::Recall($id); - // - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // if ($storedFile->isAccessed()) { - // return PEAR::raiseError( - // 'Cannot delete an object that is currently accessed.' - // ); - // } - // // move to trash: - // switch (BasicStor::GetObjType($id)) { - // - // case "audioclip": - // $playLists = $storedFile->getPlaylists(); - // $item_gunid = $storedFile->getGunid(); - // if( $playLists != NULL) { - // - // foreach($playLists as $key=>$val) { - // $playList_id = BasicStor::IdFromGunidBigInt($val["gunid"]); - // $playList_titles[] = BasicStor::bsGetMetadataValue($playList_id, "dc:title"); - // } - // return PEAR::raiseError( - // 'Please remove this song from all playlists: ' . join(",", $playList_titles) - // ); - // } - // break; - // - // case "playlist": - // if($storedFile->isScheduled()) { - // return PEAR::raiseError( - // 'Cannot delete an object that is scheduled to play.' - // ); - // } - // break; - // - // case "webstream": - // - // break; - // default: - // } - // - // $res = $storedFile->setState('deleted'); - // if (PEAR::isError($res)) { - // return $res; - // } - // - // return TRUE; - // } - - - /* ----------------------------------------------------- put, access etc. */ - /** - * Check validity of access/put token - * - * @param string $token - * Access/put token - * @param string $type - * 'put'|'access'|'download' - * @return boolean - */ - public static function bsCheckToken($token, $type='put') - { - global $CC_CONFIG, $CC_DBC; - $cnt = $CC_DBC->getOne(" - SELECT count(token) FROM ".$CC_CONFIG['accessTable']." - WHERE token=x'{$token}'::bigint AND type='$type' - "); - if (PEAR::isError($cnt)) { - return FALSE; - } - return ($cnt == 1); - } - - - /** - * Create and return access link to real file - * - * @param string $realFname - * Local filepath to accessed file - * (NULL for only increase access counter, no symlink) - * @param string $ext - * Useful filename extension for accessed file - * @param int $gunid - * Global unique id - * (NULL for special files such exported playlists) - * @param string $type - * 'access'|'download' - * @param int $parent - * parent token (recursive access/release) - * @param int $owner - * Local user id - owner of token - * @return array - * array with: seekable filehandle, access token - */ - public static function bsAccess($realFname, $ext, $gunid, $type='access', - $parent='0', $owner=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (!is_null($gunid)) { - $gunid = StoredFile::NormalizeGunid($gunid); - } - $token = StoredFile::CreateGunid(); - if (!is_null($realFname)) { - $linkFname = $CC_CONFIG['accessDir']."/$token.$ext"; - //broken links are ignored by the player, do not worry about it here - /* if (!is_file($realFname) && !is_link($realFname)) { - return PEAR::raiseError( - "BasicStor::bsAccess: real file not found ($realFname)", - GBERR_FILEIO); - } - */ - if (! @symlink($realFname, $linkFname)) { - return PEAR::raiseError( - "BasicStor::bsAccess: symlink create failed ($linkFname)", - GBERR_FILEIO); - } - } else { - $linkFname = NULL; - } - $escapedExt = pg_escape_string($ext); - $escapedType = pg_escape_string($type); - $CC_DBC->query("BEGIN"); - $gunidSql = (is_null($gunid) ? "NULL" : "x'{$gunid}'::bigint" ); - $ownerSql = (is_null($owner) ? "NULL" : "$owner" ); - $res = $CC_DBC->query(" - INSERT INTO ".$CC_CONFIG['accessTable']." - (gunid, token, ext, type, parent, owner, ts) - VALUES - ($gunidSql, x'$token'::bigint, - '$escapedExt', '$escapedType', x'{$parent}'::bigint, $ownerSql, now()) - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - if (!is_null($gunid)) { - $res = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['filesTable']." - SET currentlyAccessing=currentlyAccessing+1, mtime=now() - WHERE gunid=x'{$gunid}'::bigint - "); - } - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - $res = $CC_DBC->query("COMMIT"); - if (PEAR::isError($res)) { - return $res; - } - return array('fname'=>$linkFname, 'token'=>$token); - } - - - /** - * Release access link to real file - * - * @param string $token - * Access token - * @param string $type - * 'access'|'download' - * @return array - * gunid: string, global unique ID or real pathname of special file - * owner: int, local subject id of token owner - * realFname: string, real local pathname of accessed file - */ - public static function bsRelease($token, $type='access') - { - global $CC_CONFIG, $CC_DBC; - if (!BasicStor::bsCheckToken($token, $type)) { - return PEAR::raiseError( - "BasicStor::bsRelease: invalid token ($token)" - ); - } - $acc = $CC_DBC->getRow(" - SELECT to_hex(gunid)as gunid, ext, owner FROM ".$CC_CONFIG['accessTable']." - WHERE token=x'{$token}'::bigint AND type='$type' - "); - if (PEAR::isError($acc)) { - return $acc; - } - $ext = $acc['ext']; - $owner = $acc['owner']; - $linkFname = $CC_CONFIG['accessDir']."/$token.$ext"; - $realFname = readlink($linkFname); - if (file_exists($linkFname)) { - if(! @unlink($linkFname)){ - return PEAR::raiseError( - "BasicStor::bsRelease: unlink failed ($linkFname)", - GBERR_FILEIO); - } - } - $CC_DBC->query("BEGIN"); - if (!is_null($acc['gunid'])) { - $gunid = StoredFile::NormalizeGunid($acc['gunid']); - $res = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['filesTable']." - SET currentlyAccessing=currentlyAccessing-1, mtime=now() - WHERE gunid=x'{$gunid}'::bigint AND currentlyAccessing>0 - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - } - $res = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['accessTable']." WHERE token=x'$token'::bigint - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - $res = $CC_DBC->query("COMMIT"); - if (PEAR::isError($res)) { - return $res; - } - $res = array( - 'gunid' => (isset($gunid) ? $gunid : NULL ), - 'realFname' => $realFname, - 'owner' => $owner, - ); - return $res; - } - - - /** - * Create and return downloadable URL for file - * - * @param int $id - * Virtual file's local id - * @param string $part - * 'media'|'metadata' - * @param int $parent - * parent token (recursive access/release) - * @return array - * array with strings: - * downloadable URL, download token, chsum, size, filename - */ - // public function bsOpenDownload($id, $part='media') - // { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // $gunid = $storedFile->gunid; - // switch ($part) { - // case "media": - // $realfile = $storedFile->getRealFileName(); - // $ext = $storedFile->getFileExtension(); - // $filename = $storedFile->getName(); - // break; - // case "metadata": - // $realfile = $storedFile->getRealMetadataFileName(); - // $ext = "xml"; - // $filename = $storedFile->getName(); - // break; - // default: - // return PEAR::raiseError( - // "BasicStor::bsOpenDownload: unknown part ($part)" - // ); - // } - // $acc = BasicStor::bsAccess($realfile, $ext, $gunid, 'download'); - // if (PEAR::isError($acc)) { - // return $acc; - // } - // $url = BasicStor::GetUrlPart()."access/".basename($acc['fname']); - // $chsum = md5_file($realfile); - // $size = filesize($realfile); - // return array( - // 'url'=>$url, 'token'=>$acc['token'], - // 'chsum'=>$chsum, 'size'=>$size, - // 'filename'=>$filename - // ); - // } - - - /** - * Discard downloadable URL - * - * @param string $token - * Download token - * @param string $part - * 'media'|'metadata' - * @return string - * gunid - */ - // public function bsCloseDownload($token, $part='media') - // { - // if (!BasicStor::bsCheckToken($token, 'download')) { - // return PEAR::raiseError( - // "BasicStor::bsCloseDownload: invalid token ($token)" - // ); - // } - // $r = BasicStor::bsRelease($token, 'download'); - // if (PEAR::isError($r)){ - // return $r; - // } - // return (is_null($r['gunid']) ? $r['realFname'] : $r['gunid']); - // } - - - /** - * Create writable URL for HTTP PUT method file insert - * - * @param string $chsum - * md5sum of the file having been put - * @param string $gunid - * global unique id - * (NULL for special files such imported playlists) - * @param int $owner - * local user id - owner of token - * @return array - * array with: - * url string: writable URL - * fname string: writable local filename - * token string: PUT token - */ - // public function bsOpenPut($chsum, $gunid, $owner=NULL) - // { - // global $CC_CONFIG, $CC_DBC; - // if (!is_null($gunid)) { - // $gunid = StoredFile::NormalizeGunid($gunid); - // } - // $escapedChsum = pg_escape_string($chsum); - // $token = StoredFile::CreateGunid(); - // $res = $CC_DBC->query("DELETE FROM ".$CC_CONFIG['accessTable'] - // ." WHERE token=x'$token'::bigint"); - // if (PEAR::isError($res)) { - // return $res; - // } - // $gunidSql = (is_null($gunid) ? "NULL" : "x'{$gunid}'::bigint" ); - // $ownerSql = (is_null($owner) ? "NULL" : "$owner" ); - // $res = $CC_DBC->query(" - // INSERT INTO ".$CC_CONFIG['accessTable']." - // (gunid, token, ext, chsum, type, owner, ts) - // VALUES - // ($gunidSql, x'$token'::bigint, - // '', '$escapedChsum', 'put', $ownerSql, now())"); - // if (PEAR::isError($res)) { - // return $res; - // } - // $fname = $CC_CONFIG['accessDir']."/$token"; - // touch($fname); // is it needed? - // $url = BasicStor::GetUrlPart()."xmlrpc/put.php?token=$token"; - // return array('url'=>$url, 'fname'=>$fname, 'token'=>$token); - // } - - - /** - * Get file from writable URL and return local filename. - * Caller should move or unlink this file. - * - * @param string $token - * PUT token - * @return array - * hash with fields: - * fname string, local path of the file having been put - * owner int, local subject id - owner of token - */ - // public function bsClosePut($token) - // { - // global $CC_CONFIG, $CC_DBC; - // $token = StoredFile::NormalizeGunid($token); - // - // if (!BasicStor::bsCheckToken($token, 'put')) { - // return PEAR::raiseError( - // "BasicStor::bsClosePut: invalid token ($token)", - // GBERR_TOKEN); - // } - // $row = $CC_DBC->getRow( - // "SELECT chsum, owner FROM ".$CC_CONFIG['accessTable'] - // ." WHERE token=x'{$token}'::bigint"); - // if (PEAR::isError($row)) { - // return $row; - // } - // $fname = $CC_CONFIG['accessDir']."/$token"; - // $md5sum = md5_file($fname); - // - // $chsum = $row['chsum']; - // $owner = $row['owner']; - // $error = null; - // if ( (trim($chsum) != '') && ($chsum != $md5sum) ) { - // // Delete the file if the checksums do not match. - // if (file_exists($fname)) { - // @unlink($fname); - // } - // $error = new PEAR_Error( - // "BasicStor::bsClosePut: md5sum does not match (token=$token)". - // " [$chsum/$md5sum]", - // GBERR_PUT); - // } else { - // // Remember the MD5 sum - // $storedFile = StoredFile::RecallByToken($token); - // if (!is_null($storedFile) && !PEAR::isError($storedFile)) { - // $storedFile->setMd5($md5sum); - // } else { - //# $error = $storedFile; - // } - // } - // - // // Delete entry from access table. - // $res = $CC_DBC->query("DELETE FROM ".$CC_CONFIG['accessTable'] - // ." WHERE token=x'$token'::bigint"); - // if (PEAR::isError($error)) { - // return $error; - // } elseif (PEAR::isError($res)) { - // return $res; - // } - // - // return array('fname'=>$fname, 'owner'=>$owner); - // } - - - /** - * Check uploaded file - * - * @param string $token - * "Put" token - * @return array - * hash, ( - * status: boolean, - * size: int - filesize - * expectedsum: string - expected checksum - * realsum: string - checksum of uploaded file - * ) - */ - // public function bsCheckPut($token) - // { - // global $CC_CONFIG, $CC_DBC; - // if (!BasicStor::bsCheckToken($token, 'put')) { - // return PEAR::raiseError( - // "BasicStor::bsCheckPut: invalid token ($token)" - // ); - // } - // $chsum = $CC_DBC->getOne(" - // SELECT chsum FROM ".$CC_CONFIG['accessTable']." - // WHERE token=x'{$token}'::bigint - // "); - // if (PEAR::isError($chsum)) { - // return $chsum; - // } - // $fname = $CC_CONFIG['accessDir']."/$token"; - // $md5sum = md5_file($fname); - // $size = filesize($fname); - // $status = ($chsum == $md5sum); - // return array( - // 'status'=>$status, 'size'=>$size, - // 'expectedsum'=>$chsum, - // 'realsum'=>$md5sum, - // ); - // } - - - /** - * Return starting part of storageServer URL - * - * @return string - * URL - */ - // public static function GetUrlPart() - // { - // global $CC_CONFIG; - // $host = $CC_CONFIG['storageUrlHost']; - // $port = $CC_CONFIG['storageUrlPort']; - // $path = $CC_CONFIG['storageUrlPath']; - // return "http://$host:$port$path/"; - // } - - - /** - * Get tokens by type - * - * @param string $type - * access|put|render etc. - * @return array - * array of tokens - */ - // public static function GetTokensByType($type) - // { - // global $CC_CONFIG, $CC_DBC; - // $res = $CC_DBC->query( - // "SELECT TO_HEX(token) AS token FROM ".$CC_CONFIG['accessTable']." WHERE type=?", - // array($type)); - // while ($row = $res->fetchRow()) { - // $r[] = $row['token']; - // } - // return $r; - // } - - - /* ----------------------------------------------------- metadata methods */ - - /** - * Replace metadata with new XML file or string - * - * @param int $id - * Virtual file's local id - * @param string $mdata - * Local path of metadata XML file - * @param string $mdataLoc - * 'file'|'string' - * @return boolean|PEAR_Error - */ - // public function bsReplaceMetadata($id, $mdata, $mdataLoc='file') - // { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // return $storedFile->setMetadata($mdata, $mdataLoc); - // } - - - /** - * Get metadata as XML string - * - * @param int $id - * Virtual file's local id - * @return string|PEAR_Error - */ - // public function bsGetMetadata($id) - // { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // return $storedFile->getMetadata(); - // } - - - /** - * Get dc:title (if exists) - * - * @param int $id - * Virtual file's local id - * @param string $gunid - * Virtual file's gunid, optional, used only if not - * null, id is then ignored - * @return string|PEAR_Error - */ - // public function bsGetTitle($id, $gunid=NULL) - // { - // if (is_null($gunid)) { - // $storedFile = StoredFile::Recall($id); - // } else { - // $storedFile = StoredFile::RecallByGunid($gunid); - // } - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // $r = $storedFile->md["title"]; - // $title = (empty($r) ? 'unknown' : $r); - // return $title; - // } - - - /** - * Get metadata element value - * - * @param int $id - * Virtual file's local id - * @param string|array|null $category - * metadata element name, or array of metadata element names, - * if null is passed, all metadata values for the given ID will - * be fetched. - * @return string|array - * If a string is passed in for $category, a string is returned, - * if an array is passed, an array is returned. - * @see Metadata::getMetadataValue - */ - // public function bsGetMetadataValue($id, $category = null) - // { - // if (!is_numeric($id)) { - // return null; - // } - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // if (is_null($category)) { - // return $storedFile->md; - // } elseif (is_array($category)) { - // $values = array(); - // foreach ($category as $tmpCat) { - // $values[$tmpCat] = $storedFile->md[$tmpCat]; - // } - // return $values; - // } else { - // return $storedFile->md[$category]; - // } - // } - - - /** - * Convert XML name to database column name. Used for backwards compatibility - * with old code. - * - * @param string $p_category - * @return string|null - */ - // public static function xmlCategoryToDbColumn($p_category) - // { - // global $g_metadata_xml_to_db_mapping; - // if (array_key_exists($p_category, $g_metadata_xml_to_db_mapping)) { - // return $g_metadata_xml_to_db_mapping[$p_category]; - // } - // return null; - // } - - - /** - * Convert database column name to XML name. - * - * @param string $p_dbColumn - * @return string|null - */ - // public static function dbColumnToXmlCatagory($p_dbColumn) - // { - // global $g_metadata_xml_to_db_mapping; - // $str = array_search($p_dbColumn, $g_metadata_xml_to_db_mapping); - // // make return value consistent with xmlCategoryToDbColumn() - // if ($str === FALSE) { - // $str = null; - // } - // return $str; - // } - - /** - * Set metadata element value - * - * @param int|StoredFile $id - * Database ID of file - * @param string $category - * Metadata element identification (e.g. dc:title) - * @param string $value - * value to store, if NULL then delete record - * @return boolean - */ - // public static function bsSetMetadataValue($p_id, $p_category, $p_value) - // { - // global $CC_CONFIG, $CC_DBC; - // if (!is_string($p_category) || is_array($p_value)) { - // return FALSE; - // } - // if (is_a($p_id, "StoredFile")) { - // $p_id = $p_id->getId(); - // } - // if ($p_category == 'dcterms:extent') { - // $p_value = BasicStor::NormalizeExtent($p_value); - // } - // $columnName = BasicStor::xmlCategoryToDbColumn($p_category); // Get column name - // - // if (!is_null($columnName)) { - // $escapedValue = pg_escape_string($p_value); - // $sql = "UPDATE ".$CC_CONFIG["filesTable"] - // ." SET $columnName='$escapedValue'" - // ." WHERE id=$p_id"; - // //var_dump($sql); - // $res = $CC_DBC->query($sql); - // if (PEAR::isError($res)) { - // return $res; - // } - // } - // return TRUE; - // } - - - /** - * Normalize time value to hh:mm:ss:dddddd format - * - * @param mixed $v - * value to normalize - * @return string - */ - // private static function NormalizeExtent($v) - // { - // if (!preg_match("|^\d{2}:\d{2}:\d{2}.\d{6}$|", $v)) { - // $s = Playlist::playlistTimeToSeconds($v); - // $t = Playlist::secondsToPlaylistTime($s); - // return $t; - // } - // return $v; - // } - - - /** - * Set metadata values in 'batch' mode - * - * @param int|StoredFile $id - * Database ID of file or StoredFile object - * @param array $values - * array of key/value pairs - * (e.g. 'dc:title'=>'New title') - * @return boolean - */ - // public static function bsSetMetadataBatch($id, $values) - // { - // global $CC_CONFIG, $CC_DBC; - // if (!is_array($values)) { - // $values = array($values); - // } - // if (count($values) == 0) { - // return true; - // } - // if (is_a($id, "StoredFile")) { - // $storedFile =& $id; - // } else { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // } - // foreach ($values as $category => $oneValue) { - // $columnName = BasicStor::xmlCategoryToDbColumn($category); - // if (!is_null($columnName)) { - // if ($category == 'dcterms:extent') { - // $oneValue = BasicStor::NormalizeExtent($oneValue); - // } - // // Since track_number is an integer, you cannot set - // // it to be the empty string, so we NULL it instead. - // if ($columnName == 'track_number' && empty($oneValue)) { - // $sqlPart = "$columnName = NULL"; - // } elseif (($columnName == 'length') && (strlen($oneValue) > 8)) { - // // Postgres doesnt like it if you try to store really large hour - // // values. TODO: We need to fix the underlying problem of getting the - // // right values. - // $parts = explode(':', $oneValue); - // $hour = intval($parts[0]); - // if ($hour > 24) { - // continue; - // } else { - // $sqlPart = "$columnName = '$oneValue'"; - // } - // } else { - // $escapedValue = pg_escape_string($oneValue); - // $sqlPart = "$columnName = '$escapedValue'"; - // } - // $sqlValues[] = $sqlPart; - // } - // } - // if (count($sqlValues)==0) { - // return TRUE; - // } - // $sql = "UPDATE ".$CC_CONFIG["filesTable"] - // ." SET ".join(",", $sqlValues) - // ." WHERE id=$id"; - // $CC_DBC->query($sql); - // return TRUE; - // } - - /** - * Method returning array with where-parts of sql queries - * - * @param array $conditions - * See 'conditions' field in search criteria format - * definition in class documentation - * @return array - * array of strings - WHERE-parts of SQL queries - */ - private function _makeWhereArr($conditions) - { - $ops = array('full'=>"='%s'", 'partial'=>"ILIKE '%%%s%%'", - 'prefix'=>"ILIKE '%s%%'", '<'=>"< '%s'", '='=>"= '%s'", - '>'=>"> '%s'", '<='=>"<= '%s'", '>='=>">= '%s'" - ); - $whereArr = array(); - if (is_array($conditions)) { - foreach ($conditions as $cond) { - $columnName = StoredFile::xmlCategoryToDbColumn($cond['cat']); - $op = strtolower($cond['op']); - $value = $cond['val']; - if (!empty($value)) { - $splittedQn = XML_Util::splitQualifiedName($catQn); - $catNs = $splittedQn['namespace']; - $cat = $splittedQn['localPart']; - $opVal = sprintf($ops[$op], pg_escape_string($value)); - // retype for timestamp value - if ($cat == 'mtime') { - switch ($op) { - case 'partial': - case 'prefix': - break; - default: - $retype = "::timestamp with time zone"; - $opVal = "$retype $opVal$retype"; - } - } - $sqlCond = " {$columnName} {$opVal}\n"; - $whereArr[] = $sqlCond; - } - } - } - return $whereArr; - } - - /** - * Search in local metadata database. - * - * @param array $criteria - * has the following structure:
- * - * @param int $limit - * limit for result arrays (0 means unlimited) - * @param int $offset - * starting point (0 means without offset) - * @return array - * array of hashes, fields: - * cnt : integer - number of matching gunids - * of files have been found - * results : array of hashes: - * gunid: string - * type: string - audioclip | playlist | webstream - * title: string - dc:title from metadata - * creator: string - dc:creator from metadata - * source: string - dc:source from metadata - * length: string - dcterms:extent in extent format - */ - public function bsLocalSearch($criteria, $limit=0, $offset=0) - { - global $CC_CONFIG, $CC_DBC; - - // Input values - $filetype = (isset($criteria['filetype']) ? $criteria['filetype'] : 'all'); - $filetype = strtolower($filetype); - if (!array_key_exists($filetype, $this->filetypes)) { - return PEAR::raiseError(__FILE__.":".__LINE__.': unknown filetype in search criteria'); - } - $filetype = $this->filetypes[$filetype]; - $operator = (isset($criteria['operator']) ? $criteria['operator'] : 'and'); - $operator = strtolower($operator); - $conditions = (isset($criteria['conditions']) ? $criteria['conditions'] : array()); - - // Create the WHERE clause - this is the actual search part - $whereArr = $this->_makeWhereArr($conditions); - - // Metadata values to fetch - $metadataNames = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title', 'dcterms:extent'); - - // Order by clause - $orderby = TRUE; - $orderByAllowedValues = array('dc:creator', 'dc:source', 'dc:title', 'dcterms:extent', "ls:track_num"); - $orderByDefaults = array('dc:creator', 'dc:source', 'dc:title'); - if ((!isset($criteria['orderby'])) - || (is_array($criteria['orderby']) && (count($criteria['orderby'])==0))) { - // default ORDER BY - // PaulB: track number removed because it doesnt work yet because - // if track_num is not an integer (e.g. bad metadata like "1/20", - // or if the field is blank) the SQL statement gives an error. - //$orderbyQns = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title'); - $orderbyQns = $orderByDefaults; - } else { - // ORDER BY clause is given in the parameters. - - // Convert the parameter to an array if it isnt already. - $orderbyQns = $criteria['orderby']; - if (!is_array($orderbyQns)) { - $orderbyQns = array($orderbyQns); - } - - // Check that it has valid ORDER BY values, if not, revert - // to the default ORDER BY values. - foreach ($orderbyQns as $metadataTag) { - if (!in_array($metadataTag, $orderByAllowedValues)) { - $orderbyQns = $orderByDefaults; - break; - } - } - } - - $descA = (isset($criteria['desc']) ? $criteria['desc'] : NULL); - if (!is_array($descA)) { - $descA = array($descA); - } - - $orderBySql = array(); - // $dataName contains the names of the metadata columns we want to - // fetch. It is indexed numerically starting from 1, and the value - // in the array is the qualified name with ":" replaced with "_". - // e.g. "dc:creator" becomes "dc_creator". - foreach ($orderbyQns as $xmlTag) { - $columnName = StoredFile::xmlCategoryToDbColumn($xmlTag); - $orderBySql[] = $columnName; - } - - // Build WHERE clause - $whereClause = ""; - if (!is_null($filetype)) { - $whereClause .= "WHERE (ftype='$filetype')"; - } - else { - $whereClause .= "WHERE (ftype is NOT NULL)"; - } - if (count($whereArr) != 0) { - if ($operator == 'and') { - $whereClause .= " AND ((".join(") AND (", $whereArr)."))"; - } else { - $whereClause .= " AND ((".join(") OR (", $whereArr)."))"; - } - } - - // Final query - - //"dcterms:extent" => "length", - //"dc:title" => "track_title", - //"dc:creator" => "artist_name", - //dc:description - - global $g_metadata_xml_to_db_mapping; - $plSelect = "SELECT "; - $fileSelect = "SELECT "; - $_SESSION["br"] = ""; - foreach ($g_metadata_xml_to_db_mapping as $key => $val){ - $_SESSION["br"] .= "key: ".$key." value:".$val.", "; - if($key === "dc:title"){ - $plSelect .= "name AS ".$val.", "; - $fileSelect .= $val.", "; - } - else if ($key === "dc:creator"){ - $plSelect .= "creator AS ".$val.", "; - $fileSelect .= $val.", "; - } - else if ($key === "dcterms:extent"){ - $plSelect .= "length, "; - $fileSelect .= "length, "; - } - else if ($key === "dc:description"){ - $plSelect .= "text(description) AS ".$val.", "; - $fileSelect .= $val.", "; - } - else { - $plSelect .= "NULL AS ".$val.", "; - $fileSelect .= $val.", "; - } - } - - $sql = "SELECT * FROM ((".$plSelect."PL.id, 'playlist' AS ftype - FROM ".$CC_CONFIG["playListTable"]." AS PL - LEFT JOIN ".$CC_CONFIG['playListTimeView']." PLT ON PL.id = PLT.id) - - UNION - - (".$fileSelect."id, ftype FROM ".$CC_CONFIG["filesTable"]." AS FILES)) AS RESULTS "; - - $sql .= $whereClause; - - if ($orderby) { - $sql .= " ORDER BY ".join(",", $orderBySql); - } - - $_SESSION["debugsql"] = $sql; - - $res = $CC_DBC->getAll($sql); - if (PEAR::isError($res)) { - return $res; - } - if (!is_array($res)) { - $res = array(); - } - - $count = count($res); - $_SESSION["br"] .= " COUNT: ".$count; - - $res = array_slice($res, $offset != 0 ? $offset : 0, $limit != 0 ? $limit : 10); - - $eres = array(); - foreach ($res as $it) { - $eres[] = array( - 'id' => $it['id'], - 'type' => strtolower($it['ftype']), - 'title' => $it['track_title'], - 'creator' => $it['artist_name'], - 'duration' => $it['length'], - 'source' => $it['album_title'], - 'track_num' => $it['track_number'], - ); - } - return array('results'=>$eres, 'cnt'=>$count); - } - - - /** - * Return values of specified metadata category - * - * @param string $category - * metadata category name with or without namespace prefix (dc:title, author) - * @param int $limit - * limit for result arrays (0 means unlimited) - * @param int $offset - * starting point (0 means without offset) - * @param array $criteria - * see bsLocalSearch method - * @return array - * hash, fields: - * results : array with found values - * cnt : integer - number of matching values - */ - public function bsBrowseCategory($category, $limit=0, $offset=0, $criteria=NULL) - { - global $CC_CONFIG, $CC_DBC; - - $pl_cat = array( - "dcterms:extent" => "length", - "dc:title" => "name", - "dc:creator" => "creator", - "dc:description" => "description" - ); - - $category = strtolower($category); - $columnName = StoredFile::xmlCategoryToDbColumn($category); - if (is_null($columnName)) { - return new PEAR_Error(__FILE__.":".__LINE__." -- could not map XML category to DB column."); - } - $sql = "SELECT DISTINCT $columnName FROM ".$CC_CONFIG["filesTable"]; - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - $countRowsSql = "SELECT COUNT(DISTINCT $columnName) FROM ".$CC_CONFIG["filesTable"]; - - //$_SESSION["br"] = "in Browse Category: ".$category; - $cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $res; - } - if (!is_array($res)) { - $res = array(); - } - - if (array_key_exists($category, $pl_cat) && $category !== "dcterms:extent") { - $columnName = $pl_cat[$category]; - - $sql = "SELECT DISTINCT $columnName FROM ".$CC_CONFIG["playListTable"]; - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - $countRowsSql = "SELECT COUNT(DISTINCT $columnName) FROM ".$CC_CONFIG["playListTable"]; - - $pl_cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $pl_res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $pl_res; - } - if (!is_array($pl_res)) { - $pl_res = array(); - } - - $res = array_merge($res, $pl_res); - $res = array_slice($res, 0, $limit); - $cnt = $cnt + $pl_cnt; - } - else if ($category === "dcterms:extent") { - $columnName = $pl_cat[$category]; - - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - - $sql = "SELECT DISTINCT length AS $columnName FROM ".$CC_CONFIG["playListTimeView"]; - - $countRowsSql = "SELECT COUNT(DISTINCT length) FROM ".$CC_CONFIG["playListTimeView"]; - - $pl_cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $pl_res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $pl_res; - } - if (!is_array($pl_res)) { - $pl_res = array(); - } - - $res = array_merge($res, $pl_res); - $res = array_slice($res, 0, $limit); - $cnt = $cnt + $pl_cnt; - } - - return array('results'=>$res, 'cnt'=>$cnt); - } - - - /* ---------------------------------------------------- methods4playlists */ - - /** - * Create a tarfile with playlist export - playlist and all matching - * sub-playlists and media files (if desired) - * - * @param array $plids - * Array of strings, playlist global unique IDs (one gunid is accepted too) - * @param string $type - * Playlist format, possible values: lspl | smil | m3u - * @param boolean $withContent - * if true, export related files too - * @return array - * hasharray with fields: - * fname string: readable fname, - * token string: access token - */ - // public function bsExportPlaylistOpen($plids, $type='lspl', $withContent=TRUE) - // { - // global $CC_CONFIG; - // if (!is_array($plids)) { - // $plids = array($plids); - // } - // $gunids = array(); - // foreach ($plids as $plid) { - // $pl = StoredFile::RecallByGunid($plid); - // if (is_null($pl) || PEAR::isError($pl)) { - // return $pl; - // } - // if ($withContent) { - // $gunidsX = $pl->export(); - // if (PEAR::isError($gunidsX)) { - // return $gunidsX; - // } - // } else { - // $gunidsX = array(array('gunid'=>$plid, 'type'=>'playlist')); - // } - // $gunids = array_merge($gunids, $gunidsX); - // } - // $plExts = array('lspl'=>"lspl", 'smil'=>"smil", 'm3u'=>"m3u"); - // $plExt = (isset($plExts[$type]) ? $plExts[$type] : "xml" ); - // $res = array(); - // $tmpn = tempnam($CC_CONFIG['bufferDir'], 'plExport_'); - // $tmpf = "$tmpn.tar"; - // $tmpd = "$tmpn.dir"; - // mkdir($tmpd); - // $tmpdp = "$tmpn.dir/playlist"; - // mkdir($tmpdp); - // if ($withContent) { - // $tmpdc = "$tmpn.dir/audioClip"; - // mkdir($tmpdc); - // } - // foreach ($gunids as $i => $it) { - // $storedFile = StoredFile::RecallByGunid($it['gunid']); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - //// $MDfname = $storedFile->md->getFileName(); - // $MDfname = $storedFile->md["name"]; - // if (PEAR::isError($MDfname)) { - // return $MDfname; - // } - // if (file_exists($MDfname)) { - // switch ($it['type']) { - // case "playlist": - // $storedFile = $r = StoredFile::RecallByGunid($it['gunid']); - // switch ($type) { - // case "smil": - // $string = $r = $storedFile->outputToSmil(); - // break; - // case "m3u": - // $string = $r = $storedFile->outputToM3u(); - // break; - // default: - //// $string = $r = $storedFile->md->genXmlDoc(); - // } - // if (PEAR::isError($r)) { - // return $r; - // } - // $r = BasicStor::WriteStringToFile($string, "$tmpdp/{$it['gunid']}.$plExt"); - // if (PEAR::isError($r)) { - // return $r; - // } - // break; - // default: - // copy($MDfname, "$tmpdc/{$it['gunid']}.xml"); break; - // } // switch - // } // if file_exists() - // $RADfname = $storedFile->getRealFileName(); - // if (PEAR::isError($RADfname)) { - // return $RADfname; - // } - // $RADext = $storedFile->getFileExtension(); - // if (PEAR::isError($RADext)) { - // return $RADext; - // } - // if (file_exists($RADfname)) { - // copy($RADfname, "$tmpdc/{$it['gunid']}.$RADext"); - // } - // } - // if (count($plids)==1) { - // copy("$tmpdp/$plid.$plExt", "$tmpd/exportedPlaylist.$plExt"); - // } - // $res = `cd $tmpd; tar cf $tmpf * --remove-files`; - // @rmdir($tmpdc); - // @rmdir($tmpdp); - // @rmdir($tmpd); - // unlink($tmpn); - // $acc = BasicStor::bsAccess($tmpf, 'tar', NULL/*gunid*/, 'access'); - // if (PEAR::isError($acc)) { - // return $acc; - // } - // return $acc; - // } - - - /** - * Close playlist export previously opened by the bsExportPlaylistOpen - * method - * - * @param string $token - * Access token obtained from bsExportPlaylistOpen method call. - * @return true/PEAR_Error - */ - // public function bsExportPlaylistClose($token) - // { - // $r = BasicStor::bsRelease($token, 'access'); - // if (PEAR::isError($r)) { - // return $r; - // } - // $file = $r['realFname']; - // if (file_exists($file)) { - // if(! @unlink($file)){ - // return PEAR::raiseError( - // "BasicStor::bsExportPlaylistClose: unlink failed ($file)", - // GBERR_FILEIO); - // } - // } - // return TRUE; - // } - - - /** - * Import playlist in LS Archive format - * - * @param string $plid - * Playlist gunid - * @param string $aPath - * Absolute path part of imported file (e.g. /home/user/campcaster) - * @param string $rPath - * Relative path/filename part of imported file (e.g. playlists/playlist_1.smil) - * @param string $ext - * Playlist extension (determines type of import) - * @param array $gunids - * Hash relation from filenames to gunids - * @param int $subjid - * Local subject (user) id (id of user doing the import) - * @return int - * Result file local id (or error object) - */ - // public function bsImportPlaylistRaw($plid, $aPath, $rPath, $ext, &$gunids, $subjid) - // { - // $id = BasicStor::IdFromGunid($plid); - // if (!is_null($id)) { - // return $id; - // } - // $path = realpath("$aPath/$rPath"); - // if (FALSE === $path) { - // return PEAR::raiseError( - // "BasicStor::bsImportPlaylistRaw: file doesn't exist ($aPath/$rPath)" - // ); - // } - // switch ($ext) { - // case "xml": - // case "lspl": - // $fname = $plid; - // $values = array( - // "filename" => $fname, - // "metadata" => $path, - // "gunid" => $plid, - // "filetype" => "playlist" - // ); - // $storedFile = StoredFile::Insert($values); - // $res = $storedFile->getId(); - // break; - // case "smil": - // require_once("SmilPlaylist.php"); - // $res = SmilPlaylist::import($this, $aPath, $rPath, $gunids, $plid, $subjid); - // if (PEAR::isError($res)) { - // break; - // } - // $res = $res->getId(); - // break; - // case "m3u": - // require_once("M3uPlaylist.php"); - // $res = M3uPlaylist::import($this, $aPath, $rPath, $gunids, $plid, $subjid); - // if (PEAR::isError($res)) { - // break; - // } - // $res = $res->getId(); - // break; - // default: - // $res = PEAR::raiseError( - // "BasicStor::importPlaylistRaw: unknown playlist format". - // " (gunid:$plid, format:$ext)" - // ); - // break; - // } - // if (!PEAR::isError($res)) { - // $gunids[basename($rPath)] = $plid; - // } - // return $res; - // } - - - /** - * Import playlist in LS Archive format - * - * @param string $fpath - * Imported file pathname - * @param int $subjid - * Local subject (user) id (id of user doing the import) - * @return int - * Result file local id (or error object) - */ - // public function bsImportPlaylist($fpath, $subjid) - // { - // global $CC_CONFIG; - // // untar: - // $tmpn = tempnam($CC_CONFIG['bufferDir'], 'plImport_'); - // $tmpd = "$tmpn.dir"; - // $tmpdc = "$tmpd/audioClip"; - // $tmpdp = "$tmpd/playlist"; - // mkdir($tmpd); - // $res = `cd $tmpd; tar xf $fpath`; - // // clips: - // $d = @dir($tmpdc); - // $entries = array(); - // $gunids = array(); - // if ($d !== false) { - // while (false !== ($entry = $d->read())) { - // if (preg_match("|^([0-9a-fA-F]{16})\.(.*)$|", $entry, $va)) { - // list(,$gunid, $ext) = $va; - // switch ($ext) { - // case"xml": - // $entries[$gunid]['metadata'] = $entry; - // break; - // default: - // $entries[$gunid]['rawMedia'] = $entry; - // $entries[$gunid]['rawMediaExt'] = $ext; - // $gunids[$entry] = $gunid; - // break; - // } - // } - // } - // $d->close(); - // } - // $res = TRUE; - // foreach ($entries as $gunid => $it) { - // $rawMedia = "$tmpdc/{$it['rawMedia']}"; - // if (!file_exists($rawMedia)) { - // $rawMedia = NULL; - // } - // $metadata = "$tmpdc/{$it['metadata']}"; - // if (!file_exists($metadata)) { - // $metadata = NULL; - // } - // $f = StoredFile::RecallByGunid($gunid); - // if (!PEAR::isError($f)) { - // $exists = $f->existsFile(); - // if ( $exists ) { - // $res = $f->delete(); - // } - // } - // if (!PEAR::isError($res) ) { - // $values = array( - // "filename" => $gunid, - // "filepath" => $rawMedia, - // "metadata" => $metadata, - // "gunid" => $gunid, - // "filetype" => "audioclip" - // ); - // $storedFile = StoredFile::Insert($values); - // $res = $storedFile->getId(); - // } - // @unlink("$tmpdc/{$it['rawMedia']}"); - // @unlink("$tmpdc/{$it['metadata']}"); - // if (PEAR::isError($res)) { - // break; - // } - // } - // // playlists: - // $d = @dir($tmpdp); - // if ($d !== false) { - // while ((!PEAR::isError($res)) && false !== ($entry = $d->read())) { - // if (preg_match("|^([0-9a-fA-F]{16})\.(.*)$|", $entry, $va)) { - // list(,$gunid, $ext) = $va; - // $res = $this->bsImportPlaylistRaw($gunid, - // $tmpdp, $entry, $ext, $gunids, $subjid); - // unlink("$tmpdp/$entry"); - // if (PEAR::isError($res)) { - // break; - // } - // } - // } - // $d->close(); - // } - // //@rmdir($tmpdc); @rmdir($tmpdp); @rmdir($tmpd); - // @system("rm -rf $tmpdc"); - // @system("rm -rf $tmpdp"); - // @system("rm -rf $tmpd"); - // @unlink($tmpn); - // return $res; - // } - - - /* --------------------------------------------------------- info methods */ - - /** - * Analyze media file for internal metadata information - * - * @param int $id - * Virtual file's local id - * @return array - */ - // public function bsAnalyzeFile($id) - // { - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // $ia = $storedFile->analyzeFile(); - // return $ia; - // } - - - /** - * Check if file exists in the storage - * - * @param int $id - * Local id - * @param string $ftype - * Internal file type - * @param boolean $byGunid - * select file by gunid (id is then ignored) - * @return boolean - */ - // public function bsExistsFile($id, $ftype=NULL, $byGunid=FALSE) - // { - // if ($byGunid) { - // $storedFile = StoredFile::RecallByGunid($id); - // } else { - // $storedFile = StoredFile::Recall($id); - // } - // if (is_null($storedFile)) { - // return $storedFile; - // } - // if (PEAR::isError($storedFile)) { - // // catch some exceptions - // switch ($storedFile->getCode()) { - // case GBERR_FILENEX: - // case GBERR_FOBJNEX: - // return FALSE; - // break; - // default: - // return $storedFile; - // } - // } - // $realFtype = BasicStor::GetType($storedFile->gunid); - // if (!is_null($ftype) && ( - // (strtolower($realFtype) != strtolower($ftype)) - // // webstreams are subset of audioclips - // && !($realFtype == 'webstream' && $ftype == 'audioclip') - // )) { - // return FALSE; - // } - // return TRUE; - // } - - - /* ---------------------------------------------------- redefined methods */ - /** - * Get object type by id. - * - * @param int $oid - * Local object id - * @return string|PEAR_Error - */ - // public static function GetObjType($p_id) - // { - // $type = "unknown"; - // $f = StoredFile::Recall($p_id); - // return $f->getType(); - - // $gunid = BasicStor::GunidFromId($oid); - // if (PEAR::isError($gunid)) { - // return $gunid; - // } - // $ftype = BasicStor::GetType($gunid); - // if (PEAR::isError($ftype)) { - // return $ftype; - // } - // if (!is_null($ftype)) { - // $type = $ftype; - // } - // return $type; - // } - - - /** - * Add new user - * - * @param string $login - * @param string $pass - * @param string $realname - * @return int|PEAR_Error - */ - public static function addSubj($login, $pass=NULL, $realname='') - { - global $CC_CONFIG; - $uid = Subjects::AddSubj($login, $pass, $realname); - if (PEAR::isError($uid)) { - return $uid; - } - if (Subjects::IsGroup($uid) === FALSE) { - $res = Alib::AddPerm($uid, '_all', '0', 'A'); - if (PEAR::isError($res)) { - return $res; - } - $res = Subjects::AddSubjectToGroup($login, $CC_CONFIG['StationPrefsGr']); - if (PEAR::isError($res)) { - return $res; - } - // $res = Subjects::AddSubjectToGroup($login, $CC_CONFIG['AllGr']); - // if (PEAR::isError($res)) { - // return $res; - // } - } - return $uid; - } - - - /** - * Remove user by login - * - * @param string $login - * @return boolean|PEAR_Error - */ - public function removeSubj($login) - { - global $CC_CONFIG, $CC_DBC; - if (FALSE !== array_search($login, $CC_CONFIG['sysSubjs'])) { - return $CC_DBC->raiseError( - "BasicStor::removeSubj: cannot remove system user/group"); - } - $uid = Subjects::GetSubjId($login); - if (PEAR::isError($uid)) { - return $uid; - } - $res = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['accessTable']." WHERE owner=$uid - "); - if (PEAR::isError($res)) { - return $res; - } - $res = Alib::RemoveSubj($login); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Authenticate and create session - * - * @param string $login - * @param string $pass - * @return boolean|sessionId|PEAR_Error - */ - function login($login, $pass) - { - $r = Alib::Login($login, $pass); - return $r; - } - - - /* ================================================== "protected" methods */ - /** - * Check authorization - auxiliary method - * - * @param array $acts - * Array of actions - * @param array $pars - * Array of parameters - e.g. ids - * @param string $sessid - * Session id - * @return true|PEAR_Error - */ - public static function Authorize($acts, $pars, $sessid='') - { - $userid = Alib::GetSessUserId($sessid); - if (PEAR::isError($userid)) { - return $userid; - } - if (is_null($userid)) { - return PEAR::raiseError( - "BasicStor::Authorize: invalid session", GBERR_DENY); - } - if (!is_array($pars)) { - $pars = array($pars); - } - if (!is_array($acts)) { - $acts = array($acts); - } - $perm = true; - // foreach ($acts as $i => $action) { - // $res = Alib::CheckPerm($userid, $action, $pars[$i]); - // if (PEAR::isError($res)) { - // return $res; - // } - // $perm = $perm && $res; - // } - if ($perm) { - return TRUE; - } - $adesc = "[".join(',',$acts)."]"; - return PEAR::raiseError( - "BasicStor::$adesc: access denied", GBERR_DENY); - } - - - /** - * Get local id from global id (in hex). - * - * @param string $p_gunid - * Global id - * @return int - * Local id - */ - // public static function IdFromGunid($p_gunid) - // { - // global $CC_DBC; - // global $CC_CONFIG; - // return $CC_DBC->getOne("SELECT id FROM ".$CC_CONFIG['filesTable']." WHERE gunid=x'$p_gunid'::bigint"); - // } - - /** - * Get local id from global id (big int). - * - * @param string $p_gunid - * Global id - * @return int - * Local id - */ - // public static function IdFromGunidBigInt($p_gunid) - // { - // global $CC_DBC; - // global $CC_CONFIG; - // return $CC_DBC->getOne("SELECT id FROM ".$CC_CONFIG['filesTable']." WHERE gunid='$p_gunid'"); - // } - - - /** - * Get global id from local id - * - * @param int $p_id - * Local id - * @return string - * Global id - */ - // public static function GunidFromId($p_id) - // { - // global $CC_CONFIG; - // global $CC_DBC; - // if (!is_numeric($p_id)) { - // return NULL; - // } - // $gunid = $CC_DBC->getOne(" - // SELECT to_hex(gunid)as gunid FROM ".$CC_CONFIG['filesTable']." - // WHERE id='$p_id' - // "); - // if (PEAR::isError($gunid)) { - // return $gunid; - // } - // if (is_null($gunid)) { - // return NULL; - // } - // return StoredFile::NormalizeGunid($gunid); - // } - - - /** - * Get storage-internal file type - * - * @param string $p_gunid - * Global unique id of file - * @return string - */ - // public static function GetType($p_gunid) - // { - // global $CC_CONFIG; - // global $CC_DBC; - // $ftype = $CC_DBC->getOne(" - // SELECT ftype FROM ".$CC_CONFIG['filesTable']." - // WHERE gunid=x'$p_gunid'::bigint - // "); - // return $ftype; - // } - - - /** - * Check gunid format - * - * @param string $p_gunid - * Global unique ID - * @return boolean - */ - // protected static function CheckGunid($p_gunid) - // { - // $res = preg_match("|^([0-9a-fA-F]{16})?$|", $p_gunid); - // return $res; - // } - - /** - * Set playlist edit flag - * - * @param string $p_playlistId - * Playlist unique ID - * @param boolean $p_val - * Set/clear of edit flag - * @param string $p_sessid - * Session id - * @param int $p_subjid - * Subject id (if sessid is not specified) - * @return boolean - * previous state - */ - public function setEditFlag($p_playlistId, $p_val=TRUE, $p_sessid=NULL, $p_subjid=NULL) - { - if (!is_null($p_sessid)) { - $p_subjid = Alib::GetSessUserId($p_sessid); - if (PEAR::isError($p_subjid)) { - return $p_subjid; - } - } - $pl = Playlist::Recall($p_playlistId); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - $state = $pl->getState(); - if ($p_val) { - $r = $pl->setState('edited', $p_subjid); - } else { - $r = $pl->setState('ready', 'NULL'); - } - if (PEAR::isError($r)) { - return $r; - } - return ($state == 'edited'); - } - - - /** - * Check if playlist is marked as edited - * - * @param string $p_playlistId - * Playlist global unique ID - * @return FALSE|int - * ID of user editing it - */ - public function isEdited($p_playlistId) - { - $pl = Playlist::Recall($p_playlistId); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - if (!$pl->isEdited($p_playlistId)) { - return FALSE; - } - return $pl->isEditedBy($p_playlistId); - } - - - /* ---------------------------------------- redefined "protected" methods */ - /** - * Copy virtual file. - * Redefined from parent class. - * - * @return int - * New object local id - */ - // protected static function CopyObj($id, $newParid, $after=NULL) - // { - // switch (BasicStor::GetObjType($id)) { - // case "audioclip": - // case "playlist": - // case "webstream": - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile) || PEAR::isError($storedFile)) { - // return $storedFile; - // } - // $ac2 = StoredFile::CopyOf($storedFile, $nid); - // //$ac2->setName(M2tree::GetObjName($nid)); - // break; - // case "File": - // default: - // } - // return $nid; - // } - - - /** - * Remove virtual file.
- * Redefined from parent class. - * - * @param int $id - * Local id of removed object - * @param boolean $forced - * Unconditional delete - * @return true|PEAR_Error - */ - // public static function RemoveObj($id, $forced=FALSE) - // { - // $ot = BasicStor::GetObjType($id); - // if (PEAR::isError($ot)) { - // return $ot; - // } - // switch ($ot) { - // case "audioclip": - // case "playlist": - // case "webstream": - // $storedFile = StoredFile::Recall($id); - // if (is_null($storedFile)) { - // return TRUE; - // } - // if (PEAR::isError($storedFile)) { - // return $storedFile; - // } - // if ($storedFile->isEdited() && !$forced) { - // return PEAR::raiseError( - // 'BasicStor::RemoveObj(): is edited' - // ); - // } - // if ($storedFile->isAccessed() && !$forced) { - // return PEAR::raiseError( - // 'BasicStor::RemoveObj(): is accessed' - // ); - // } - // $storedFile->delete(); - // break; - // case "File": - //// case "Folder": - //// case "Replica": - // break; - // default: - // return PEAR::raiseError( - // "BasicStor::bsDeleteFile: unknown obj type ($ot)" - // ); - // } - // $res = Alib::RemoveObj($id); - // if (PEAR::isError($res)) { - // return $res; - // } - // return TRUE; - // } - - - /* ========================================================= misc methods */ - /** - * Write string to file - * - * @param string $str - * string to be written to file - * @param string $fname - * pathname to file - * @return TRUE|raiseError - */ - private static function WriteStringToFile($p_str, $p_fname) - { - $fp = @fopen($p_fname, "w"); - if ($fp === FALSE) { - return PEAR::raiseError( - "BasicStor::WriteStringToFile: cannot open file ($p_fname)" - ); - } - fwrite($fp, $p_str); - fclose($fp); - return TRUE; - } - - - /* =============================================== test and debug methods */ - - /** - * - * - */ - public function debug($va) - { - echo"
\n";
-        print_r($va);
-    }
-
-
-    /**
-     * deleteFiles
-     *
-     * @return void
-     */
-    //    private function deleteFiles()
-    //    {
-    //        global $CC_CONFIG, $CC_DBC;
-    //        $ids = $CC_DBC->getAll("SELECT id FROM ".$CC_CONFIG['filesTable']);
-    //        if (is_array($ids)) {
-    //            foreach ($ids as $i => $item) {
-    //              $f = StoredFile::Recall($item['id']);
-    //              $f->delete();
-    //            }
-    //        }
-    //    }
-
-
-    /**
-     * Aux logging for debug
-     *
-     * @param string $msg - log message
-     */
-    public function debugLog($msg)
-    {
-        global $CC_CONFIG, $CC_DBC;
-        $fp = fopen($CC_CONFIG['storageDir']."/log", "a") or die("Can't write to log\n");
-        fputs($fp, date("H:i:s").">$msg<\n");
-        fclose($fp);
-    }
-
-    } // class BasicStor
-    ?>
\ No newline at end of file
diff --git a/backend/GreenBox.php b/backend/GreenBox.php
deleted file mode 100644
index d990cc2db..000000000
--- a/backend/GreenBox.php
+++ /dev/null
@@ -1,1726 +0,0 @@
-";
-}
-require_once("BasicStor.php");
-if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) {
-    echo __FILE__.':line '.__LINE__.": Loaded BasicStor
"; -} -require_once("Playlist.php"); -require_once("Renderer.php"); -require_once('Prefs.php'); -require_once("Backup.php"); -require_once('Restore.php'); -require_once("Transport.php"); - -/** - * GreenBox class - * - * File storage module. - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class GreenBox extends BasicStor { - - /* ====================================================== storage methods */ - - /** - * Store new file in the storage - * - * @param string $fileName - * The name for the new file. - * @param string $mediaFileLP - * Local path of the media file - * @param string $mdataFileLP - * Local path of the metadata file - * @param string $sessid - * Session id - * @param string $gunid - * Global unique id - * @param string $ftype - * Internal file type - * @return int - * ID of the StoredFile that was created. - */ - public function putFile($p_values, $p_sessionId='') - { - if (($res = BasicStor::Authorize('write', null, $p_sessionId)) !== TRUE) { - return $res; - } - $storedFile = StoredFile::Insert($p_values); - return $storedFile; - } // fn putFile - - - /** - * Store new webstream - * - * @param string $fileName - * Name for new file - * @param string $mdataFileLP - * Local path of metadata file - * @param string $sessid - * Session id - * @param string $gunid - * Global unique id - * @param string $url - * Webstream url - * @return int - * @exception PEAR::error - */ - public function storeWebstream($fileName, $mdataFileLP, $sessid='', - $gunid=NULL, $url) - { - if (($res = BasicStor::Authorize('write', null, $sessid)) !== TRUE) { - return $res; - } - if (!file_exists($mdataFileLP)) { - $mdataFileLP = dirname(__FILE__).'/emptyWebstream.xml'; - } - $values = array( - "filename" => $fileName, - "metadata" => $mdataFileLP, - "gunid" => $gunid, - "filetype" => "webstream" - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - $r = $storedFile->setMetadataValue('ls:url', $url); - if (PEAR::isError($r)) { - return $r; - } - return $oid; - } // fn storeWebstream - - - /** - * Access stored file - increase access counter - * - * @param int $id - * virt.file's local id - * @param string $sessid - * session id - * @return string access token - */ - // function accessFile($id, $sessid='') - // { - // if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - // return $res; - // } - // $gunid = BasicStor::GunidFromId($id); - // $r = BasicStor::bsAccess(NULL, '', $gunid, 'access'); - // if (PEAR::isError($r)) { - // return $r; - // } - // $token = $r['token']; - // return $token; - // } // fn accessFile - - - /** - * Release stored file - decrease access counter - * - * @param string $token - * access token - * @param string $sessid - * session id - * @return boolean - */ - // function releaseFile($token, $sessid='') - // { - // $r = BasicStor::bsRelease($token, 'access'); - // if (PEAR::isError($r)) { - // return $r; - // } - // return FALSE; - // } // fn releaseFile - - - /** - * Analyze media file for internal metadata information - * - * @param int $id - * Virtual file's local id - * @param string $sessid - * Session id - * @return array - */ - // public function analyzeFile($id, $sessid='') - // { - // if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - // return $res; - // } - // return $this->bsAnalyzeFile($id); - // } - - - /** - * Rename file - * - * @param int $id - * Virtual file's local id - * @param string $newName - * @param string $sessid - * Session id - * @return boolean|PEAR_Error - */ - // public function renameFile($id, $newName, $sessid='') - // { - // if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - // return $res; - // } - // return $this->bsRenameFile($id, $newName); - // } - - - /** - * Replace file. Doesn't change filetype! - * - * @param int $id - * virt.file's local id - * @param string $mediaFileLP - * local path of media file - * @param string $mdataFileLP - * local path of metadata file - * @param string $sessid - * session id - * @return TRUE|PEAR_Error - */ - // public function replaceFile($id, $mediaFileLP, $mdataFileLP, $sessid='') - // { - // if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - // return $res; - // } - // return $this->bsReplaceFile($id, $mediaFileLP, $mdataFileLP); - // } - - - /** - * Delete file - * - * @param int $id - * local id - * @param int $sessid - * @param boolean $forced - * if true don't use trash -- now ignored - * @return true|PEAR_Error - */ - public function deleteFile($id, $sessid='', $forced=FALSE) - { - if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::Recall($id); - return $f->delete(true); - } - - - /* ------------------------------------------------------------- metadata */ - - /** - * Replace metadata with new XML file or string - * - * @param int $id - * Virtual file's local id - * @param string $mdata - * XML string or local path of metadata XML file - * @param string $mdataLoc - * metadata location: 'file'|'string' - * @param string $sessid - * session id - * @return boolean|PEAR_Error - */ - // public function replaceMetadata($id, $mdata, $mdataLoc='file', $sessid='') - // { - // if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - // return $res; - // } - // return $this->bsReplaceMetadata($id, $mdata, $mdataLoc); - // } // fn replaceMetadata - - - /** - * Get metadata XML tree as string - * - * @param int $id - * Virtual file's local id - * @param string $sessid - * session id - * @return string|PEAR_Error - * @todo rename this function to "getMetadata" - */ - public function getMetadata($id, $sessid='') - { - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::Recall($id); - return $f->getMetadata(); - } - - - /** - * Return metadata as hierarchical PHP hash-array - * - * If xml:lang attribute is specified in metadata category, - * array of metadata values indexed by xml:lang values - * is presented instead of one plain metadata value. - * - * @param int $id - * local object id - * @param string $sessid - * session ID - * @return array - */ - public function getMetadataArray($id, $sessid) - { - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $storedFile = StoredFile::Recall($id); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - return $storedFile->md; - - // $arr = $storedFile->md->genPhpArray(); - $md = FALSE; - foreach ($arr['children'] as $i=>$a) { - if ($a['elementname'] == 'metadata'){ - $md = $arr['children'][$i]; - break; - } - } - if ($md === FALSE) { - return PEAR::raiseError( - "GreenBox::getMetadataArray: no metadata container found" - ); - } - $res = array(); - foreach ($md['children'] as $el) { - $lang = isset($el['attrs']['xml:lang']) ? $el['attrs']['xml:lang'] : ""; - $category = $el['elementname']; - if ($lang == "") { - $res[$category] = $el['content']; - } else { - $res[$category][$lang] = $el['content']; - } - } - return $res; - } - - - /** - * Get metadata element value - * - * @param int $id - * Virtual file's local id - * @param string $category - * metadata element name - * @param string $sessid - * session id - * @param string $lang - * xml:lang value for select language version - * @param string $deflang - * xml:lang for default language - * @return array of matching records as hash with fields: - *
    - *
  • mid int, local metadata record id
  • - *
  • value string, element value
  • - *
  • attrs hasharray of element's attributes indexed by - * qualified name (e.g. xml:lang)
  • - *
- */ - public function getMetadataValue($id, $category, $sessid='', - $lang=NULL, $deflang=NULL) - { - if (!is_numeric($id)) { - return null; - } - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::Recall($id); - return $f->getMetadataValue($category); - } - - - /** - * Set metadata element value - * - * @param int $id - * Virtual file's local id - * @param string $category - * Metadata element identification (e.g. dc:title) - * @param string $sessid - * Session id - * @param string $value - * The value to store, if NULL then delete record - * @return boolean - */ - public function setMetadataValue($id, $category, $sessid, $value) - { - if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::Recall($id); - return $f->setMetadataValue($category, $value); - } // fn setMetadataValue - - - /** - * Search in local metadata database. - * - * @param array $criteria - * with following structure:
- *
    - *
  • filetype - string, type of searched files, - * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'
  • - *
  • operator - string, type of conditions join - * (any condition matches / all conditions match), - * meaningful values: 'and', 'or', '' - * (may be empty or ommited only with less then 2 items in - * "conditions" field) - *
  • - *
  • limit : int - limit for result arrays (0 means unlimited)
  • - *
  • offset : int - starting point (0 means without offset)
  • - *
  • orderby : string - metadata category for sorting (optional) - * or array of strings for multicolumn orderby - * [default: dc:creator, dc:source, dc:title] - *
  • - *
  • desc : boolean - flag for descending order (optional) - * or array of boolean for multicolumn orderby - * (it corresponds to elements of orderby field) - * [default: all ascending] - *
  • - *
  • conditions - array of hashes with structure: - *
      - *
    • cat - string, metadata category name
    • - *
    • op - string, operator - meaningful values: - * 'full', 'partial', 'prefix', '=', '<', - * '<=', '>', '>='
    • - *
    • val - string, search value
    • - *
    - *
  • - *
- * @param string $sessid - * session id - * @return array of hashes, fields: - *
    - *
  • cnt : integer - number of matching gunids - * of files have been found
  • - *
  • results : array of hashes: - *
      - *
    • gunid: string
    • - *
    • type: string - audioclip | playlist | webstream
    • - *
    • title: string - dc:title from metadata
    • - *
    • creator: string - dc:creator from metadata
    • - *
    • length: string - dcterms:extent in extent format
    • - *
    - *
  • - *
- * @see BasicStor::bsLocalSearch - */ - public function localSearch($criteria, $sessid='') - { - $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0); - $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0); - return $this->bsLocalSearch($criteria, $limit, $offset); - } // fn localSearch - - - /** - * Return values of specified metadata category - * - * @param string $category - * metadata category name - * with or without namespace prefix (dc:title, author) - * @param array $criteria - * see localSearch method - * @param string $sessid - * @return array, fields: - * results : array with found values - * cnt : integer - number of matching values - * @see BasicStor::bsBrowseCategory - */ - public function browseCategory($category, $criteria = null, $sessid = '') - { - $limit = 0; - $offset = 0; - if (!is_null($criteria)) { - $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0); - $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0); - } - $res = $this->bsBrowseCategory($category, $limit, $offset, $criteria); - return $res; - } // fn browseCategory - - - /*====================================================== playlist methods */ - /** - * Create a new empty playlist. - * - * @param string $fname - * human readable menmonic file name - * @param string $sessid - * session ID - * @return int - * local id of created playlist - */ - public function createPlaylist($fname, $sessid='') - { - $pl = new Playlist(); - $pl = $pl->create($fname); - - return $pl; - } // fn createPlaylist - - public function setPLMetadataValue($id, $category, $value, $lang=NULL, $mid=NULL) - { - $pl = Playlist::Recall($id); - - if($pl === FALSE) - return FALSE; - - $res = $pl->setPLMetaData($category, $value, $lang); - - return $res; - } - - public function getPLMetadataValue($id, $category, $langId=NULL) - { - $pl = Playlist::Recall($id); - - if($pl === FALSE) - return FALSE; - - $res = $pl->getPLMetaData($category); - - return $res; - } - - /** - * Return playlist as XML string - * - * @param int $id - * local object id - * @param string $sessid - * session ID - * @return string - * XML - */ - // function getPlaylistXml($id, $sessid) - // { - // return $this->getMetadata($id, $sessid); - // } // fn getPlaylistXml - - - /** - * Return playlist as hierarchical PHP hash-array - * - * @param int $id - * local object id - * @param string $sessid - * session ID - * @return array - */ - public function getPlaylistArray($id) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->getContents(); - - if(is_null($res)) - return array(); - - return $res; - } // fn getPlaylistArray - - - /** - * Mark playlist as edited and return edit token - * - * @param int $id - * local object id - * @param string $sessid - * session ID - * @return string - * playlist access token - */ - public function lockPlaylistForEdit($id, $sessid) { - $pl = Playlist::Recall($id); - - if($pl === FALSE) - return; - - $res = $pl->lock($sessid); - - return $res; - } - - - /** - * clear edit flag. - * - * @param string $sessid - * session ID - * @return string gunid - */ - public function releaseLockedPlaylist($id, $sessid) { - $pl = Playlist::Recall($id); - - if($pl === FALSE) - return FALSE; - - $res = $pl->unlock($sessid); - return $res; - } - - - /** - * Add audioclip specified by local id to the playlist - * - * @param string $token - * playlist access token - * @param string $acId - * local ID of added file - * @param string $sessid - * session ID - * @param string $fadeIn - * in time format hh:mm:ss.ssssss - * @param string $fadeOut - * in time format hh:mm:ss.ssssss - * @param string $length - * length in extent format - - * for webstream (or for overrule length of audioclip) - * @param string $clipstart - * optional clipstart time format hh:mm:ss.ssssss - relative to begin - * @param string $clipend - * optional $clipend time format hh:mm:ss.ssssss - relative to begin - * @return boolean, true if added. - */ - public function addAudioClipToPlaylist($id, $acId, $pos=NULL, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cueIn=NULL, $cueOut=NULL) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->addAudioClip($acId, $pos, $fadeIn, $fadeOut, $cliplength, $cueIn, $cueOut); - - return $res; - } // fn addAudioClipToPlaylist - - - /** - * Remove audioclip from playlist - * - * @param string $id - * playlist id - * @param int $pos - * position of element in playlist to delete. - * @return boolean, true if deleted. - * @todo rename this function to "deleteAudioClipFromPlaylist" - */ - public function delAudioClipFromPlaylist($id, $pos) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->delAudioClip($pos); - if($res === FALSE) - return FALSE; - - return TRUE; - } - - /** - * Move audioClip to the new position in the playlist. - * - * This method may change id attributes of playlistElements and/or - * fadeInfo. - * - * @param string $id - * playlist id - * @param id $oldPos - * old position in playlist - * @param int $newPos - * new position in playlist - * @return boolean - */ - public function moveAudioClipInPlaylist($id, $oldPos, $newPos) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->moveAudioClip($oldPos, $newPos); - - return $res; - } - - /** - * Change fadeInfo values - * - * @param string $id - * playlist id - * @param string $fadeIn - * in time format hh:mm:ss.ssssss - * @param string $fadeOut - * in time format hh:mm:ss.ssssss - * @return boolean - */ - public function changeFadeInfo($id, $pos, $fadeIn, $fadeOut) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->changeFadeInfo($pos, $fadeIn, $fadeOut); - - return $res; - } - - /** - * Change cueIn/cueOut values for playlist element - * - * @param string $id - * playlist id - * @param string $cueIn - * in time format hh:mm:ss.ssssss - * @param string $cueOut - * in time format hh:mm:ss.ssssss - * relative to begin - * @param sessid $string - * session ID - * @return boolean or pear error object - */ - public function changeClipLength($id, $pos, $cueIn, $cueOut) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->changeClipLength($pos, $cueIn, $cueOut); - - return $res; - } - - /** - * Delete a Playlist metafile. - * - * @param int $id - * local id - * @param string $sessid - * session ID - * @return boolean - */ - public function deletePlaylist($id) - { - return Playlist::Delete($id); - - } - - /** - * Find info about clip at specified offset in playlist. - * - * @param string $sessid - * session id - * @param string $plid - * playlist global unique id - * @param string $offset - * current playtime (hh:mm:ss.ssssss) - * @param int $distance - * 0=current clip; 1=next clip ... - * @return array of matching clip info: - *
    - *
  • gunid string, global unique id of clip
  • - *
  • elapsed string, already played time of clip
  • - *
  • remaining string, remaining time of clip
  • - *
  • duration string, total playlength of clip
  • - *
- */ - public function displayPlaylistClipAtOffset($sessid, $plid, $offset, $distance=0) - { - $pl = Playlist::Recall($plid); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - $res = $pl->displayPlaylistClipAtOffset($offset, $distance); - if (PEAR::isError($res)) { - return $res; - } - $res['title'] = NULL; - $f = StoredFile::RecallByGunid($res['gunid']); - if (PEAR::isError($f)) { - return $f; - } - $res['title'] = $f->getMetadataValue("dc:title"); - $res['playlist_title'] = NULL; - $pl = Playlist::Recall($plid); - $res['playlist'] = $pl->getName(); - - return $res; - } - - - /** - * Create a tarfile with playlist export - playlist and all matching - * sub-playlists and media files (if desired) - * - * @param string $sessid - * string, session ID - * @param array $plids - * array of strings, playlist global unique IDs - * (one gunid is accepted too) - * @param string $type - * playlist format, values: lspl | smil | m3u - * @param boolean $standalone - * if only playlist should be exported or - * with all related files - * @return hasharray with fields: - * fname string: readable fname, - * token string: access token - */ - public function exportPlaylistOpen($sessid, $plids, $type='lspl', $standalone=FALSE) - { - return $this->bsExportPlaylistOpen($plids, $type, !$standalone); - } // fn exportPlaylistOpen - - - /** - * Close playlist export previously opened by the exportPlaylistOpen method - * - * @param string $token - * access token obtained from exportPlaylistOpen - * method call - * @return TRUE|PEAR_Error - */ - public function exportPlaylistClose($token) - { - return $this->bsExportPlaylistClose($token); - } // fn exportPlaylistClose - - - /** - * Open writable handle for import playlist in LS Archive format - * - * @param string $sessid - * session id - * @param string $chsum - * md5 checksum of imported file - * @return hasharray with: - * fname string: writable local filename - * token string: put token - */ - public function importPlaylistOpen($sessid, $chsum='') - { - $userid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($userid)) { - return $userid; - } - $r = $this->bsOpenPut($chsum, NULL, $userid); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } // fn importPlaylistOpen - - - /** - * Close import-handle and import playlist - * - * @param string $token - * import token obtained by importPlaylistOpen method - * @return int - * result file local id (or error object) - */ - public function importPlaylistClose($token) - { - $arr = $this->bsClosePut($token); - if (PEAR::isError($arr)) { - return $arr; - } - $fname = $arr['fname']; - $owner = $arr['owner']; - $res = $this->bsImportPlaylist($fname, $owner); - if (file_exists($fname)) { - @unlink($fname); - } - return $res; - } // fn importPlaylistClose - - - /** - * Check whether a Playlist metafile with the given playlist ID exists. - * - * @param int $id - * local id - * @param string $sessid - * session ID - * @return boolean - */ - public function existsPlaylist($id) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - return TRUE; - } // fn existsPlaylist - - - /** - * Check whether a Playlist metafile with the given playlist ID - * is available for editing, i.e., exists and is not marked as - * beeing edited. - * - * @param int $id - * local id - * @param string $sessid - * session ID - * @return TRUE|int - * id of user editing it - */ - public function playlistIsAvailable($id, $sessid) - { - $pl = Playlist::Recall($id); - if ($pl === FALSE) { - return FALSE; - } - - $res = $pl->isEdited(); - - if($res !== FALSE) - return $res; - - return TRUE; - } // fn playlistIsAvailable - - - /* ---------------------------------------------- time conversion methods */ - /** - * Convert playlist time value to float seconds - * - * @param string $plt - * playlist time value (HH:mm:ss.dddddd) - * @return int - * seconds - */ - public function playlistTimeToSeconds($plt) - { - return Playlist::playlistTimeToSeconds($plt); - } - - - /** - * Convert float seconds value to playlist time format - * - * @param int $s0 - * seconds - * @return string - * time in playlist time format (HH:mm:ss.dddddd) - */ - public static function secondsToPlaylistTime($s0) - { - return Playlist::secondsToPlaylistTime($s0); - } // fn secondsToPlaylistTime - - - /* ------------------------------------------------------- render methods */ - /** - * Render playlist to ogg file (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return string $token - * render token - */ - public function renderPlaylistToFileOpen($sessid, $plid) - { - $r = Renderer::rnRender2FileOpen($this, $plid); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } // fn renderPlaylistToFileOpen - - - /** - * Render playlist to ogg file (check results) - * - * @param string $token - * render token - * @return hasharray: - * status : string - susccess | working | fault - * tmpfile : string - filepath to result temporary file - */ - public function renderPlaylistToFileCheck($token) - { - $r = Renderer::rnRender2FileCheck($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return array('status'=>$r['status'], 'tmpfile'=>$r['tmpfile']); - } // fn renderPlaylistToFileCheck - - - /** - * Render playlist to ogg file (list results) - * - * @param string $status - * success | working | fault - * if this parameter is not set, then return with all unclosed - * @return array of hasharray: - * status : string - susccess | working | fault - * tmpfile : string - filepath to result temporary file - */ - public function renderPlaylistToFileList($status='') - { - return Renderer::rnRender2FileList($this, $status); - } // fn renderPlaylistToFileList - - - /** - * Render playlist to ogg file (close handle) - * - * @param string $token - * render token - * @return boolean - * status - */ - public function renderPlaylistToFileClose($token) - { - $r = Renderer::rnRender2FileClose($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return array(TRUE); - } // fn renderPlaylistToFileClose - - - /** - * Render playlist to storage media clip (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return string - * render token - */ - public function renderPlaylistToStorageOpen($sessid, $plid) - { - $owner = GreenBox::getSessUserId($sessid); - if (PEAR::isError($owner)) { - return $owner; - } - $r = Renderer::rnRender2FileOpen($this, $plid, $owner); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } // fn renderPlaylistToStorageOpen - - - /** - * Render playlist to storage media clip (check results) - * - * @param string $token - * render token - * @return hasharray: - * status : string - susccess | working | fault - * gunid : string - gunid of result file - */ - public function renderPlaylistToStorageCheck($token) - { - $r = Renderer::rnRender2StorageCheck($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } // fn renderPlaylistToStorageCheck - - - /** - * Render playlist to RSS file (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return string - * render token - */ - public function renderPlaylistToRSSOpen($sessid, $plid) - { - $token = '123456789abcdeff'; - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - file_put_contents($fakeFile, "fake rendered file"); - return array('token'=>$token); - } // fn renderPlaylistToRSSOpen - - - /** - * Render playlist to RSS file (check results) - * - * @param string $token - * render token - * @return hasharray: - * status : string - susccess | working | fault - * tmpfile : string - filepath to result temporary file - */ - public function renderPlaylistToRSSCheck($token) - { - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - if ($token != '123456789abcdeff' || !file_exists($fakeFile)){ - return PEAR::raiseError( - "renderPlaylistToRSSCheck: invalid token ($token)" - ); - } - return array( - 'status'=> 'success', - 'tmpfile' => $fakeFile, - ); - } // fn renderPlaylistToRSSCheck - - - /** - * Render playlist to RSS file (list results) - * - * @param string $status - * success | working | fault - * @return array of hasharray: - * status : string - susccess | working | fault - * tmpfile : string - filepath to result temporary file - */ - // function renderPlaylistToRSSList($status='') - // { - // $dummytokens = array ('123456789abcdeff'); - // foreach ($dummytokens as $token) { - // $r[] = $this->renderPlaylistToRSSCheck($token); - // } - // return $r; - // } // fn renderPlaylistToRSSList - - - /** - * Render playlist to RSS file (close handle) - * - * @param string $token - * render token - * @return boolean - * status - */ - public function renderPlaylistToRSSClose($token) - { - if ($token != '123456789abcdeff'){ - return PEAR::raiseError( - "GreenBox::renderPlaylistToRSSClose: invalid token" - ); - } - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - unlink($fakeFile); - return TRUE; - } // fn renderPlaylistToRSSClose - - - /*================================================= storage admin methods */ - /* ------------------------------------------------------- backup methods */ - /** - * Create backup of storage (open handle) - * - * @param string $sessid - * session id - * @param struct $criteria - * see search criteria - * @return array - * token : string - backup token - */ - public function createBackupOpen($sessid, $criteria='') - { - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->openBackup($sessid,$criteria); - } // fn createBackupOpen - - - /** - * Create backup of storage (check results) - * - * @param string $token - * backup token - * @return hasharray with field: - * status : string - susccess | working | fault - * faultString: string - description of fault - * token : stirng - backup token - * url : string - access url - */ - public function createBackupCheck($token) - { - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->checkBackup($token); - } // fn createBackupCheck - - - /** - * Create backup of storage (list results) - * - * @param string $sessid - * session id - * @param string $stat - * if this parameter is not set, then return with all unclosed backups - * @return array of hasharray with field: - * status : string - susccess | working | fault - * token : stirng - backup token - * url : string - access url - */ - public function createBackupList($sessid, $stat='') - { - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->listBackups($stat); - } // fn createBackupList - - - /** - * Create backup of storage (close handle) - * - * @param string $token - * backup token - * @return boolean - * status - */ - public function createBackupClose($token) - { - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->closeBackup($token); - } // fn createBackupClose - - - /* ===================================================== restore funcitons*/ - /** - * Restore a backup file - * - * @param string $sessid - * session id - * @param string $filename - * backup file path - * @return string - * restore token - */ - public function backupRestoreOpen($sessid, $filename) - { - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->openRestore($sessid,$filename); - } // fn backupRestoreOpen - - - /** - * Check status of backup restore - * - * @param string $token - * restore token - * @return hasharray - * fields: - * token: string - restore token - * status: string - working | fault | success - * faultString: string - description of fault - */ - public function backupRestoreCheck($token) - { - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->checkRestore($token); - } // fn backupRestoreCheck - - - /** - * Close a restore procedure - * - * @param string $token - * restore token - * @return boolean - * is success - */ - public function backupRestoreClose($token) { - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->closeRestore($token); - } // fn backupRestoreClose - - /* ============================================== methods for preferences */ - - /** - * Read preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @return string - * preference value - */ - public function loadPref($sessid, $key) - { - $pr = new Prefs($this); - $res = $pr->loadPref($sessid, $key); - return $res; - } // fn loadPref - - - /** - * Save preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @param string $value - * preference value - * @return boolean - */ - public function savePref($sessid, $key, $value) - { - $pr = new Prefs($this); - $res = $pr->savePref($sessid, $key, $value); - return $res; - } // fn savePref - - - /** - * Delete preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @return boolean - */ - public function delPref($sessid, $key) - { - $pr = new Prefs($this); - $res = $pr->delPref($sessid, $key); - return $res; - } // fn delPref - - - /** - * Read group preference record - * - * @param string $sessid - * session id - * @param string $group - * group name - * @param string $key - * preference key - * @return string - * preference value - */ - public function loadGroupPref($group, $key) - { - $pr = new Prefs($this); - $res = $pr->loadGroupPref($group, $key); - return $res; - } // fn loadGroupPref - - - /** - * Save group preference record - * - * @param string $sessid - * session id - * @param string $group - * group name - * @param string $key - * preference key - * @param string $value - * preference value - * @return boolean - */ - public function saveGroupPref($sessid, $group, $key, $value) - { - $pr = new Prefs($this); - $res = $pr->saveGroupPref($sessid, $group, $key, $value); - return $res; - } // fn saveGroupPref - - - /** - * Delete group preference record - * - * @param string $sessid - * session id - * @param string $group - * group name - * @param string $key - * preference key - * @return boolean - */ - public function delGroupPref($sessid, $group, $key) - { - $pr = new Prefs($this); - $res = $pr->delGroupPref($sessid, $group, $key); - return $res; - } // fn delGroupPref - - - /* =================================================== networking methods */ - /* ------------------------------------------------------- common methods */ - /** - * Common "check" method for transports - * - * @param string $trtok - * transport token - * @return array with fields: - * trtype: string - audioclip | playlist | search | file - * state: string - transport state - * direction: string - up | down - * expectedsize: int - file size in bytes - * realsize: int - currently transported bytes - * expectedchsum: string - orginal file checksum - * realchsum: string - transported file checksum - * ... ? - */ - public function getTransportInfo($trtok) - { - $tr = new Transport($this); - return $tr->getTransportInfo($trtok); - } // fn getTransportInfo - - - /** - * Turn transports on/off, optionaly return current state. - * - * @param string $sessid - * session id - * @param boolean $onOff - * optional (if not used, current state is returned) - * @return boolean - * previous state - */ - public function turnOnOffTransports($sessid, $onOff=NULL) - { - $tr = new Transport($this); - return $tr->turnOnOffTransports($sessid, $onOff); - } // fn turnOnOffTransports - - - /** - * Pause, resume or cancel transport - * - * @param string $trtok - * transport token - * @param string $action - * pause | resume | cancel - * @return string - * resulting transport state - */ - public function doTransportAction($trtok, $action) - { - $tr = new Transport($this); - $res = $tr->doTransportAction($trtok, $action); - return $res; - } // fn doTransportAction - - - /* ------------------------ methods for ls-archive-format file transports */ - /** - * Open async file transfer from local storageServer to network hub, - * file should be ls-archive-format file. - * - * @param string $filePath - * local path to uploaded file - * @return string - * transport token - */ - public function uploadFile2Hub($filePath) - { - $tr = new Transport($this); - return $tr->uploadFile2Hub($filePath); - } // fn uploadFile2Hub - - - /** - * Get list of prepared transfers initiated by hub - * - * @return array of structs/hasharrays with fields: - * trtok: string transport token - * ... ? - */ - public function getHubInitiatedTransfers() - { - $tr = new Transport($this); - return $tr->getHubInitiatedTransfers(); - } // fn getHubInitiatedTransfers - - - /** - * Start of download initiated by hub - * - * @param string $trtok - * transport token obtained from - * the getHubInitiatedTransfers method - * @return string - * transport token - */ - public function startHubInitiatedTransfer($trtok) - { - $tr = new Transport($this); - return $tr->startHubInitiatedTransfer($trtok); - } // fn startHubInitiatedTransfer - - - /* ------------- special methods for audioClip/webstream object transport */ - - /** - * Start upload of audioClip/webstream/playlist from local storageServer - * to hub - * - * @param string $gunid - * global unique id of object being transported - * @param boolean $withContent - * if true, transport playlist content too - * @return string - * transport token - * @todo rename this function "uploadToHub" - */ - public function upload2Hub($gunid, $withContent=FALSE) - { - $tr = new Transport($this); - return $tr->upload2Hub($gunid, $withContent); - } // fn upload2Hub - - - /** - * Start download of audioClip/webstream/playlist from hub to local - * storageServer - * - * @param string $sessid - * session id - * @param string $gunid - * global unique id of playlist being transported - * @param boolean $withContent - * if true, transport playlist content too - * @return string - * transport token - */ - public function downloadFromHub($sessid, $gunid, $withContent=TRUE){ - $uid = GreenBox::getSessUserId($sessid); - if (PEAR::isError($uid)) { - return $uid; - } - $tr = new Transport($this); - return $tr->downloadFromHub($uid, $gunid, $withContent); - } // fn downloadFromHub - - - /* ------------------------------------------------ global-search methods */ - /** - * Start search job on network hub - * - * @param array $criteria - * criteria format (see localSearch) - * @return string - * transport token - */ - public function globalSearch($criteria) - { - $tr = new Transport($this); - //return $tr->globalSearch($criteria); - return $tr->remoteSearch($criteria); - } - - - /** - * Get results from search job on network hub - * - * @param string $trtok - * transport token - * @param boolean $andClose - * if TRUE, close transport token - * @return array - * search result format (see localSearch) - */ - // public function getSearchResults($trtok, $andClose=TRUE) - // { - // $tr = new Transport($this); - // return $tr->getSearchResults($trtok, $andClose); - // } // fn getSearchResults - - - /* ========================================================= info methods */ - /** - * Check if file gunid exists in the storage and - * user have permission to read it - * - * @param string $sessid - * session id - * @param string $gunid - * @param string $ftype - * internal file type - * @return string|PEAR_Error - */ - public function existsFile($sessid, $gunid, $ftype=NULL) - { - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::RecallByGunid($gunid); - return $f->existsFile(); - } // fn existsFile - - - /* ==================================================== redefined methods */ - /** - * Get user id from session id - * - * This redefinition only simulate old (bad) behaviour - returns NULL - * for wrong sessid (code ALIBERR_NOTEXISTS). - * HtmlUI depends on it. - * - * @param string $sessid - * @return int|null|PEAR_Error - */ - public static function GetSessUserId($sessid) - { - $r = Alib::GetSessUserId($sessid); - if (PEAR::isError($r)) { - if ($r->getCode() == ALIBERR_NOTEXISTS) { - return NULL; - } else { - return $r; - } - } - return $r; - } // fn getSessUserId - - - /** - * Change user password. - * - * ('superuser mode'= superuser is changing some password without - * knowledge of the old password) - * - * @param string $login - * @param string $oldpass - * old password - * (should be null or empty for 'superuser mode') - * @param string $pass - * @param string $sessid - * session id, required for 'superuser mode' - * @return boolean/err - */ - public function passwd($login, $oldpass=null, $pass='', $sessid='') - { - if (is_null($oldpass) || ($oldpass == '') ) { - if (($res = BasicStor::Authorize('subjects', $this->rootId, $sessid)) !== TRUE) { - sleep(2); - return $res; - } else { - $oldpass = null; - } - } else { - if (FALSE === Subjects::Authenticate($login, $oldpass)) { - sleep(2); - return PEAR::raiseError( - "GreenBox::passwd: access denied (oldpass)", GBERR_DENY); - } - } - $res = Subjects::Passwd($login, $oldpass, $pass); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } // fn passwd - - - /** - * Insert permission record - * - * @param int $sid - * local user/group id - * @param string $action - * @param int $oid - * local object id - * @param char $type - * 'A'|'D' (allow/deny) - * @param string $sessid - * session id - * @return int - * local permission id - */ - public function addPerm($sid, $action, $oid, $type='A', $sessid='') - { - if (($res = BasicStor::Authorize('editPerms', $oid, $sessid)) !== TRUE) { - return $res; - } - return Alib::AddPerm($sid, $action, $oid, $type); - } // fn addPerm - - - /** - * Remove permission record - * - * @param int $permid - * local permission id - * @param int $subj - * local user/group id - * @param int $obj - * local object id - * @param string $sessid - * session id - * @return boolean/error - */ - public function removePerm($permid=NULL, $subj=NULL, $obj=NULL, $sessid='') - { - if (!is_null($permid)) { - $oid = Alib::GetPermOid($permid); - if (PEAR::isError($oid)) { - return $oid; - } - if (!is_null($oid)) { - if (($res = BasicStor::Authorize('editPerms', $oid, $sessid)) !== TRUE) { - return $res; - } - } - } - $res = Alib::RemovePerm($permid, $subj, $obj); - return $res; - } // fn removePerm - - } // class GreenBox - ?> \ No newline at end of file diff --git a/backend/LocStor.php b/backend/LocStor.php deleted file mode 100644 index fa0956f3b..000000000 --- a/backend/LocStor.php +++ /dev/null @@ -1,1749 +0,0 @@ -"; -} -require_once("BasicStor.php"); -if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) { - echo __FILE__.':line '.__LINE__.": Loaded BasicStor
"; -} -require_once("Transport.php"); -if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) { - echo __FILE__.':line '.__LINE__.": Loaded Transport
"; -} - -/** - * LocStor class - * - * Local storage interface - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class LocStor extends BasicStor { - - /* ---------------------------------------------------------------- store */ - - /** - * Store or replace existing audio clip. - * - * Sending a file to the storage server is a 3 step process: - * 1) Call storeAudioClipOpen - * 2) Upload the file to the URL specified - * 3) Call storeAudioClipClose - * - * @param string $sessid - * session id - * @param string $gunid - * global unique id - * @param string $metadata - * metadata XML string - * @param string $fname - * human readable menmonic file name - * with extension corresponding to filetype - * @param string $chsum - * md5 checksum of media file - * @param string $ftype - * audioclip | playlist | webstream - * @return array - * {url:writable URL for HTTP PUT, token:access token} - */ - protected function storeAudioClipOpen($sessid, $gunid, $metadata, - $fname, $chsum, $ftype='audioclip') - { - // Check the gunid format - if (!BasicStor::CheckGunid($gunid)) { - return PEAR::raiseError( - "LocStor::storeAudioClipOpen: Wrong gunid ($gunid)" - ); - } - - // Check if we already have this file. - $duplicate = StoredFile::RecallByMd5($chsum); - if (!empty($chsum) && $duplicate) { - return PEAR::raiseError( - "LocStor::storeAudioClipOpen: Duplicate file" - ." - Matched MD5 ($chsum) against '".$duplicate->getName()."'", - 888); - } - - // Check if specified gunid exists. - $storedFile =& StoredFile::RecallByGunid($gunid); - if (!is_null($storedFile) && !PEAR::isError($storedFile)) { - // gunid exists - do replace - $oid = $storedFile->getId(); - if (($res = BasicStor::Authorize('write', $oid, $sessid)) !== TRUE) { - return $res; - } - if ($storedFile->isAccessed()) { - return PEAR::raiseError( - 'LocStor::storeAudioClipOpen: is accessed' - ); - } - $res = $storedFile->replace($oid, $storedFile->getName(), '', $metadata, 'string'); - if (PEAR::isError($res)) { - return $res; - } - } else { - // gunid doesn't exist - do insert: - $tmpFname = uniqid(); - if (($res = BasicStor::Authorize('write', null, $sessid)) !== TRUE) { - return $res; - } - $values = array( - "metadata" => $metadata, - "gunid" => $gunid, - "filetype" => $ftype); - $storedFile =& StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - if (PEAR::isError($res)) { - return $res; - } - } - $res = $storedFile->setState('incomplete'); - if (PEAR::isError($res)) { - return $res; - } - if ($fname == '') { - $fname = "newFile"; - } - $storedFile->setName($fname); - return $this->bsOpenPut($chsum, $storedFile->gunid); - } - - - /** - * Store or replace existing audio clip - * - * @param string $sessid - * @param string $token - * @return string gunid|PEAR_Error - */ - protected function storeAudioClipClose($sessid, $token) - { - $storedFile =& StoredFile::RecallByToken($token); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - $arr = $this->bsClosePut($token); - if (PEAR::isError($arr)) { - $storedFile->delete(); - return $arr; - } - $fname = $arr['fname']; - $res = $storedFile->setRawMediaData($fname); - if (PEAR::isError($res)) { - return $res; - } - if (file_exists($fname)) { - @unlink($fname); - } - $res = $storedFile->setState('ready'); - if (PEAR::isError($res)) { - return $res; - } - return $storedFile->gunid; - } - - - /** - * Check uploaded file - * - * @param string $token - * "put" token - * @return array - * hash, (status: boolean, size: int - filesize) - */ - protected function uploadCheck($token) - { - return $this->bsCheckPut($token); - } - - - /** - * Store webstream - * - * @param string $sessid - * session id - * @param string $gunid - * global unique id - * @param string $metadata - * metadata XML string - * @param string $fname - * human readable menmonic file name with extension corresponding to filetype - * @param string $url - * webstream url - * @return string - * gunid - */ - protected function storeWebstream($sessid, $gunid, $metadata, $fname, $url) - { - $a = $this->storeAudioClipOpen( - $sessid, $gunid, $metadata, $fname, md5(''), 'webstream'); - if (PEAR::isError($a)) { - return $a; - } - $gunid = $this->storeAudioClipClose($sessid, $a['token']); - if (PEAR::isError($gunid)) { - return $gunid; - } - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - $r = $storedFile->setMetadataValue('ls:url', $url); - if (PEAR::isError($r)) { - return $r; - } - return $gunid; - } - - - /* --------------------------------------------------------------- access */ - /** - * Make access to audio clip - * - * @param string $sessid - * @param string $gunid - * @param int $parent - * parent token - * @return array - * with: seekable filehandle, access token - */ - public function accessRawAudioData($sessid, $gunid, $parent='0') - { - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - if (($res = BasicStor::Authorize('read', $storedFile->getId(), $sessid)) !== TRUE) { - return $res; - } - return $storedFile->accessRawMediaData($parent); - } - - - /** - * Release access to audio clip - * - * @param string $sessid - * @param string $token - * access token - * @return boolean|PEAR_Error - */ - public function releaseRawAudioData($sessid, $token) - { - $storedFile =& StoredFile::RecallByToken($token); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - return $storedFile->releaseRawMediaData($token); - } - - - /* ------------------------------------------------------------- download */ - /** - * Create and return downloadable URL for audio file - * - * @param string $sessid - * session id - * @param string $gunid - * global unique id - * @return array - * array with strings: - * downloadable URL, download token, chsum, size, filename - */ - protected function downloadRawAudioDataOpen($sessid, $gunid) - { - $ex = $this->existsAudioClip($sessid, $gunid); - if (PEAR::isError($ex)) { - return $ex; - } - $media = StoredFile::RecallByGunid($gunid); - $id = $media->getId(); - if (is_null($id) || !$ex) { - return PEAR::raiseError( - "LocStor::downloadRawAudioDataOpen: gunid not found ($gunid)", - GBERR_NOTF - ); - } - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - return $this->bsOpenDownload($id); - } - - - /** - * Discard downloadable URL for audio file - * - * @param string $token - * download token - * @return string - * gunid - */ - protected function downloadRawAudioDataClose($token) - { - return $this->bsCloseDownload($token); - } - - - /** - * Create and return downloadable URL for metadata - * - * @param string $sessid - * session id - * @param string $gunid - * global unique id - * @return array - * array with strings: - * downloadable URL, download token, chsum, filename - */ - protected function downloadMetadataOpen($sessid, $gunid) - { - // $res = $this->existsAudioClip($sessid, $gunid); - // if(PEAR::isError($res)) return $res; - $media = StoredFile::RecallByGunid($gunid) - $id = $media->getGunid(); - if (is_null($id)) { - return PEAR::raiseError( - "LocStor::downloadMetadataOpen: gunid not found ($gunid)" - ); - } - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $res = $this->bsOpenDownload($id, 'metadata'); - #unset($res['filename']); - return $res; - } - - - /** - * Discard downloadable URL for metadata - * - * @param string $token - * download token - * @return string - * gunid - */ - protected function downloadMetadataClose($token) - { - return $this->bsCloseDownload($token, 'metadata'); - } - - - /** - * Return metadata as XML - * - * @param string $sessid - * @param string $gunid - * @return string|PEAR_Error - */ - protected function getAudioClip($sessid, $gunid) - { - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - if (($res = BasicStor::Authorize('read', $storedFile->getId(), $sessid)) !== TRUE) { - return $res; - } - $md = $storedFile->getMetadata(); - if (PEAR::isError($md)) { - return $md; - } - return $md; - } - - - /* ------------------------------------------------------- search, browse */ - - /** - * Search in metadata database - * - * @param string $sessid - * @param array $criteria - * with following structure:
- *
    - *
  • filetype - string, type of searched files, - * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'
  • - *
  • operator - string, type of conditions join - * (any condition matches / all conditions match), - * meaningful values: 'and', 'or', '' - * (may be empty or ommited only with less then 2 items in - * "conditions" field) - *
  • - *
  • limit : int - limit for result arrays (0 means unlimited)
  • - *
  • offset : int - starting point (0 means without offset)
  • - *
  • orderby : string - metadata category for sorting (optional) - * or array of strings for multicolumn orderby - * [default: dc:creator, dc:source, dc:title] - *
  • - *
  • desc : boolean - flag for descending order (optional) - * or array of boolean for multicolumn orderby - * (it corresponds to elements of orderby field) - * [default: all ascending] - *
  • - *
  • conditions - array of hashes with structure: - *
      - *
    • cat - string, metadata category name
    • - *
    • op - string, operator - meaningful values: - * 'full', 'partial', 'prefix', '=', '<', - * '<=', '>', '>='
    • - *
    • val - string, search value
    • - *
    - *
  • - *
- * @return array of hashes, fields: - *
    - *
  • cnt : integer - number of matching gunids - * of files have been found
  • - *
  • results : array of hashes: - *
      - *
    • gunid: string
    • - *
    • type: string - audioclip | playlist | webstream
    • - *
    • title: string - dc:title from metadata
    • - *
    • creator: string - dc:creator from metadata
    • - *
    • source: string - dc:source from metadata
    • - *
    • length: string - dcterms:extent in extent format
    • - *
    - *
  • - *
- * @see BasicStor::localSearch - */ - public function searchMetadata($sessid, $criteria) - { - if (($res = BasicStor::Authorize('read', $this->storId, $sessid)) !== TRUE) { - return $res; - } - $criteria['resultMode'] = 'xmlrpc'; - $res = $this->localSearch($criteria, $sessid); - return $res; - } - - - /** - * @param array $criteria - * @param mixed $sessid - * This variable isnt used. - * @return unknown - */ - public function localSearch($criteria, $sessid='') - { - $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0); - $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0); - $res = $this->bsLocalSearch($criteria, $limit, $offset); - return $res; - } - - - /** - * Return values of specified metadata category - * - * @param string $category - * metadata category name - * with or without namespace prefix (dc:title, author) - * @param hash $criteria - * see searchMetadata method - * @param string $sessid - * @return array - * hash, fields: - * results : array with found values - * cnt : integer - number of matching values - * @see BasicStor::bsBrowseCategory - */ - protected function browseCategory($category, $criteria=NULL, $sessid='') - { - $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0); - $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0); - $res = $this->bsBrowseCategory($category, $limit, $offset, $criteria); - return $res; - } - - - /* ----------------------------------------------------------------- etc. */ - /** - * Check if audio clip exists - * - * @param string $sessid - * @param string $gunid - * @return boolean - */ - protected function existsAudioClip($sessid, $gunid) - { - $ex = $this->existsFile($sessid, $gunid, 'audioclip'); - // webstreams are subset of audioclips - moved to BasicStor - // if($ex === FALSE ){ - // $ex = $this->existsFile($sessid, $gunid, 'webstream'); - // } - if ($ex === FALSE ) { - return FALSE; - } - if (PEAR::isError($ex)) { - return $ex; - } - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - return $storedFile->exists(); - } - - - /** - * Check if file exists in the storage - * - * @param string $sessid - * @param string $gunid - * @param string $ftype - * internal file type - * @return boolean - */ - protected function existsFile($sessid, $gunid, $ftype=NULL) - { - if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - return $res; - } - $f = StoredFile::RecallByGunid($gunid); - if (PEAR::isError($f)) { - return FALSE; - } - return $f->existsFile(); - } - - - /** - * Delete existing audio clip - * - * @param string $sessid - * @param string $gunid - * @param boolean $forced - * if true, don't use trash - * @return boolean|PEAR_Error - */ - protected function deleteAudioClip($sessid, $gunid, $forced=FALSE) - { - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile)) { - return TRUE; - } - if (PEAR::isError($storedFile)) { - if ($storedFile->getCode()==GBERR_FOBJNEX && $forced) { - return TRUE; - } - return $storedFile; - } - if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) { - return $res; - } - $res = $storedFile->delete(); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Update existing audio clip metadata - * - * @param string $sessid - * @param string $gunid - * @param string $metadata - * metadata XML string - * @return boolean|PEAR_Error - */ - protected function updateAudioClipMetadata($sessid, $gunid, $metadata) - { - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) { - return $res; - } - return $storedFile->setMetadata($metadata, 'string'); - } - - - /*====================================================== playlist methods */ - /** - * Create a new empty playlist. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @param string $fname - * human readable mnemonic file name - * @return string - * playlist global unique ID - */ - public function createPlaylist($sessid, $playlistId, $fname) - { - $ex = $this->existsPlaylist($sessid, $playlistId); - if (PEAR::isError($ex)) { - return $ex; - } - if ($ex) { - return PEAR::raiseError( - 'LocStor::createPlaylist: already exists' - ); - } - $tmpFname = uniqid(''); - if (($res = BasicStor::Authorize('write', null, $sessid)) !== TRUE) { - return $res; - } - $values = array( - "metadata" => dirname(__FILE__).'/emptyPlaylist.xml', - "gunid" => $playlistId, - "filetype" => "playlist"); - // This is all wrong now. - $storedFile = StoredFile::Insert($values); - if ($fname == '') { - $fname = "newFile.xml"; - } - $storedFile->setName($fname); - $storedFile->setState('ready'); - $storedFile->setMime('application/smil'); - return $storedFile->gunid; - } - - - /** - * Open a Playlist metafile for editing. - * Open readable URL and mark file as beeing edited. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @return struct - * {url:readable URL for HTTP GET, token:access token, chsum:checksum} - */ - public function editPlaylist($sessid, $playlistId) - { - $ex = $this->existsPlaylist($sessid, $playlistId); - if (PEAR::isError($ex)) { - return $ex; - } - if (!$ex) { - return PEAR::raiseError( - 'LocStor::editPlaylist: playlist not exists' - ); - } - if ($this->isEdited($playlistId) !== FALSE) { - return PEAR::raiseError( - 'LocStor::editPlaylist: playlist already edited' - ); - } - $storedFile =& StoredFile::RecallByGunid($playlistId); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - $id = $storedFile->getId(); - if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) { - return $res; - } - $res = $this->bsOpenDownload($id, 'metadata'); - if (PEAR::isError($res)) { - return $res; - } - $r = $this->setEditFlag($playlistId, TRUE, $sessid); - if (PEAR::isError($r)) { - return $r; - } - unset($res['filename']); - return $res; - } - - - /** - * Store a new Playlist metafile in place of the old one. - * - * @param string $sessid - * session ID - * @param string $playlistToken - * playlist access token - * @param string $newPlaylist - * new playlist as XML string - * @return string - * playlistId - */ - protected function savePlaylist($sessid, $playlistToken, $newPlaylist) - { - $playlistId = $this->bsCloseDownload($playlistToken, 'metadata'); - if (PEAR::isError($playlistId)) { - return $playlistId; - } - $storedFile =& StoredFile::RecallByGunid($playlistId); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - $res = $storedFile->setMetadata($newPlaylist, 'string', 'playlist'); - if (PEAR::isError($res)) { - return $res; - } - $r = $this->setEditFlag($playlistId, FALSE, $sessid); - if (PEAR::isError($r)) { - return $r; - } - return $playlistId; - } - - - /** - * RollBack playlist changes to the locked state - * - * @param string $playlistToken - * playlist access token - * @param string $sessid - * session ID - * @return string - * gunid of playlist - */ - public function revertEditedPlaylist($playlistToken, $sessid='') - { - $gunid = $this->bsCloseDownload($playlistToken, 'metadata'); - if (PEAR::isError($gunid)) { - return $gunid; - } - $storedFile =& StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - $id = $storedFile->getId(); - $mdata = $storedFile->getMetadata(); - if (PEAR::isError($mdata)) { - return $mdata; - } - $res = $storedFile->setMetadata($mdata, 'string'); - if (PEAR::isError($res)) { - return $res; - } - $this->setEditFlag($gunid, FALSE, $sessid); - return $gunid; - } - - - /** - * Delete a Playlist metafile. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @param boolean $forced - * if true don't use trash - * @return boolean - */ - public function deletePlaylist($sessid, $playlistId, $forced=FALSE) - { - $ex = $this->existsPlaylist($sessid, $playlistId); - if (PEAR::isError($ex)) { - return $ex; - } - if (!$ex) { - if ($forced) { - return TRUE; - } - return PEAR::raiseError( - 'LocStor::deletePlaylist: playlist not exists', - GBERR_FILENEX - ); - } - $storedFile =& StoredFile::RecallByGunid($playlistId); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) { - return $res; - } - $res = $storedFile->delete(); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Access (read) a Playlist metafile. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @param boolean $recursive - * flag for recursive access content inside playlist - * @param int $parent - * parent token - * @return struct { - * url: readable URL for HTTP GET, - * token: access token, - * chsum: checksum, - * content: array of structs - recursive access (optional) - * filename: string mnemonic filename - * } - */ - public function accessPlaylist($sessid, $playlistId, $recursive=FALSE, $parent='0') - // { - // if ($recursive) { - // require_once("AccessRecur.php"); - // $r = AccessRecur::accessPlaylist($this, $sessid, $playlistId); - // if (PEAR::isError($r)) { - // return $r; - // } - // return $r; - // } - // $ex = $this->existsPlaylist($sessid, $playlistId); - // if (PEAR::isError($ex)) { - // return $ex; - // } - // if (!$ex) { - // return PEAR::raiseError( - // "LocStor::accessPlaylist: playlist not found ($playlistId)", - // GBERR_NOTF - // ); - // } - // $id = BasicStor::IdFromGunid($playlistId); - // if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) { - // return $res; - // } - // $res = $this->bsOpenDownload($id, 'metadata', $parent); - // #unset($res['filename']); - // return $res; - } - - - /** - * Release the resources obtained earlier by accessPlaylist(). - * - * @param string $sessid - * session ID - * @param string $playlistToken - * playlist access token - * @param boolean $recursive - * flag for recursive access content inside playlist - * @return string - * playlist ID - */ - public function releasePlaylist($sessid, $playlistToken, $recursive=FALSE) - { - if ($recursive) { - require_once"AccessRecur.php"; - $r = AccessRecur::releasePlaylist($this, $sessid, $playlistToken); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - return $this->bsCloseDownload($playlistToken, 'metadata'); - } - - - /** - * Create a tarfile with playlist export - playlist and all matching - * sub-playlists and media files (if desired) - * - * @param string $sessid - * session ID - * @param array $plids - * array of strings, playlist global unique IDs (one gunid is accepted too) - * @param string $type - * playlist format, values: lspl | smil | m3u - * @param boolean $standalone - * if only playlist should be exported or with all related files - * @return hasharray with fields: - * url string: readable url, - * token string: access token - * chsum string: md5 checksum, - */ - protected function exportPlaylistOpen($sessid, $plids, $type='lspl', $standalone=FALSE) - { - $res = $this->bsExportPlaylistOpen($plids, $type, !$standalone); - if (PEAR::isError($res)) { - return $res; - } - $url = BasicStor::GetUrlPart()."access/".basename($res['fname']); - $chsum = md5_file($res['fname']); - $size = filesize($res['fname']); - return array( - 'url' => $url, - 'token' => $res['token'], - 'chsum' => $chsum, - ); - } - - - /** - * Close playlist export previously opened by the exportPlaylistOpen method - * - * @param string $token - * access token obtained from exportPlaylistOpen method call - * @return boolean|PEAR_Error - */ - protected function exportPlaylistClose($token) - { - return $this->bsExportPlaylistClose($token); - } - - - /** - * Open writable handle for import playlist in LS Archive format - * - * @param string $sessid - * session id - * @param string $chsum - * md5 checksum of imported file - * @return hasharray with: - * url string: writable URL - * token string: PUT token - */ - protected function importPlaylistOpen($sessid, $chsum) - { - $userid = Alib::GetSessUserId($sessid); - if (PEAR::isError($userid)) { - return $userid; - } - $r = $this->bsOpenPut($chsum, NULL, $userid); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - /** - * Close import-handle and import playlist - * - * @param string $token - * import token obtained by importPlaylistOpen method - * @return string - * result file global id (or error object) - */ - protected function importPlaylistClose($token) - { - $arr = $this->bsClosePut($token); - if (PEAR::isError($arr)) { - return $arr; - } - $fname = $arr['fname']; - $owner = $arr['owner']; - $res = $this->bsImportPlaylist($fname); - if (file_exists($fname)) { - @unlink($fname); - } - if (PEAR::isError($res)) { - return $res; - } - $media = StoredFile::Recall($id); - return $media->getGunId(); - } - - - /** - * Check whether a Playlist metafile with the given playlist ID exists. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @return boolean - */ - public function existsPlaylist($sessid, $playlistId) - { - return $this->existsFile($sessid, $playlistId, 'playlist'); - } - - - /** - * Check whether a Playlist metafile with the given playlist ID - * is available for editing, i.e., exists and is not marked as - * being edited. - * - * @param string $sessid - * session ID - * @param string $playlistId - * playlist global unique ID - * @param boolean $getUid - * flag for returning editedby uid - * @return boolean - */ - public function playlistIsAvailable($sessid, $playlistId, $getUid=FALSE) - { - $ex = $this->existsPlaylist($sessid, $playlistId); - if (PEAR::isError($ex)) { - return $ex; - } - if (!$ex) { - return PEAR::raiseError( - 'LocStor::playlistIsAvailable: playlist not exists' - ); - } - $ie = $this->isEdited($playlistId); - if ($ie === FALSE) { - return TRUE; - } - if ($getUid) { - return $ie; - } - return FALSE; - } - - - /* ------------------------------------------------------- render methods */ - /** - * Render playlist to ogg file (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return hasharray - * token: string - render token - */ - protected function renderPlaylistToFileOpen($sessid, $plid) - { - require_once("Renderer.php"); - $r = Renderer::rnRender2FileOpen($this, $plid); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - /** - * Render playlist to ogg file (check results) - * - * @param string $token - * render token - * @return hasharray: - * status : string - success | working | fault - * url : string - readable url - */ - protected function renderPlaylistToFileCheck($token) - { - require_once("Renderer.php"); - $r = Renderer::rnRender2FileCheck($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return array('status'=>$r['status'], 'url'=>$r['url']); - } - - - /** - * Render playlist to ogg file (close handle) - * - * @param string $token - * render token - * @return boolean status - */ - protected function renderPlaylistToFileClose($token) - { - require_once("Renderer.php"); - $r = Renderer::rnRender2FileClose($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return array(TRUE); - } - - - /** - * Render playlist to storage media clip (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return string - * render token - */ - protected function renderPlaylistToStorageOpen($sessid, $plid) - { - require_once("Renderer.php"); - $owner = Alib::GetSessUserId($sessid); - if (PEAR::isError($owner)) { - return $owner; - } - $r = Renderer::rnRender2FileOpen($this, $plid, $owner); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - /** - * Render playlist to storage media clip (check results) - * - * @param string $token - * render token - * @return hasharray: - * status : string - success | working | fault - * gunid : string - gunid of result file - */ - protected function renderPlaylistToStorageCheck($token) - { - require_once("Renderer.php"); - $r = Renderer::rnRender2StorageCheck($this, $token); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - /** - * Render playlist to RSS file (open handle) - * - * @param string $sessid - * session id - * @param string $plid - * playlist gunid - * @return string - * render token - */ - protected function renderPlaylistToRSSOpen($sessid, $plid) - { - global $CC_CONFIG; - $token = '123456789abcdeff'; - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - file_put_contents($fakeFile, "fake rendered file"); - return array('token'=>$token); - } - - - /** - * Render playlist to RSS file (check results) - * - * @param string $token - * render token - * @return hasharray : - * status : string - success | working | fault - * url : string - readable url - */ - protected function renderPlaylistToRSSCheck($token) - { - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - if ($token != '123456789abcdeff' || !file_exists($fakeFile)) { - return PEAR::raiseError( - "LocStor::renderPlaylistToRSSCheck: invalid token ($token)" - ); - } - $fakeFUrl = BasicStor::GetUrlPart()."access/$token.rss"; - return array( - 'status'=> 'success', - 'url' => $fakeFUrl, - ); - } - - - /** - * Render playlist to RSS file (close handle) - * - * @param string $token - * render token - * @return boolean - * status - */ - protected function renderPlaylistToRSSClose($token) - { - if ($token != '123456789abcdeff') { - return PEAR::raiseError( - "LocStor::renderPlaylistToRSSClose: invalid token" - ); - } - $fakeFile = $CC_CONFIG['accessDir']."/$token.rss"; - unlink($fakeFile); - return TRUE; - } - - - /*================================================= storage admin methods */ - - /* ------------------------------------------------------- backup methods */ - - /** - * Create backup of storage (open handle) - * - * @param string $sessid - * session id - * @param array $criteria - * see search criteria - * @return array - * token : string - backup token - */ - protected function createBackupOpen($sessid, $criteria='') - { - require_once("Backup.php"); - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - $r = $bu->openBackup($sessid,$criteria); - if ($r === FALSE) { - return PEAR::raiseError( - "LocStor::createBackupOpen: false returned from Backup" - ); - } - return $r; - } - - - /** - * Create backup of storage (check results) - * - * @param string $token - * backup token - * @return hasharray - * with field: - * status : string - susccess | working | fault - * faultString: string - description of fault - * token : stirng - backup token - * url : string - access url - */ - protected function createBackupCheck($token) - { - require_once("Backup.php"); - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->checkBackup($token); - } - - - /** - * Create backup of storage (list results) - * - * @param string $sessid - * session id - * @param status $stat - * if this parameter is not set, then return with all unclosed backups - * @return array - * array of hasharray with field: - * status : string - susccess | working | fault - * token : stirng - backup token - * url : string - access url - */ - protected function createBackupList($sessid, $stat='') - { - require_once("Backup.php"); - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->listBackups($stat); - } - - - /** - * Create backup of storage (close handle) - * - * @param string $token - * backup token - * @return boolean - * status - */ - protected function createBackupClose($token) - { - require_once("Backup.php"); - $bu = new Backup($this); - if (PEAR::isError($bu)) { - return $bu; - } - return $bu->closeBackup($token); - } - - - /* ------------------------------------------------------ restore methods */ - - /** - * Restore a backup file (open handle) - * - * @param string $sessid - * session id - * @param string $chsum - * md5 checksum of imported file - * @return array - * array with: - * url string: writable URL - * fname string: writable local filename - * token string: PUT token - */ - protected function restoreBackupOpen($sessid, $chsum) - { - $userid = Alib::getSessUserId($sessid); - if (PEAR::isError($userid)) { - return $userid; - } - $r = $this->bsOpenPut($chsum, NULL, $userid); - if (PEAR::isError($r)) { - return $r; - } - return $r; - } - - - /** - * Restore a backup file (close put handle) - * - * @param string $sessid - * session id - * @param string $token - * "put" token - * @return string $token - * restore token - */ - protected function restoreBackupClosePut($sessid, $token) { - $arr = $this->bsClosePut($token); - if (PEAR::isError($arr)) { - return $arr; - } - $fname = $arr['fname']; - require_once('Restore.php'); - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->openRestore($sessid, $fname); - } - - - /** - * Restore a backup file (check state) - * - * @param string $token - * restore token - * @return array - * status - fields: - * token: string - restore token - * status: string - working | fault | success - * faultString: string - description of fault - */ - protected function restoreBackupCheck($token) - { - require_once('Restore.php'); - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->checkRestore($token); - } - - - /** - * Restore a backup file (close handle) - * - * @param string $token - * restore token - * @return array - * status - fields: - * token: string - restore token - * status: string - working | fault | success - */ - protected function restoreBackupClose($token) { - require_once('Restore.php'); - $rs = new Restore($this); - if (PEAR::isError($rs)) { - return $rs; - } - return $rs->closeRestore($token); - } - - - /*===================================================== auxiliary methods */ - /** - * Dummy method - only returns Campcaster version - * - * @return string - */ - public static function getVersion() - { - return CAMPCASTER_VERSION; - } - - /** - * Open upload transport (from station to hub) - * - * @param string $sessid - * session id - * @param string $chsum - * checksum - * @return array - * hasharray with: - * url string: writable URL - * token string: PUT token - */ - function uploadOpen($sessid, $chsum) - { - $owner = Alib::GetSessUserId($sessid); - if (PEAR::isError($owner)) { - return $owner; - } - $res = $this->bsOpenPut($chsum, NULL, $owner); - if (PEAR::isError($res)) { - return $res; - } - return array('url'=>$res['url'], 'token'=>$res['token']); - } - - - /** - * Close upload transport - * - * @param string $token - * transport token - * @param string $trtype - * transport type - * @param array $pars - * transport parameters - * @return mixed - */ - function uploadClose($token, $trtype, $pars=array()) - { - $res = $this->bsClosePut($token); - if (PEAR::isError($res)) { - return $res; - } - extract($res); // fname, owner - switch ($trtype) { - case "audioclip": - $mdtoken = $pars['mdpdtoken']; - $res = $this->bsClosePut($mdtoken); - if (PEAR::isError($res)) { - return $res; - } - $mdfname = $res['fname']; - if ($gunid == '') { - $gunid = NULL; - } - $values = array( - "filename" => $pars['name'], - "filepath" => $fname, - "metadata" => $mdfname, - "gunid" => $pars['gunid'], - "filetype" => "audioclip" - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - $res = $storedFile->getId(); - @unlink($fname); - @unlink($mdfname); - break; - case "playlist": - if ($gunid == '') { - $gunid = NULL; - } - $values = array( - "filename" => $pars['name'], - "metadata" => $fname, - "gunid" => $pars['gunid'], - "filetype" => "playlist" - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - $res = $storedFile->getId(); - @unlink($fname); - break; - case "playlistPkg": - $chsum = md5_file($fname); - // importPlaylistOpen: - $res = $this->bsOpenPut($chsum, NULL, $owner); - if (PEAR::isError($res)) { - return $res; - } - $dest = $res['fname']; - $token = $res['token']; - copy($fname, $dest); - $r = $this->importPlaylistClose($token); - if (PEAR::isError($r)) { - return $r; - } - @unlink($fname); - return $r; - break; - case "searchjob": - $crits = file_get_contents($fname); - $criteria = unserialize($crits); - @unlink($fname); - $results = $this->localSearch($criteria); - if (PEAR::isError($results)) { - return $results; - } - $realfile = tempnam($this->accessDir, 'searchjob_'); - @chmod($realfile, 0660); - $len = file_put_contents($realfile, serialize($results)); - $acc = BasicStor::bsAccess($realfile, '', NULL, 'download'); - if (PEAR::isError($acc)) { - return $acc; - } - $url = BasicStor::GetUrlPart()."access/".basename($acc['fname']); - $chsum = md5_file($realfile); - $size = filesize($realfile); - $res = array( - 'url'=>$url, 'token'=>$acc['token'], - 'chsum'=>$chsum, 'size'=>$size, - 'filename'=>$filename - ); - return $res; - break; - case "metadata": - break; - default: - } - return $res; - } - - - /** - * Open download transport - * - * @param string $sessid - * session id - * @param string $trtype - * transport type - * @param array $pars - * transport parameters - * @return hasharray with: - * url string: writable URL - * token string: PUT token - */ - function downloadOpen($sessid, $trtype, $pars=array()) - { - // global $CC_CONFIG; - // switch ($trtype) { - // case "unknown": - // case "audioclip": - // case "metadata": - // case "playlist": - // case "playlistPkg": - // if (!isset($pars['gunid'])) { - // return PEAR::raiseError("Archive::downloadOpen: gunid not set"); - // } - // break; - // } - // $gunid = $pars['gunid']; - // // resolve trtype by object type: - // if ( ($trtype == 'unknown') || ($trtype == 'playlistPkg') ) { - // $media = StoredFile::RecallByGunid($gunid); - // $trtype2 = $media->getType(); - // if (PEAR::isError($trtype2)) { - // return $trtype2; - // } - // // required with content: - // $trtype = ( ($trtype2 == 'playlist') && ($trtype == 'playlistPkg') ? - // 'playlistPkg' : $trtype2); - // //return PEAR::raiseError("Archive::downloadOpen: TT=$trtype TT2=$trtype2 G=$gunid"); - // } - // switch ($trtype) { - // case "audioclip": - // $res = $this->downloadRawAudioDataOpen($sessid, $gunid); - // break; - // case "metadata": - // $res = $this->downloadMetadataOpen($sessid, $gunid); - // break; - // case "playlist": - // $res = $this->accessPlaylist($sessid, $gunid); - // break; - // case "playlistPkg": - // $res = $this->bsExportPlaylistOpen($gunid); - // if (PEAR::isError($res)) { - // return $res; - // } - // $tmpn = tempnam($CC_CONFIG['transDir'], 'plExport_'); - // $plfpath = "$tmpn.lspl"; - // copy($res['fname'], $plfpath); - // $res = $this->bsExportPlaylistClose($res['token']); - // if (PEAR::isError($res)) { - // return $res; - // } - // $fname = "transported_playlist.lspl"; - // $id = BasicStor::IdFromGunid($gunid); - // $acc = BasicStor::bsAccess($plfpath, 'lspl', NULL, 'download'); - // if (PEAR::isError($acc)) { - // return $acc; - // } - // $url = BasicStor::GetUrlPart()."access/".basename($acc['fname']); - // $chsum = md5_file($plfpath); - // $size = filesize($plfpath); - // $res = array( - // 'url'=>$url, 'token'=>$acc['token'], - // 'chsum'=>$chsum, 'size'=>$size, - // 'filename'=>$fname - // ); - // break; - // case "searchjob": - // $res = $pars; - // break; - // case "file": - // $res = array(); - // break; - // default: - // return PEAR::raiseError("Archive::downloadOpen: NotImpl ($trtype)"); - // } - // if (PEAR::isError($res)) { - // return $res; - // } - // switch ($trtype) { - // case "audioclip": - // case "metadata": - // case "playlist": - // case "playlistPkg": - // $f = StoredFile::RecallByGunid($gunid); - // $title = $f->getTitle(); - // break; - // case "searchjob": - // $title = 'searchjob'; - // break; - // case "file": - // $title = 'regular file'; - // break; - // default: - // } - // $res['title'] = $title; - // $res['trtype'] = $trtype; - // return $res; - } - - - /** - * Close download transport - * - * @param string $token - * transport token - * @param string $trtype - * transport type - * @return array - * hasharray with: - * url string: writable URL - * token string: PUT token - */ - function downloadClose($token, $trtype) - { - switch ($trtype) { - case "audioclip": - $res = $this->downloadRawAudioDataClose($token); - if (PEAR::isError($res)) { - return $res; - } - return $res; - case "metadata": - $res = $this->downloadMetadataClose($token); - return $res; - case "playlist": - $res = $this->releasePlaylist(NULL/*$sessid*/, $token); - return $res; - case "playlistPkg": - $res = BasicStor::bsRelease($token, 'download'); - if (PEAR::isError($res)) { - return $res; - } - $realFname = $r['realFname']; - @unlink($realFname); - if (preg_match("|(plExport_[^\.]+)\.lspl$|", $realFname, $va)) { - list(,$tmpn) = $va; - $tmpn = $CC_CONFIG['transDir']."/$tmpn"; - if (file_exists($tmpn)) { - @unlink($tmpn); - } - } - return $res; - case "searchjob": - $res = BasicStor::bsRelease($token, 'download'); - return $res; - case "file": - return array(); - default: - return PEAR::raiseError("Archive::downloadClose: NotImpl ($trtype)"); - } - } - - - /** - * Prepare hub initiated transport - * - * @param string $target - * hostname of transport target - * @param string $trtype - * transport type - * @param string $direction - * 'up' | 'down' - * @param array $pars - * transport parameters - * @return mixed - */ - function prepareHubInitiatedTransfer( - $target, $trtype='file', $direction='up',$pars=array()) - { - $tr = new Transport($this); - $trec = TransportRecord::create($tr, $trtype, $direction, - array_merge($pars, array('target'=>$target))); - if (PEAR::isError($trec)) { - return $trec; - } - return TRUE; - } - - - /** - * List hub initiated transports - * - * @param string $target - * hostname of transport target - * @param string $direction - * 'up' | 'down' - * @param string $trtok - * transport token - * @return mixed - */ - function listHubInitiatedTransfers( - $target=NULL, $direction=NULL, $trtok=NULL) - { - $tr = new Transport($this); - $res = $tr->getTransports($direction, $target, $trtok); - return $res; - } - - - /** - * Set state of hub initiated transport - * - * @param string $target - * hostname of transport target - * @param string $trtok - * transport token - * @param string $state - * transport state - * @return TransportRecord|PEAR_Error - */ - function setHubInitiatedTransfer($target, $trtok, $state) - { - $tr = new Transport($this); - $trec = TransportRecord::recall($tr, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $r = $trec->setState($state); - if (PEAR::isError($r)) { - return $r; - } - return $trec; - } - - /* ==================================================== auxiliary methods */ - -} // class LocStor -?> \ No newline at end of file diff --git a/backend/M3uPlaylist.php b/backend/M3uPlaylist.php deleted file mode 100644 index 388c24aa5..000000000 --- a/backend/M3uPlaylist.php +++ /dev/null @@ -1,352 +0,0 @@ -lock($gb, $subjid); -// if (PEAR::isError($r)) { -// return $r; -// } -// foreach ($arr as $i => $it) { -// list($md, $uri) = preg_split("|\n|", $it); -// list($length, $title) = preg_split("|, *|", $md); -// // $gunid = StoredFile::CreateGunid(); -// $gunid = ( isset($gunids[basename($uri)]) ? $gunids[basename($uri)] : NULL); -// $acId = BasicStor::IdFromGunid($gunid); -// if (PEAR::isError($acId)) { -// return $acId; -// } -// $length = Playlist::secondsToPlaylistTime($length); -// $offset = '???'; -// if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) { -// switch (strtolower($ext = $va[1])) { -// case "lspl": -// case "xml": -// case "smil": -// case "m3u": -// $acId = $gb->bsImportPlaylistRaw($gunid, -// $aPath, $uri, $ext, $gunids, $subjid); -// if (PEAR::isError($acId)) { -// break; -// } -// //no break! -// default: -// if (is_null($gunid)) { -// return PEAR::raiseError( -// "M3uPlaylist::import: no gunid"); -// } -// $r = $pl->addAudioClip($acId); -// if (PEAR::isError($r)) { -// return $r; -// } -// } -// } -// } -// $r = $pl->unlock($gb); -// if (PEAR::isError($r)) { -// return $r; -// } -// return $pl; - } - - /** - * Import M3U file to storage - * - * @param GreenBox $gb - * @param string $data - * local path to M3U file - * @return string - * XML playlist in Campcaster playlist format - */ - function convert2lspl(&$gb, $data) - { - $arr = M3uPlaylist::parse($data); - if (PEAR::isError($arr)) { - return $arr; - } - $ind = ''; - $ind2 = $ind.INDCH; - $ind3 = $ind2.INDCH; - $res = ''; - foreach ($arr as $i => $it) { - list($md, $uri) = preg_split("|\n|", $it); - list($length, $title) = preg_split("|, *|", $md); - $gunid = StoredFile::CreateGunid(); - $gunid2 = StoredFile::CreateGunid(); - $length = Playlist::secondsToPlaylistTime($length); - $offset = '???'; - $clipStart = '???'; - $clipEnd = '???'; - $clipLength = '???'; - $uri_h = preg_replace("|--|", "d;d;", htmlspecialchars("$uri")); - if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) { - switch (strtolower($ext = $va[1])) { - case "lspl": - case "xml": - case "smil": - case "m3u": - $acOrPl = "$ind3 ". - "\n"; - break; - default: - $acOrPl = "$ind3 ". - "\n"; - break; - } - } - $res .= "$ind2\n". - $acOrPl. - "$ind2\n"; - } - $res = "$ind\n". - "$ind\n". - "$ind2\n". - "$res". - "$ind\n"; - return $res; - } -} // class M3uPlaylist - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class M3uPlaylistBodyElement { - function convert2lspl(&$tree, $ind='') - { - $ind2 = $ind.INDCH; - if ($tree->name != 'body') { - return PEAR::raiseError("M3uPlaylist::parse: body tag expected"); - } - if (isset($tree->children[1])) { - return PEAR::raiseError(sprintf( - "M3uPlaylist::parse: unexpected tag %s in tag body", - $tree->children[1]->name - )); - } - $res = M3uPlaylistParElement::convert2lspl($tree->children[0], $ind2); - if (PEAR::isError($res)) { - return $res; - } - $gunid = StoredFile::CreateGunid(); - $playlength = '???'; // *** - $res = "$ind\n". - "$ind\n". - "$ind2\n". - "$res". - "$ind\n"; - return $res; - } -} - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class M3uPlaylistParElement { - function convert2lspl(&$tree, $ind='') - { - if ($tree->name != 'par') { - return PEAR::raiseError("M3uPlaylist::parse: par tag expected"); - } - $res = ''; - foreach ($tree->children as $i => $ch) { - $ch =& $tree->children[$i]; - $r = M3uPlaylistAudioElement::convert2lspl($ch, $ind.INDCH); - if (PEAR::isError($r)) { - return $r; - } - $res .= $r; - } - return $res; - } -} - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class M3uPlaylistAudioElement { - function convert2lspl(&$tree, $ind='') - { - $ind2 = $ind.INDCH; - if ($tree->name != 'audio') { - return PEAR::raiseError("M3uPlaylist::parse: audio tag expected"); - } - if (isset($tree->children[2])) { - return PEAR::raiseError(sprintf( - "M3uPlaylist::parse: unexpected tag %s in tag audio", - $tree->children[2]->name - )); - } - $res = ''; $fadeIn = 0; $fadeOut = 0; - foreach ($tree->children as $i => $ch) { - $ch =& $tree->children[$i]; - $r = M3uPlaylistAnimateElement::convert2lspl($ch, $ind2); - if (PEAR::isError($r)) { - return $r; - } - switch ($r['type']) { - case "fadeIn": - $fadeIn = $r['val']; - break; - case "fadeOut": - $fadeOut = $r['val']; - break; - } - } - if ($fadeIn > 0 || $fadeOut > 0) { - $fadeIn = Playlist::secondsToPlaylistTime($fadeIn); - $fadeOut = Playlist::secondsToPlaylistTime($fadeOut); - $fInfo = "$ind2\n"; - } else { - $fInfo = ''; - } - $plElGunid = StoredFile::CreateGunid(); - $aGunid = StoredFile::CreateGunid(); - $title = basename($tree->attrs['src']->val); - $offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val); - $playlength = '???'; # *** - $res = "$ind\n". - "$ind2\n". - $fInfo. - "$ind\n"; - return $res; - } -} // class M3uPlaylistAudioElement - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class M3uPlaylistAnimateElement { - function convert2lspl(&$tree, $ind='') { - if ($tree->name != 'animate') { - return PEAR::raiseError("M3uPlaylist::parse: animate tag expected"); - } - if ($tree->attrs['attributeName']->val == 'soundLevel' && - $tree->attrs['from']->val == '0%' && - $tree->attrs['to']->val == '100%' && - $tree->attrs['calcMode']->val == 'linear' && - $tree->attrs['fill']->val == 'freeze' && - $tree->attrs['begin']->val == '0s' && - preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $va) - ) { - return array('type'=>'fadeIn', 'val'=>$va[1]); - } - if ($tree->attrs['attributeName']->val == 'soundLevel' && - $tree->attrs['from']->val == '100%' && - $tree->attrs['to']->val == '0%' && - $tree->attrs['calcMode']->val == 'linear' && - $tree->attrs['fill']->val == 'freeze' && - preg_match("|^([0-9.]+)s$|", $tree->attrs['begin']->val, $vaBegin) && - preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $vaEnd) - ) { - return array('type'=>'fadeOut', 'val'=>($vaEnd[1] - $vaBegin[1])); - } - return PEAR::raiseError( - "M3uPlaylistAnimateElement::convert2lspl: animate parameters too general" - ); - } -} - -?> \ No newline at end of file diff --git a/backend/Playlist.php b/backend/Playlist.php deleted file mode 100644 index 3419c1eef..000000000 --- a/backend/Playlist.php +++ /dev/null @@ -1,1497 +0,0 @@ - "DbName", "dc:creator" => "DbCreator", "dc:description" => "DbDescription", "dcterms:extent" => "length"); - - - /** - * @param string $p_gunid - */ - public function __construct($p_gunid=NULL) - { - - } - - /** - * @param array $p_name - * The name of the playlist - */ - private static function Insert($p_name = null) - { - // Create the StoredPlaylist object - $storedPlaylist = new Playlist(); - $storedPlaylist->name = !empty($p_name) ? $p_name : date("H:i:s"); - $storedPlaylist->mtime = new DateTime("now"); - - $pl = new CcPlaylist(); - $pl->setDbName($storedPlaylist->name); - $pl->setDbState("incomplete"); - $pl->setDbMtime($storedPlaylist->mtime); - $pl->save(); - - $storedPlaylist->id = $pl->getDbId(); - $storedPlaylist->setState('ready'); - - return $storedPlaylist->id; - - } - - public static function Delete($id) { - $pl = CcPlaylistQuery::create()->findPK($id); - if($pl === NULL) - return FALSE; - - $pl->delete(); - return TRUE; - } - - - /** - * Delete the file from all playlists. - * @param string $p_fileId - */ - public static function DeleteFileFromAllPlaylists($p_fileId) - { - CcPlaylistcontentsQuery::create()->filterByDbFileId($p_fileId)->delete(); - } - - - /** - * Fetch instance of Playlist object.
- * - * @param string $id - * DB id of file - * @return Playlist|FALSE - * Return FALSE if the object doesnt exist in the DB. - */ - public static function Recall($id) { - - $pl = CcPlaylistQuery::create()->findPK($id); - if($pl === NULL) - return FALSE; - - $storedPlaylist = new Playlist(); - $storedPlaylist->id = $pl->getDbId(); - $storedPlaylist->name = $pl->getDbName(); - $storedPlaylist->state = $pl->getDbState(); - $storedPlaylist->currentlyaccessing = $pl->getDbCurrentlyaccessing(); - $storedPlaylist->editedby = $pl->getDbEditedby(); - $storedPlaylist->mtime = $pl->getDbMtime(); - - return $storedPlaylist; - } - - /** - * Rename stored virtual playlist - * - * @param string $p_newname - * @return TRUE|PEAR_Error - */ - public function setName($p_newname) - { - $pl = CcPlaylistQuery::create()->findPK($this->id); - - if($pl === NULL) - return FALSE; - - $pl->setDbName($p_newname); - $pl->setDbMtime(new DateTime("now")); - $pl->save(); - - $this->name = $p_newname; - return TRUE; - } - - /** - * Get mnemonic playlist name - * - * @param string $p_gunid - * global unique id of playlist - * @return string - */ - public function getName($id=NULL) - { - if (is_null($id)) { - return $this->name; - } - $pl = CcPlaylistQuery::create()->findPK($id); - if($pl === NULL) - return FALSE; - - return $pl->getDbName(); - } - - /** - * Set state of virtual playlist - * - * @param string $p_state - * 'empty'|'incomplete'|'ready'|'edited' - * @param int $p_editedby - * user id | 'NULL' for clear editedBy field - * @return TRUE|PEAR_Error - */ - public function setState($p_state, $p_editedby=NULL) - { - $pl = CcPlaylistQuery::create()->findPK($this->id); - - if($pl === NULL) - return FALSE; - - $pl->setDbState($p_state); - $pl->setDbMtime(new DateTime("now")); - - $eb = (!is_null($p_editedby) ? $p_editedby : NULL); - $pl->setDbEditedby($eb); - - $pl->save(); - - $this->state = $p_state; - $this->editedby = $p_editedby; - return TRUE; - } - - /** - * Get storage-internal file state - * - * @param string $p_gunid - * global unique id of file - * @return string - * see install() - */ - public function getState($id=NULL) - { - if (is_null($id)) { - return $this->state; - } - - $pl = CcPlaylistQuery::create()->findPK($id); - if($pl === NULL) - return FALSE; - - return $pl->getDbState(); - } - - /** - * TODO have to change this. - * */ - - /* - public function isScheduled() { - global $CC_CONFIG, $CC_DBC; - - $sql = "SELECT * " - ." FROM ".$CC_CONFIG['scheduleTable'] - ." WHERE ends > now() and playlist=x'{$this->gunid}'::bigint"; - $scheduled = $CC_DBC->getAll($sql); - - return $scheduled; - } - */ - - /** - * Returns true if virtual file is currently in use.
- * Static or dynamic call is possible. - * - * @param string $p_gunid - * optional (for static call), global unique id - * @return boolean|PEAR_Error - */ - public function isAccessed($id=NULL) - { - if (is_null($id)) { - return ($this->currentlyaccessing > 0); - } - - $pl = CcPlaylistQuery::create()->findPK($id); - if (is_null($pl)) { - return PEAR::raiseError( - "StoredPlaylist::isAccessed: invalid id ($id)", - GBERR_FOBJNEX - ); - } - - return ($pl->getDbCurrentlyaccessing() > 0); - } - - /** - * Returns id of user editing playlist - * - * @param string $p_playlistId - * playlist global unique ID - * @return int id of user editing playlist - */ - public function isEdited() { - - if($this->state === 'edited') { - return $this->editedby; - } - return FALSE; - } - - - /** - * Set playlist edit flag - * - * @param string $p_playlistId - * Playlist unique ID - * @param boolean $p_val - * Set/clear of edit flag - * @param string $p_sessid - * Session id - * @param int $p_subjid - * Subject id (if sessid is not specified) - * @return boolean - * TRUE on success. - */ - - public function setEditFlag($p_val=TRUE, $p_sessid=NULL, $p_subjid=NULL) { - - if (!is_null($p_sessid)) { - $p_subjid = Alib::GetSessUserId($p_sessid); - if (PEAR::isError($p_subjid)) { - return $p_subjid; - } - } - - if ($p_val) { - $r = $this->setState('edited', $p_subjid); - } else { - $r = $this->setState('ready'); - } - if ($r === FALSE) { - return FALSE; - } - return TRUE; - } - - /** - * Return local ID of virtual file. - * - * @return int - */ - public function getId() { - return $this->id; - } - - private function getNextPos() { - - $res = CcPlaylistQuery::create() - ->findPK($this->id) - ->computeLastPosition(); - - if(is_null($res)) { - return 0; - } - - return $res + 1; - } - - /** - * Get the entire playlist as a two dimentional array, sorted in order of play. - * @return array - */ - public function getContents() { - $files = array(); - $rows = CcPlaylistcontentsQuery::create() - ->joinWith('CcFiles') - ->orderByDbPosition() - ->filterByDbPlaylistId($this->id) - ->find(); - - foreach ($rows as $row) { - $files[] = $row->toArray(BasePeer::TYPE_FIELDNAME, true, true); - } - - return $files; - } - - public function getLength() { - $res = CcPlaylistQuery::create() - ->findPK($this->id) - ->computeLength(); - - if(is_null($res)) { - return '00:00:00.000000'; - } - - return $res; - } - - /** - * Create instance of Playlist object and insert empty file - * - * @param string $fname - * name of new file - * @return instance of Playlist object - */ - public function create($fname=NULL) - { - $pl_id = Playlist::Insert($fname); - $this->id = $pl_id; - return $this->id; - } - - - public static function findPlaylistByName($p_name) - { - $res = CcPlaylistQuery::create()->findByDbName($p_name); - return $res; - } - - - /** - * Lock playlist for edit - * - * @param string $sessid - * session id - * @param int $subjid - * local subject (user) id - * @param boolean $val - * if false do unlock - * @return boolean - * previous state or error object - */ - public function lock($sessid, $subjid=NULL, $val=TRUE) - { - if ($val && $this->isEdited() !== FALSE) { - return PEAR::raiseError( - 'Playlist::lock: playlist already locked' - ); - } - $r = $this->setEditFlag($val, $sessid, $subjid); - return $r; - } - - - /** - * Unlock playlist - * - * @param sessId - * reference to GreenBox object - * @return boolean - * previous state or error object - */ - public function unlock($sessid) - { - $r = $this->lock($sessid, NULL, FALSE); - return $r; - } - - - /** - * Add audio clip to the playlist - * - * @param string $p_id - * local ID of added file - * @param string $p_position - * optional, Which position in the playlist to insert the audio clip - * @param string $p_fadeIn - * optional, in time format hh:mm:ss.ssssss - total duration - * @param string $p_fadeOut - * optional, in time format hh:mm:ss.ssssss - total duration - * @param string $p_clipLength - * optional length in in time format hh:mm:ss.ssssss - - * for webstream (or for overrule length of audioclip) - * @return true|PEAR_Error - * TRUE on success - */ - public function addAudioClip($p_mediaId, $p_position=NULL, $p_fadeIn=NULL, $p_fadeOut=NULL, $p_clipLength=NULL, $p_cuein=NULL, $p_cueout=NULL) - { - $_SESSION['debug'] = "in add"; - - //get audio clip. - $media = StoredFile::Recall($p_mediaId); - if (is_null($media) || PEAR::isError($media)) { - return $media; - } - // get information about audioClip - // $acInfo = $this->getAudioClipInfo($ac); - // if (PEAR::isError($acInfo)) { - // return $acInfo; - // } - // extract($acInfo); // 'acGunid', 'acLen', 'acTit', 'elType' - $metadata = $media->getMetadata(); - $length = $metadata["length"]; - - if (!is_null($p_clipLength)) { - $length = $p_clipLength; - } - - // insert at end of playlist. - if (is_null($p_position)) - $p_position = $this->getNextPos(); - if (PEAR::isError($p_position)) { - return $p_position; - } - - // insert default values if parameter was empty - $p_cuein = !is_null($p_cuein) ? $p_cuein : '00:00:00.000000'; - $p_cueout = !is_null($p_cueout) ? $p_cueout : $length; - - $mediaLengthSec = $clipLengthSec = self::playlistTimeToSeconds($length); - if (!is_null($p_cuein)) { - $clipLengthSec = $mediaLengthSec - self::playlistTimeToSeconds($p_cuein); - } - if (!is_null($p_cueout)) { - $clipLengthSec = $clipLengthSec - ($mediaLengthSec - self::playlistTimeToSeconds($p_cueout)); - } - $p_clipLength = self::secondsToPlaylistTime($clipLengthSec); - - $res = $this->insertPlaylistElement($this->id, $p_mediaId, $p_position, $p_clipLength, $p_cuein, $p_cueout, $p_fadeIn, $p_fadeOut); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Remove audioClip from playlist - * - * @param int $position - * position of audioclip in the playlist. - * @return boolean - */ - public function delAudioClip($pos) - { - if($pos < 0 || $pos >= $this->getNextPos()) - return FALSE; - - $row = CcPlaylistcontentsQuery::create() - ->filterByDbPlaylistId($this->id) - ->filterByDbPosition($pos) - ->findOne(); - - if(is_null($row)) - return FALSE; - - $row->delete(); - return $row; - } - - /** - * Move audioClip to the new position in the playlist - * - * @param int $oldPos - * old positioin in playlist - * @param int $newPos - * new position in playlist - * @return mixed - */ - public function moveAudioClip($oldPos, $newPos) - { - if($newPos < 0 || $newPos >= $this->getNextPos() || $oldPos < 0 || $oldPos >= $this->getNextPos()) - return FALSE; - - $row = $this->delAudioClip($oldPos); - if($row === FALSE) - return FALSE; - - $res = $this->addAudioClip($row->getDbFileId(), $newPos, $row->getDbFadein(), $row->getDbFadeout(), $row->getDbCliplength(), $row->getDbCuein(), $row->getDbCueout()); - if($res !== TRUE) - return FALSE; - - return TRUE; - } - - - /** - * Change fadeIn and fadeOut values for playlist Element - * - * @param int $pos - * position of audioclip in playlist - * @param string $fadeIn - * new value in ss.ssssss or extent format - * @param string $fadeOut - * new value in ss.ssssss or extent format - * @return boolean - */ - public function changeFadeInfo($pos, $fadeIn, $fadeOut) - { - $errArray= array(); - - if(is_null($pos) || $pos < 0 || $pos >= $this->getNextPos()) { - $errArray["error"]="Invalid position."; - return $errArray; - } - - $row = CcPlaylistcontentsQuery::create() - ->filterByDbPlaylistId($this->id) - ->filterByDbPosition($pos) - ->findOne(); - - $clipLength = $row->getDbCliplength(); - - if(!is_null($fadeIn) && !is_null($fadeOut)) { - - if(Playlist::playlistTimeToSeconds($fadeIn) > Playlist::playlistTimeToSeconds($clipLength)) { - $errArray["error"]="Fade In can't be larger than overall playlength."; - return $errArray; - } - if(Playlist::playlistTimeToSeconds($fadeOut) > Playlist::playlistTimeToSeconds($clipLength)) { - $errArray["error"]="Fade Out can't be larger than overall playlength."; - return $errArray; - } - - $row->setDbFadein($fadeIn); - $row->setDbFadeout($fadeOut); - } - else if(!is_null($fadeIn)) { - - if(Playlist::playlistTimeToSeconds($fadeIn) > Playlist::playlistTimeToSeconds($clipLength)) { - $errArray["error"]="Fade In can't be larger than overall playlength."; - return $errArray; - } - - $row->setDbFadein($fadeIn); - } - else if(!is_null($fadeOut)){ - - if(Playlist::playlistTimeToSeconds($fadeOut) > Playlist::playlistTimeToSeconds($clipLength)) { - $errArray["error"]="Fade Out can't be larger than overall playlength."; - return $errArray; - } - - $row->setDbFadeout($fadeOut); - } - - $row->save(); - - return array("fadeIn"=>$fadeIn, "fadeOut"=>$fadeOut); - } - - /** - * Change cueIn/cueOut values for playlist element - * - * @param int $pos - * position of audioclip in playlist - * @param string $cueIn - * new value in ss.ssssss or extent format - * @param string $cueOut - * new value in ss.ssssss or extent format - * @return boolean or pear error object - */ - public function changeClipLength($pos, $cueIn, $cueOut) - { - $errArray= array(); - - if(is_null($cueIn) && is_null($cueOut)) { - $errArray["error"]="Cue in and cue out are null."; - return $errArray; - } - - if(is_null($pos) || $pos < 0 || $pos >= $this->getNextPos()) { - $errArray["error"]="Invalid position."; - return $errArray; - } - - $row = CcPlaylistcontentsQuery::create() - ->joinWith(CcFiles) - ->filterByDbPlaylistId($this->id) - ->filterByDbPosition($pos) - ->findOne(); - - $oldCueIn = $row->getDBCuein(); - $oldCueOut = $row->getDbCueout(); - $fadeIn = $row->getDbFadein(); - $fadeOut = $row->getDbFadeout(); - - $file = $row->getCcFiles(); - $origLength = $file->getDbLength(); - - - if(!is_null($cueIn) && !is_null($cueOut)){ - - if($cueOut === ""){ - $cueOut = $origLength; - } - if(Playlist::playlistTimeToSeconds($cueIn) > Playlist::playlistTimeToSeconds($cueOut)) { - $errArray["error"]= "Can't set cue in to be larger than cue out."; - return $errArray; - } - if(Playlist::playlistTimeToSeconds($cueOut) > Playlist::playlistTimeToSeconds($origLength)){ - $errArray["error"] = "Can't set cue out to be greater than file length."; - return $errArray; - } - - $row->setDbCuein($cueIn); - $row->setDbCueout($cueOut); - $row->setDBCliplength(Playlist::secondsToPlaylistTime(Playlist::playlistTimeToSeconds($cueOut) - - Playlist::playlistTimeToSeconds($cueIn))); - - } - else if(!is_null($cueIn)) { - - if(Playlist::playlistTimeToSeconds($cueIn) > Playlist::playlistTimeToSeconds($oldCueOut)) { - $errArray["error"] = "Can't set cue in to be larger than cue out."; - return $errArray; - } - - $row->setDbCuein($cueIn); - $row->setDBCliplength(Playlist::secondsToPlaylistTime(Playlist::playlistTimeToSeconds($oldCueOut) - - Playlist::playlistTimeToSeconds($cueIn))); - } - else if(!is_null($cueOut)) { - - if($cueOut === ""){ - $cueOut = $origLength; - } - - if(Playlist::playlistTimeToSeconds($cueOut) < Playlist::playlistTimeToSeconds($oldCueIn)) { - $errArray["error"] ="Can't set cue out to be smaller than cue in."; - return $errArray; - } - - if(Playlist::playlistTimeToSeconds($cueOut) > Playlist::playlistTimeToSeconds($origLength)){ - $errArray["error"] ="Can't set cue out to be greater than file length."; - return $errArray; - } - - $row->setDbCueout($cueOut); - $row->setDBCliplength(Playlist::secondsToPlaylistTime(Playlist::playlistTimeToSeconds($cueOut) - - Playlist::playlistTimeToSeconds($oldCueIn))); - } - - $cliplength = $row->getDbCliplength(); - - if(Playlist::playlistTimeToSeconds($fadeIn) > Playlist::playlistTimeToSeconds($cliplength)){ - $fadeIn = $cliplength; - - $row->setDbFadein($fadeIn); - } - if(Playlist::playlistTimeToSeconds($fadeOut) > Playlist::playlistTimeToSeconds($cliplength)){ - $fadeOut = $cliplength; - - $row->setDbFadein($fadeOut); - } - - $row->save(); - - return array("cliplength"=>$cliplength, "cueIn"=>$cueIn, "cueOut"=>$cueOut, "length"=>$this->getLength(), - "fadeIn"=>$fadeIn, "fadeOut"=>$fadeOut); - } - - /** - * Find info about clip at specified offset in playlist. - * - * @param string $offset - * current playtime (hh:mm:ss.ssssss) - * @param int $distance - * 0=current clip; 1=next clip ... - * @return array of matching clip info: - *
    - *
  • gunid string, global unique id of clip
  • - *
  • elapsed string, already played time of clip
  • - *
  • remaining string, remaining time of clip
  • - *
  • duration string, total playlength of clip
  • - *
- */ - public function getPlaylistClipAtPosition($pos) - { - - } - - public function getPLMetaData($category) - { - $cat = $this->categories[$category]; - - if($cat === 'length') { - return $this->getLength(); - } - - $row = CcPlaylistQuery::create()->findPK($this->id); - $method = 'get' . $cat; - return $row->$method(); - } - - public function setPLMetaData($category, $value) - { - $cat = $this->categories[$category]; - - $row = CcPlaylistQuery::create()->findPK($this->id); - $method = 'set' . $cat; - $row->$method($value); - $row->save(); - - return TRUE; - } - - /** - * Return array with gunids of all sub-playlists and clips used in - * the playlist - * - * @return array with hash elements: - * gunid - global id - * type - playlist | audioClip - */ - public function export() - { - - } - - - /** - * Convert playlist time value to float seconds - * - * @param string $plt - * playlist time value (HH:mm:ss.dddddd) - * @return int - * seconds - */ - public static function playlistTimeToSeconds($plt) - { - $arr = preg_split('/:/', $plt); - if (isset($arr[2])) { - return (intval($arr[0])*60 + intval($arr[1]))*60 + floatval($arr[2]); - } - if (isset($arr[1])) { - return intval($arr[0])*60 + floatval($arr[1]); - } - return floatval($arr[0]); - } - - - /** - * Convert float seconds value to playlist time format - * - * @param float $seconds - * @return string - * time in playlist time format (HH:mm:ss.dddddd) - */ - public static function secondsToPlaylistTime($p_seconds) - { - $seconds = $p_seconds; - $milliseconds = intval(($seconds - intval($seconds)) * 1000); - $milliStr = str_pad($milliseconds, 6, '0'); - $hours = floor($seconds / 3600); - $seconds -= $hours * 3600; - $minutes = floor($seconds / 60); - $seconds -= $minutes * 60; - $res = sprintf("%02d:%02d:%02d.%s", $hours, $minutes, $seconds, $milliStr); - return $res; - } - - /** - * Export playlist as simplified SMIL XML file. - * - * @param boolean $toString - * if false don't real export, - * return misc info about playlist only - * @return string - * XML string or hasharray with misc info - */ - public function outputToSmil($toString=TRUE) - { - - } - - - /** - * Export playlist as M3U file. - * - * @param boolean $toString - * if false don't real export, - * return misc info about playlist only - * @return string|array - * M3U string or hasharray with misc info - */ - public function outputToM3u($toString=TRUE) - { - - } - - - /** - * Export playlist as RSS XML file - * - * @param boolean $toString - * if false don't really export, - * return misc info about playlist only - * @return mixed - * XML string or hasharray with misc info - */ - public function outputToRss($toString=TRUE) - { - - } - - - /** - * Get audioClip length and title - * - * @param StoredFile $p_media - * - * @return array with fields: - *
    - *
  • acGunid, string - audioClip gunid
  • - *
  • acLen string - length of clip in dcterms:extent format
  • - *
  • acTit string - clip title
  • - *
  • elType string - audioClip | playlist
  • - *
- */ - // private function getAudioClipInfo($p_media) - // { - // $ac_id = $p_media->getId(); - // - // $r = $p_media->getMetadataValue('dcterms:extent'); - // if (isset($r)) { - // $acLen = $r; - // } else { - // $acLen = '00:00:00.000000'; - // } - // - // $r = $p_media->getMetadataValue('dc:title'); - // if (isset($r)) { - // $acTit = $r; - // } else { - // $acTit = $acGunid; - // } - // $elType = $p_media->getType(); - // $trTbl = array('audioclip'=>'audioClip', 'webstream'=>'audioClip','playlist'=>'playlist'); - // $elType = $trTbl[$elType]; - // - // return compact('acGunid', 'acLen', 'acTit', 'elType'); - // } - - - /** - * Insert a new playlist element. - * - * @param int $plId - * id of Playlist - * @param int $fileId - * id of File - * @param string $offset - * relative offset in extent format - * @param string $clipstart - * audioClip clipstart in extent format - * @param string $clipEnd - * audioClip clipEnd in extent format - * @param string $clipLength - * audioClip playlength in extent format (?) - * @param string $acGunid - * audioClip gunid - * @param string $acLen - * audioClip length in extent format - * @param string $acTit - * audioClip title - * @param string $fadeIn - * fadeIn value in ss.ssssss or extent format - * @param string $fadeOut - * fadeOut value in ss.ssssss or extent format - - * @return array with fields: - *
    - *
  • plElId int - record id of playlistElement
  • - *
  • plElGunid string - gl.unique id of playlistElement
  • - *
  • fadeInId int - record id
  • - *
  • fadeOutId int - record id
  • - *
- */ - private function insertPlaylistElement($plId, $fileId, $pos, $clipLength, $cuein, $cueout, $fadeIn=NULL, $fadeOut=NULL) - { - if(is_null($fadeIn)) - $fadeIn = '00:00:00.000'; - if(is_null($fadeOut)) - $fadeOut = '00:00:00.000'; - - $row = new CcPlaylistcontents(); - $row->setDbPlaylistId($plId); - $row->setDbFileId($fileId); - $row->setDbPosition($pos); - $row->save(); - - $row->setDbCliplength($clipLength); - $row->setDbCuein($cuein); - $row->setDbCueout($cueout); - $row->setDbFadein($fadeIn); - $row->setDbFadeout($fadeOut); - - - return TRUE; - } - - /** - * Set playlist length - dcterm:extent - * - * @param string $newPlLen - * new length in extent format - * @param int $parid - * playlist container record id - * @param int $metaParid - * metadata container record id - * @return boolean - */ - private function setPlaylistLength($newPlLen, $parid, $metaParid) - { - $mid = $this->_getMidOrInsert('playlength', $parid, $newPlLen, 'A'); - if (PEAR::isError($mid)) { - return $mid; - } - $r = $this->_setValueOrInsert( - $mid, $newPlLen, $parid, 'playlength', 'A'); - if (PEAR::isError($r)) { - return $r; - } - $mid = $this->_getMidOrInsert('dcterms:extent', $metaParid, $newPlLen); - if (PEAR::isError($mid)) { - return $mid; - } - $r = $this->_setValueOrInsert( - $mid, $newPlLen, $metaParid, 'dcterms:extent'); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - -} // class Playlist - - -/** - * Auxiliary class for GB playlist editing methods - * - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class PlaylistElement { - private $pl = NULL; - private $plEl = NULL; - - public function PlaylistElement($pl, $plEl) - { - $this->pl = $pl; - $this->plEl = $plEl; - } - - - public function analyze() - { - $plInfo = array( - 'acLen' => '00:00:00.000000', - 'acLenS' => 0, - 'fadeIn' => '00:00:00.000000', - 'fadeInS' => 0, - 'fadeOut' => '00:00:00.000000', - 'fadeOutS' => 0, - 'clipStart' => '00:00:00.000000', - 'clipStartS' => 0, - 'clipEnd' => '00:00:00.000000', - 'clipEndS' => 0 - ); - $plInfo['elOffset'] = $this->plEl['attrs']['relativeOffset']; - $plInfo['elOffsetS'] = Playlist::playlistTimeToSeconds($plInfo['elOffset']); - // cycle over tags inside playlistElement - foreach ($this->plEl['children'] as $j => $acFi) { - switch ($acFi['elementname']) { - case "playlist": - $plInfo['type'] = 'playlist'; - break; - case "audioClip": - $plInfo['type'] = 'audioClip'; - break; - } - switch ($acFi['elementname']) { - case "playlist": - case "audioClip": - $plInfo['acLen'] = $acFi['attrs']['playlength']; - $plInfo['acLenS'] = Playlist::playlistTimeToSeconds($plInfo['acLen']); - $plInfo['acGunid'] = $acFi['attrs']['id']; - break; - case "fadeInfo": - $plInfo['fadeIn'] = $acFi['attrs']['fadeIn']; - $plInfo['fadeInS'] = Playlist::playlistTimeToSeconds($plInfo['fadeIn']); - $plInfo['fadeOut'] = $acFi['attrs']['fadeOut']; - $plInfo['fadeOutS'] = Playlist::playlistTimeToSeconds($plInfo['fadeOut']); - break; - } - $plInfo['clipStart'] = $this->plEl['attrs']['clipStart']; - $plInfo['clipStartS'] = Playlist::playlistTimeToSeconds($this->plEl['attrs']['clipStart']); - $plInfo['clipEnd'] = $this->plEl['attrs']['clipEnd']; - $plInfo['clipEndS'] = Playlist::playlistTimeToSeconds($this->plEl['attrs']['clipEnd']); - } - return $plInfo; - } -} // class PlaylistElement - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @todo Rename this class PlaylistTag - */ -class PlaylistTagExport -{ - public static function OutputToSmil(&$pl, $plt, $ind='') - { - $ind2 = $ind.INDCH; - $ind3 = $ind2.INDCH; - $ind4 = $ind3.INDCH; - $res = ""; - foreach ($plt['children'] as $ple) { - switch ($ple['elementname']) { - case "playlistElement": - $r = PlaylistElementExport::OutputToSmil($pl, $ple, $ind4); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $res .= $r; - } - break; - case "metadata": - $r = PlaylistMetadataExport::OutputToSmil($pl, $ple, $ind4); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $res .= $r; - } - break; - default: - } - } - $res = "$ind\n". - "$ind\n". - "$ind2\n". - "$ind3\n". - "$res". - "$ind3\n". - "$ind2\n". - "$ind\n"; - return $res; - } - - - public static function OutputToM3u(&$pl, $plt, $ind='') - { - $res = ""; - foreach ($plt['children'] as $ple) { - switch ($ple['elementname']) { - case"playlistElement": - $r = PlaylistElementExport::OutputToM3u($pl, $ple); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $res .= $r; - } - break; - } - } - $res = "#EXTM3U\n$res"; - return $res; - } - - - public static function OutputToRss(&$pl, $plt, $ind='') - { - $ind2 = $ind.INDCH; - $ind3 = $ind2.INDCH; - $res = ""; - foreach ($plt['children'] as $ple) { - switch ($ple['elementname']) { - case "playlistElement": - $r = PlaylistElementExport::OutputToRss($pl, $ple, $ind3); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $res .= $r; - } - break; - case "metadata": - $r = PlaylistMetadataExport::OutputToRss($pl, $ple, $ind3); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $res .= $r; - } - break; - default: - } - } - $res = "$ind\n". - "$ind\n". - "$ind2\n". - "$res". - "$ind2\n". - "$ind\n"; - return $res; - } -} - - -/** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @todo Rename this class "PlaylistElement" - */ -class PlaylistElementExport { - - public static function OutputToSmil(&$pl, $ple, $ind='') - { - $acOrPl = NULL; - $finfo = array('fi'=>0, 'fo'=>0); - $ind2 = $ind.INDCH; - $ind3 = $ind2.INDCH; - $anim = ''; - foreach ($ple['children'] as $ac) { - switch ($ac['elementname']) { - case "audioClip": - $r = PlaylistAudioClipExport::OutputToSmil($pl, $ac, $ind2); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - case "playlist": - $gunid = $ac['attrs']['id']; - $pl2 = StoredFile::RecallByGunid($gunid); - if (is_null($pl2) || PEAR::isError($pl2)) { - return $pl2; - } - $r = $pl2->outputToSmil(FALSE); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - case "fadeInfo": - $r = PlaylistFadeInfoExport::OutputToSmil($pl, $ac, $ind2); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $finfo = $r; - } - break; - default: - return PEAR::raiseError( - "PlaylistElementExport::OutputToSmil:". - " unknown tag {$ac['elementname']}" - ); - } - } - $beginS = Playlist::playlistTimeToSeconds($ple['attrs']['relativeOffset']); - $playlengthS = Playlist::playlistTimeToSeconds($acOrPl['playlength']); - $fadeOutS = Playlist::playlistTimeToSeconds($finfo['fo']); - $fiBeginS = 0; - $fiEndS = Playlist::playlistTimeToSeconds($finfo['fi']); - $foBeginS = ($playlengthS - $fadeOutS); - $foEndS = Playlist::playlistTimeToSeconds($acOrPl['playlength']); - foreach (array('fi','fo') as $ff) { - if (${$ff."EndS"} - ${$ff."BeginS"} > 0) { - $anim .= "{$ind2}\n" - ; - } - } - $src = $acOrPl['src']; - $str = "$ind" : " />"). - " ". - "\n"; - return $str; - } - - - public static function OutputToM3u(&$pl, $ple, $ind='') - { - $acOrPl = NULL; - foreach ($ple['children'] as $ac) { - switch ($ac['elementname']) { - case "audioClip": - $r = PlaylistAudioClipExport::OutputToM3u($pl, $ac); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - case "playlist": - $gunid = $ac['attrs']['id']; - $pl2 = StoredFile::RecallByGunid($gunid); - if (is_null($pl2) || PEAR::isError($pl2)) { - return $pl2; - } - $r = $pl2->outputToM3u(FALSE); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - } - } - if (is_null($acOrPl)) { - return ''; - } - $playlength = ceil(Playlist::playlistTimeToSeconds($acOrPl['playlength'])); - $title = $acOrPl['title']; - $uri = (isset($acOrPl['uri']) ? $acOrPl['uri'] : '???' ); - $res = "#EXTINF: $playlength, $title\n"; - $res .= "$uri\n"; - return $res; - } - - - public static function OutputToRss(&$pl, $ple, $ind='') - { - $acOrPl = NULL; - $ind2 = $ind.INDCH; - $anim = ''; - foreach ($ple['children'] as $ac) { - switch ($ac['elementname']) { - case "audioClip": - $r = PlaylistAudioClipExport::OutputToRss($pl, $ac, $ind2); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - case "playlist": - $gunid = $ac['attrs']['id']; - $pl2 = StoredFile::RecallByGunid($gunid); - if (is_null($pl2) || PEAR::isError($pl2)) { - return $pl2; - } - $r = $pl2->outputToRss(FALSE); - if (PEAR::isError($r)) { - return $r; - } - if (!is_null($r)) { - $acOrPl = $r; - } - break; - case "fadeInfo": - break; - default: - return PEAR::raiseError( - "PlaylistElementExport::OutputToRss:". - " unknown tag {$ac['elementname']}" - ); - } - } - $title = (isset($acOrPl['title']) ? htmlspecialchars($acOrPl['title']) : '' ); - $desc = (isset($acOrPl['desc']) ? htmlspecialchars($acOrPl['desc']) : '' ); - $link = htmlspecialchars($acOrPl['src']); - $desc = ''; - $str = "$ind\n". - "$ind2$title\n". - "$ind2$desc\n". - "$ind2$link\n". - "$ind\n"; - return $str; - } - } - - - /** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @todo Rename this class to PlaylistAudioClip (notice the caps) - */ - class PlaylistAudioClipExport - { - - public static function OutputToSmil(&$pl, $plac, $ind='') - { - $gunid = $plac['attrs']['id']; - $ac = StoredFile::RecallByGunid($gunid); - if (is_null($ac) || PEAR::isError($ac)) { - return $ac; - } - $RADext = $ac->getFileExtension(); - if (PEAR::isError($RADext)) { - return $RADext; - } - return array( - 'type' => 'audioclip', - 'gunid' => $gunid, - 'src' => AC_URL_RELPATH."$gunid.$RADext", - 'playlength' => $plac['attrs']['playlength'], - ); - } - - - public static function OutputToM3u(&$pl, $plac, $ind='') - { - $gunid = $plac['attrs']['id']; - $ac = StoredFile::RecallByGunid($gunid); - if (is_null($ac) || PEAR::isError($ac)) { - return $ac; - } - $RADext = $ac->getFileExtension(); - if (PEAR::isError($RADext)) { - return $RADext; - } - return array( - 'playlength' => $plac['attrs']['playlength'], - 'title' => $plac['attrs']['title'], - 'uri' => AC_URL_RELPATH."$gunid.$RADext", - ); - } - - - public static function OutputToRss(&$pl, $plac, $ind='') - { - $id = $plac['attrs']['id']; - $playlist = Playlist::Recall($id); - if (is_null($playlist) || PEAR::isError($playlist)) { - return $playlist; - } - $RADext = $playlist->getFileExtension(); - if (PEAR::isError($RADext)) { - return $RADext; - } - $title = $playlist->getName(); - $desc = $playlist->getPLMetaData("dc:description"); - return array( - 'type' => 'audioclip', - 'gunid' => $id, - 'src' => "http://XXX/YY/$id.$RADext", - 'playlength' => $plac['attrs']['playlength'], - 'title' => $title, - 'desc' => $desc, - ); - } - } - - - /** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @todo Rename this class "PlaylistFadeInfo" (notive the caps) - */ - class PlaylistFadeInfoExport - { - - public static function OutputToSmil(&$pl, $plfi, $ind='') - { - $r = array( - 'fi'=>$plfi['attrs']['fadeIn'], - 'fo'=>$plfi['attrs']['fadeOut'], - ); - return $r; - } - - - public static function OutputToM3u(&$pl, $plfa, $ind='') - { - return ''; - } - - - public static function OutputToRss(&$pl, $plfa, $ind='') - { - return ''; - } - - } - - - /** - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @todo Rename this class to PlaylistMetadata (notice the caps) - */ - class PlaylistMetadataExport - { - public static function OutputToSmil(&$pl, $md, $ind='') - { - return NULL; - } - - - public static function OutputToM3u(&$pl, $md, $ind='') - { - return NULL; - } - - - public static function OutputToRss(&$pl, $md, $ind='') - { - return NULL; - } - } - - ?> diff --git a/backend/Prefs.php b/backend/Prefs.php deleted file mode 100644 index c51a75402..000000000 --- a/backend/Prefs.php +++ /dev/null @@ -1,442 +0,0 @@ -gb =& $gb; - } - - - /* ======================================================= public methods */ - /* ----------------------------------------------------- user preferences */ - /** - * Read preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @return string - * preference value - */ - function loadPref($sessid, $key) - { - $subjid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($subjid)) { - return $subjid; - } - if (is_null($subjid)) { - return PEAR::raiseError("Prefs::loadPref: invalid session id", - GBERR_SESS); - } - $val = $this->readVal($subjid, $key); - if (PEAR::isError($val)) { - return $val; - } - if ($val === FALSE) { - return PEAR::raiseError("Prefs::loadPref: invalid preference key", - GBERR_PREF); - } - return $val; - } - - - /** - * Save preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @param string $value - * preference value - * @return boolean - */ - function savePref($sessid, $key, $value) - { - $subjid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($subjid)) { - return $subjid; - } - if (is_null($subjid)) { - return PEAR::raiseError("Prefs::savePref: invalid session id", GBERR_SESS); - } - $r = $this->update($subjid, $key, $value); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - $r = $this->insert($subjid, $key, $value); - if (PEAR::isError($r)) { - return $r; - } - } - return TRUE; - } - - - /** - * Delete preference record by session id - * - * @param string $sessid - * session id - * @param string $key - * preference key - * @return boolean - */ - function delPref($sessid, $key) - { - $subjid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($subjid)) { - return $subjid; - } - if (is_null($subjid)) { - return PEAR::raiseError("Prefs::delPref: invalid session id", GBERR_SESS); - } - $r = $this->delete($subjid, $key); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - return PEAR::raiseError("Prefs::delPref: invalid preference key", GBERR_PREF); - } - return TRUE; - } - - - /* ---------------------------------------------------- group preferences */ - /** - * Read group preference record - * - * @param string $group - * group name - * @param string $key - * preference key - * @param boolean $returnErrorIfKeyNotExists - * If set to true and the key doesnt exist, return a PEAR error. - * @return string - * preference value - */ - function loadGroupPref($group, $key, $returnErrorIfKeyNotExists = true) - { - // if sessid is would be used here fix Transport::cronCallMethod ! - $subjid = Subjects::GetSubjId($group); - if (PEAR::isError($subjid)) { - return $subjid; - } - if (is_null($subjid)) { - return PEAR::raiseError( - "Prefs::loadGroupPref: invalid group name", ALIBERR_NOTGR); - } - $val = $this->readVal($subjid, $key); - if (PEAR::isError($val)) { - return $val; - } - if ($val === FALSE) { - if ($returnErrorIfKeyNotExists) { - return PEAR::raiseError( - "Prefs::loadGroupPref: invalid preference key", GBERR_PREF); - } else { - return ''; - } - } - return $val; - } - - - /** - * Save group preference record - * - * @param string $sessid - * session id - * @param string $group - * group name - * @param string $key - * preference key - * @param string $value - * preference value - * @return boolean - */ - function saveGroupPref($sessid, $group, $key, $value) - { - $uid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($uid)) { - return $uid; - } - if (is_null($uid)) { - return PEAR::raiseError( - "Prefs::saveGroupPref: invalid session id", GBERR_SESS); - } - $gid = Subjects::GetSubjId($group); - if (PEAR::isError($gid)) { - return $gid; - } - if (is_null($gid)) { - return PEAR::raiseError( - "Prefs::saveGroupPref: invalid group name", GBERR_SESS); - } - $memb = Subjects::IsMemberOf($uid, $gid); - if (PEAR::isError($memb)) { - return $memb; - } - if (!$memb) { - return PEAR::raiseError( - "Prefs::saveGroupPref: access denied", GBERR_DENY); - } - $r = $this->update($gid, $key, $value); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - $r = $this->insert($gid, $key, $value); - if (PEAR::isError($r)) { - return $r; - } - } - return TRUE; - } - - /** - * Delete group preference record - * - * @param string $sessid - * session id - * @param string $group - * group name - * @param string $key - * preference key - * @return boolean - */ - function delGroupPref($sessid, $group, $key) - { - $uid = GreenBox::GetSessUserId($sessid); - if (PEAR::isError($uid)) { - return $uid; - } - if (is_null($uid)) { - return PEAR::raiseError( - "Prefs::delGroupPref: invalid session id", GBERR_SESS); - } - $gid = Subjects::GetSubjId($group); - if (PEAR::isError($gid)) { - return $gid; - } - if (is_null($gid)) { - return PEAR::raiseError( - "Prefs::delGroupPref: invalid group name", GBERR_SESS); - } - $memb = Subjects::IsMemberOf($uid, $gid); - if (PEAR::isError($memb)) { - return $memb; - } - if (!$memb) { - return PEAR::raiseError( - "Prefs::delGroupPref: access denied", GBERR_DENY); - } - $r = $this->delete($gid, $key); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - return PEAR::raiseError( - "Prefs::delGroupPref: invalid preference key", GBERR_PREF); - } - return TRUE; - } - - - /* ==================================================== low level methods */ - /** - * Insert of new preference record - * - * @param int $subjid - * local user/group id - * @param string $keystr - * preference key - * @param string $valstr - * preference value - * @return int - * local user id - */ - public static function Insert($subjid, $keystr, $valstr='') - { - global $CC_CONFIG, $CC_DBC; - $id = $CC_DBC->nextId($CC_CONFIG['prefSequence']); - if (PEAR::isError($id)) { - return $id; - } - $r = $CC_DBC->query(" - INSERT INTO ".$CC_CONFIG['prefTable']." - (id, subjid, keystr, valstr) - VALUES - ($id, $subjid, '$keystr', '$valstr') - "); - if (PEAR::isError($r)) { - return $r; - } - return $id; - } - - - /** - * Read value of preference record - * - * @param int $subjid - * local user/group id - * @param string $keystr - * preference key - * @return string - * preference value - */ - function readVal($subjid, $keystr) - { - global $CC_CONFIG, $CC_DBC; - $val = $CC_DBC->getOne(" - SELECT valstr FROM ".$CC_CONFIG['prefTable']." - WHERE subjid=$subjid AND keystr='$keystr' - "); - if (PEAR::isError($val)) { - return $val; - } - if (is_null($val)) { - return FALSE; - } - return $val; - } - - - /** - * Read all keys of subject's preferences - * - * @param int $subjid - * local user/group id - * @return array - * preference keys - */ - function readKeys($subjid) - { - global $CC_CONFIG, $CC_DBC; - $res = $CC_DBC->getAll(" - SELECT keystr FROM ".$CC_CONFIG['prefTable']." - WHERE subjid=$subjid - "); - if (PEAR::isError($res)) { - return $res; - } - if (is_null($res)) { - return FALSE; - } - return $res; - } - - - /** - * Update value of preference record - * - * @param int $subjid - * local user/group id - * @param string $keystr - * preference key - * @param string $newvalstr - * new preference value - * @return boolean - */ - function update($subjid, $keystr, $newvalstr='') - { - global $CC_CONFIG, $CC_DBC; - $r = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['prefTable']." SET - valstr='$newvalstr' - WHERE subjid=$subjid AND keystr='$keystr' - "); - if (PEAR::isError($r)) { - return $r; - } - if ($CC_DBC->affectedRows() < 1) { - return FALSE; - } - return TRUE; - } - - - /** - * Delete preference record - * - * @param int $subjid - * local user/group id - * @param string $keystr - * preference key - * @return boolean - */ - function delete($subjid, $keystr) - { - global $CC_CONFIG, $CC_DBC; - $r = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['prefTable']." - WHERE subjid=$subjid AND keystr='$keystr' - "); - if (PEAR::isError($r)) { - return $r; - } - if ($CC_DBC->affectedRows() < 1) { - return FALSE; - } - return TRUE; - } - - - /* ==================================================== auxiliary methods */ - /** - * Test method - * - */ - function test() - { - global $CC_CONFIG; - $sessid = Alib::Login('root', $CC_CONFIG['tmpRootPass']); - $testkey = 'testKey'; - $testVal = 'abcDef 0123 ěščřžýáíé ĚŠČŘŽÝÁÍÉ'; - $r = savePref($sessid, $testKey, $testVal); - if (PEAR::isError($r)) { - return $r; - } - $val = loadPref($sessid, $testKey); - if ($val != $testVal) { - echo "ERROR: preference storage test failed.\n ($testVal / $val)\n"; - return FALSE; - } - $r = savePref($sessid, $testKey, ''); - if (PEAR::isError($r)) { - return $r; - } - $val = loadPref($sessid, $testKey); - if ($val != $testVal) { - echo "ERROR: preference storage test failed.\n ('' / '$val')\n"; - return FALSE; - } - return TRUE; - } - -} // class Prefs -?> \ No newline at end of file diff --git a/backend/Renderer.php b/backend/Renderer.php deleted file mode 100644 index 81d636b70..000000000 --- a/backend/Renderer.php +++ /dev/null @@ -1,290 +0,0 @@ -outputToSmil(); - if (PEAR::isError($smil)) { - return $smil; - } - // temporary file for smil: - $tmpn = tempnam($CC_CONFIG['bufferDir'], 'plRender_'); - $smilf = "$tmpn.smil"; - file_put_contents($smilf, $smil); - $url = "file://$smilf"; - // output file: - $outf = "$tmpn.".RENDER_EXT; - touch($outf); - // logging: - $logf = $CC_CONFIG['bufferDir']."/renderer.log"; - file_put_contents($logf, "--- ".date("Ymd-H:i:s")."\n", FILE_APPEND); - // open access to output file: /*gunid*/ /*parent*/ - $acc = BasicStor::bsAccess($outf, RENDER_EXT, $plid, 'render', 0, $owner); - if (PEAR::isError($acc)) { - return $acc; - } - extract($acc); - $statf = Renderer::getStatusFile($gb, $token); - file_put_contents($statf, "working"); - // command: - $stServDir = dirname(__FILE__)."/.."; - $renderExe = "$stServDir/bin/renderer.sh"; - $command = "$renderExe -p $url -o $outf -s $statf >> $logf &"; - file_put_contents($logf, "$command\n", FILE_APPEND); - $res = system($command); - if ($res === FALSE) { - return PEAR::raiseError( - 'Renderer::rnRender2File: Error running renderer' - ); - } - return array('token'=>$token); - } - - - /** - * Render playlist to ogg file (check results) - * - * @param GreenBox $gb - * GreenBox object reference - * @param string $token - * render token - * @return array - * status : string - success | working | fault - * url : string - readable url - */ - function rnRender2FileCheck(&$gb, $token) - { - $statf = Renderer::getStatusFile($gb, $token); - if (!file_exists($statf)) { - return PEAR::raiseError( - 'Renderer::rnRender2FileCheck: Invalid token' - ); - } - $status = trim(file_get_contents($statf)); - $url = Renderer::getUrl($gb, $token); - $tmpfile= Renderer::getLocalFile($gb, $token); - return array('status'=>$status, 'url'=>$url, 'tmpfile'=>$tmpfile); - } - - - /** - * Render playlist to ogg file (list results) - * - * @param GreenBox $gb - * greenbox object reference - * @param string $stat - * status (optional) if this parameter is not set, then return with all unclosed backups - * @return array - * array of hasharray: - * status : string - success | working | fault - * url : string - readable url - */ - function rnRender2FileList(&$gb,$stat='') { - // open temporary dir - $tokens = BasicStor::GetTokensByType('render'); - foreach ($tokens as $token) { - $st = Renderer::rnRender2FileCheck($gb, $token); - if ( ($stat=='') || ($st['status']==$stat) ) { - $r[] = $st; - } - } - return $r; - } - - - /** - * Render playlist to ogg file (close handle) - * - * @param GreenBox $gb - * greenbox object reference - * @param string $token - * render token - * @return mixed - * TRUE or PEAR_Error - */ - function rnRender2FileClose(&$gb, $token) - { - global $CC_CONFIG; - $r = BasicStor::bsRelease($token, 'render'); - if (PEAR::isError($r)) { - return $r; - } - $realOgg = $r['realFname']; - $tmpn = $CC_CONFIG['bufferDir']."/".basename($realOgg, '.'.RENDER_EXT); - $smilf = "$tmpn.smil"; - $statf = Renderer::getStatusFile($gb, $token); - @unlink($statf); - @unlink($realOgg); - @unlink($smilf); - @unlink($tmpn); - return TRUE; - } - - - /** - * Render playlist to storage as audioClip (check results) - * - * @param GreenBox $gb - * greenbox object reference - * @param string $token - * render token - * @return array - * status : string - success | working | fault - * gunid: string - global unique id of result file - */ - function rnRender2StorageCheck(&$gb, $token) - { - $r = Renderer::rnRender2FileCheck($gb, $token); - if (PEAR::isError($r)) { - return $r; - } - $status = $r['status']; - $res = array('status' => $status, 'gunid'=>'NULL'); - switch ($status) { - case "fault": - $res['faultString'] = "Error runing renderer"; - break; - case "success": - $r = Renderer::rnRender2StorageCore($gb, $token); - if (PEAR::isError($r)) { - return $r; - } - $res['gunid'] = $r['gunid']; - break; - default: - break; - } - return $res; - } - - - /** - * Render playlist to storage as audioClip (core method) - * - * @param GreenBox $gb - * greenbox object reference - * @param string $token - * render token - * @return array: - * gunid: string - global unique id of result file - */ - function rnRender2StorageCore(&$gb, $token) - { - // $r = BasicStor::bsRelease($token, 'render'); - // if (PEAR::isError($r)) { - // return $r; - // } - // $realOgg = $r['realFname']; - // $owner = $r['owner']; - // $gunid = $r['gunid']; - // $fileName = 'rendered_playlist'; - // $id = BasicStor::IdFromGunid($gunid); - // if (PEAR::isError($id)) { - // return $id; - // } - // $mdata = ''; - // foreach (array('dc:title', 'dcterms:extent', 'dc:creator', 'dc:description') as $item) { - // $val = $gb->bsGetMetadataValue($id, $item); - // $mdata .= " <$item>$val\n"; - // } - // $mdata = "\n \n$mdata \n\n"; - // //$mdata = "\n \n$mdata0\n\n\n"; - // $values = array( - // "filename" => $fileName, - // "filepath" => $realOgg, - // "metadata" => $mdata, - // "filetype" => "audioclip" - // ); - // $storedFile = $gb->bsPutFile($values); - // if (PEAR::isError($storedFile)) { - // return $storedFile; - // } - // return array('gunid' => $storedFile->getGunid()); - } - - - /** - * Return local filepath of rendered file - * - * @param Greenbox $gb - * greenbox object reference - * @param string $token - * render token - * @return array - */ - function getLocalFile(&$gb, $token) - { - global $CC_CONFIG; - $token = StoredFile::NormalizeGunid($token); - return $CC_CONFIG['accessDir']."/$token.".RENDER_EXT; - } - - - /** - * Return filepath of render status file - * - * @param GreenBox $gb - * greenbox object reference - * @param string $token - * render token - * @return array - */ - function getStatusFile(&$gb, $token) - { - return Renderer::getLocalFile($gb, $token).".status"; - } - - - /** - * Return remote accessible URL for rendered file - * - * @param GreenBox $gb - * greenbox object reference - * @param string $token - * render token - * @return array - */ - function getUrl(&$gb, $token) - { - $token = StoredFile::NormalizeGunid($token); - return BasicStor::GetUrlPart()."access/$token.".RENDER_EXT; - } - -} // class Renderer - -?> \ No newline at end of file diff --git a/backend/Restore.php b/backend/Restore.php deleted file mode 100644 index 892c0f19f..000000000 --- a/backend/Restore.php +++ /dev/null @@ -1,436 +0,0 @@ -gb =& $gb; - $this->token = null; - $this->logFile = $CC_CONFIG['bufferDir'].'/'.$this->ACCESS_TYPE.'.log'; - if ($this->loglevel == 'debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." construct\n"); - } - } - - - /** - * Call asyncronously the restore procedure. Restore from backup. - * - * @param string $sessid - * session id - * @param string $backup_file - * path of the backup file - * @return array - * hasharray with field: - * token string: backup token - */ - function openRestore($sessid, $backup_file) - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I-".date("Ymd-H:i:s")." doRestore - sessid:$sessid\n"); - } - $this->sessid = $sessid; - - // generate token - $this->token = StoredFile::CreateGunid(); - - // status file -> working - $this->setEnviroment(); - file_put_contents($this->statusFile, 'working'); - - //call the restore script in background - $command = dirname(__FILE__).'/../bin/restore.php'; - $runLog = "/dev/null"; - $params = "{$backup_file} {$this->statusFile} {$this->token} {$sessid}>> $runLog &"; - $ret = system("$command $params", $st); - if ($this->loglevel=='debug') { - $this->addLogItem("-I-".date("Ymd-H:i:s")." restore.php call: $st/$ret\n"); - } - - return array('token'=>$this->token); - } - - - /** - * Check the status of restore - * - * @param string $token - * @return array - * hasharray with field: - * status : string - susccess | working | fault - * faultString : string - description of fault - * token : stirng - backup token - * url : string - access url - * tmpfile : string - access filename - */ - function checkRestore($token) - { - if ($this->loglevel == 'debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n"); - } - $this->token = $token; - $this->setEnviroment(); - if (is_file($this->statusFile)) { - $r = array(); - $stat = file_get_contents($this->statusFile); - if (strpos($stat,'fault|') !== false) { - list($stat,$message) = explode('|',$stat); - } - $r['status'] = $stat; - if ($stat=='fault') { - $r['faultString'] = $message; - } else { - $r['faultString'] = ''; - } - return $r; - } else { - return PEAR::raiseError('Restore::checkRestore: invalid token!'); - } - } - - - /** - * Check the status of restore. - * - * @param string $token - * @return array - * hasharray with field: - * status : boolean - is success - */ - function closeRestore($token) - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n"); - } - $this->token = $token; - $this->setEnviroment(); - $this->rRmDir($this->tmpDir); - unlink($this->statusFile); - return array("status" => !is_file($this->statusFile)); - } - - - /** - * Do restore in background - * - * this function is called from the asyncron commandline script - * ../bin/restore.php - * - * @param string $backupfile - * path of backupfile - * @param string $token - * restore token - * @param string $sessid - * session id - */ - function startRestore($backupfile, $token, $sessid) - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." startRestore - bufile:$backupfile | token:$token\n"); - } - $this->token = $token; - $this->sessid = $sessid; - $this->setEnviroment(); - - // extract tarball - $command = 'tar -xf '.$backupfile .' --directory '.$this->tmpDir; - $res = system($command); - //$this->addLogItem('command: '.$command."\n"); - //$this->addLogItem('res: '.$res."\n"); - - //simple check of archive format - if (is_dir($this->tmpDir.'audioClip/') && - is_dir($this->tmpDir.'meta-inf/') && - is_dir($this->tmpDir.'playlist/')) { - //search metafiles - $this->metafiles = $this->getMetaFiles(); - #$this->addLogItem('metafiles:'.print_r($this->metafiles,true)); - //add to storage server - foreach ($this->metafiles as $info) { - $r = $this->addFileToStorage($info['file'],$info['type'],$info['id']); - if (PEAR::isError($r)) { - $this->addLogItem("-E- ".date("Ymd-H:i:s"). - " startRestore - addFileToStorage \n". - "(".$put->getMessage()."/".$put->getUserInfo().")\n" - ); - file_put_contents($this->statusFile, 'fault|'.$put->getMessage()."/".$put->getUserInfo()); - return; - } - } - } else { - $this->addLogItem("-E- ".date("Ymd-H:i:s")." startRestore - invalid archive format\n"); - file_put_contents($this->statusFile, 'fault|invalid archive format'); - return; - } - file_put_contents($this->statusFile, 'success'); - // unlink($backupfile); - } - - - /** - * Get the metafiles. - * - * @return array - * array of hasharray with field: - * file : string - metafile path - * type : stirng - audioClip | playlist - * id : string - the backuped gunid - */ - function getMetaFiles() - { - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." getMetaFiles - tmpDir:{$this->tmpDir}\n"); - } - $audioclips = scandir($this->tmpDir.'audioClip/'); - $playlists = scandir($this->tmpDir.'playlist/'); - for ($i = 0; $i < count($audioclips); $i++) { - if (strpos($audioclips[$i],'xml')!==false) - $r[] = array('file' => $this->tmpDir.'audioClip/'.$audioclips[$i], - 'type' => 'audioClip', - 'id' => str_replace('.xml','',$audioclips[$i])); - } - for ($i = 0; $i < count($playlists); $i++) { - if (strpos($playlists[$i],'xml') !== false) - $r[] = array('file' => $this->tmpDir.'playlist/'.$playlists[$i], - 'type' => 'playlist', - 'id' => str_replace('.xml','',$playlists[$i])); - } - return $r; - } - - - /** - * Add the file to the storage server. - * - * @param string $file - * path of metafile - * @param string $type - * restore token - * @param string $sessid - * session id - * - * @return mixed - * true if success or PEAR_error - */ - // function addFileToStorage($file,$type,$gunid) - // { - // if ($this->loglevel=='debug') { - // $this->addLogItem("-I- ".date("Ymd-H:i:s")." addFileToStorage - file:$file | type:$type | id:$gunid\n"); - // } - // require_once("XmlParser.php"); - // $tree = XmlParser::parse($file); - // $mediaFileLP = str_replace('.xml','',$file); - // $mediaFileLP = ($type=='audioClip' && is_file($mediaFileLP))?$mediaFileLP:''; - // $ex = $this->gb->existsFile($this->sessid,$gunid); - // if (PEAR::isError($ex)) { - // $this->addLogItem("-E- ".date("Ymd-H:i:s"). - // " addFileToStorage - existsFile($gunid) ". - // "(".$ex->getMessage()."/".$ex->getUserInfo().")\n" - // ); - // } - // if (!PEAR::isError($ex) && $ex) { // file is exists in storage server - // //replace it - // $id = BasicStor::IdFromGunid($gunid); - // $replace = $this->gb->replaceFile( - // $id, # id int, virt.file's local id - // $mediaFileLP, # mediaFileLP string, local path of media file - // $file, # mdataFileLP string, local path of metadata file - // $this->sessid); # sessid string, session id - // if (PEAR::isError($replace)) { - // $this->addLogItem("-E- ".date("Ymd-H:i:s"). - // " addFileToStorage - replaceFile Error ". - // "(".$replace->getMessage()."/".$replace->getUserInfo().")\n" - // ); - // file_put_contents($this->statusFile, 'fault|'.$replace->getMessage()."/".$replace->getUserInfo()); - // return $replace; - // } - // #$this->addLogItem("replace it \n"); - // } else { - // // add as new - // $name = $tree->children[0]->children[0]->content; - // if (empty($name)) { - // $name = $tree->attrs['title']->val; - // } - // if (empty($name)) { - // $name = '???'; - // } - // if ($this->loglevel=='debug') { - // $this->addLogItem("-I- ".date("Ymd-H:i:s")." putFile\n". - // "$name, $mediaFileLP, $file, {$this->sessid}, $gunid, $type \n" - // ); - // } - // $values = array( - // "filename" => $name, - // "filepath" => $mediaFileLP, - // "metadata" => $file, - // "gunid" => $gunid, - // "filetype" => $type - // ); - // $put = $this->gb->putFile($values, $this->sessid); - // //$this->addLogItem("add as new \n"); - // if (PEAR::isError($put)) { - // $this->addLogItem("-E- ".date("Ymd-H:i:s"). - // " addFileToStorage - putFile Error ". - // "(".$put->getMessage()."/".$put->getUserInfo().")\n" - // ."\n---\n".file_get_contents($file)."\n---\n" - // ); - // file_put_contents($this->statusFile, 'fault|'.$put->getMessage()."/".$put->getUserInfo()); - // //$this->addLogItem("Error Object: ".print_r($put,true)."\n"); - // return $put; - // } - // } - // $ac = StoredFile::RecallByGunid($gunid); - // if (is_null($ac) || PEAR::isError($ac)) { - // return $ac; - // } - // $res = $ac->setState('ready'); - // if (PEAR::isError($res)) { - // return $res; - // } - // return true; - // } - - - /** - * Figure out the environment to the backup. - * - */ - function setEnviroment() - { - global $CC_CONFIG; - if ($this->loglevel=='debug') { - $this->addLogItem("-I- ".date("Ymd-H:i:s")." setEnviroment\n"); - } - $this->statusFile = $CC_CONFIG['accessDir'].'/'.$this->token.'.status'; - $this->tmpDir = '/tmp/ls_restore/'.$this->token.'/'; - $this->rMkDir($this->tmpDir); - } - - - /** - * Add a line to the logfile. - * - * @param string $item - * the new row of log file - */ - function addLogItem($item) - { - $f = fopen ($this->logFile,'a'); - flock($f,LOCK_SH); - fwrite($f,$item); - flock($f,LOCK_UN); - fclose($f); - //echo file_get_contents($this->logFile)."

\n\n"; - } - - - /** - * Delete a directory recursive - * - * @param string $dirname - * path of dir - * - * @return boolean - * is success - */ - function rRmDir($dirname) - { - if (is_dir($dirname)) { - $dir_handle = opendir($dirname); - } - while ($file = readdir($dir_handle)) { - if ($file!="." && $file!="..") { - if (!is_dir($dirname."/".$file)) { - unlink ($dirname."/".$file); - } else { - Restore::rRmDir($dirname."/".$file); - } - } - } - closedir($dir_handle); - rmdir($dirname); - return true; - } - - - /** - * Create a directory recursive - * - * @param string $dirname - * path of dir. - * @param int $mode - * octal - rights of dir. - * @param boolean $recursive - * do it recursive. - * - * @return boolean - */ - function rMkDir($dirname, $mode=0777, $recursive=true) - { - if (is_null($dirname) || $dirname === "" ) { - return false; - } - if (is_dir($dirname) || $dirname === "/" ) { - return true; - } - if ($this->rMkDir(dirname($dirname), $mode, $recursive)) { - return mkdir($dirname, $mode); - } - return false; - } - -} // class Restore -?> diff --git a/backend/Schedule.php b/backend/Schedule.php deleted file mode 100644 index fa80671f3..000000000 --- a/backend/Schedule.php +++ /dev/null @@ -1,560 +0,0 @@ -groupId = $p_groupId; - } - - /** - * Return true if the schedule group exists in the DB. - * @return boolean - */ - public function exists() { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT COUNT(*) FROM ".$CC_CONFIG['scheduleTable'] - ." WHERE group_id=".$this->groupId; - $result = $CC_DBC->GetOne($sql); - if (PEAR::isError($result)) { - return $result; - } - return $result != "0"; - } - - /** - * Convert a date to an ID by stripping out all characters - * and padding with zeros. - * - * @param string $p_dateStr - */ - public static function dateToId($p_dateStr) { - $p_dateStr = str_replace(":", "", $p_dateStr); - $p_dateStr = str_replace(" ", "", $p_dateStr); - $p_dateStr = str_replace(".", "", $p_dateStr); - $p_dateStr = str_replace("-", "", $p_dateStr); - $p_dateStr = substr($p_dateStr, 0, 17); - $p_dateStr = str_pad($p_dateStr, 17, "0"); - return $p_dateStr; - } - - /** - * Add the two times together, return the result. - * - * @param string $p_baseTime - * Specified as YYYY-MM-DD HH:MM:SS - * - * @param string $p_addTime - * Specified as HH:MM:SS.nnnnnn - * - * @return string - * The end time, to the nearest second. - */ - // protected function calculateEndTime($p_startTime, $p_trackTime) { - // $p_trackTime = substr($p_startTime, 0, ); - // $start = new DateTime(); - // $interval = new DateInterval() - // - // } - - /** - * Add a music clip or playlist to the schedule. - * - * @param $p_datetime - * In the format YYYY-MM-DD HH:MM:SS.mmmmmm - * @param $p_audioFileId - * (optional, either this or $p_playlistId must be set) DB ID of the audio file - * @param $p_playlistId - * (optional, either this of $p_audioFileId must be set) DB ID of the playlist - * @param $p_options - * Does nothing at the moment. - * - * @return int|PEAR_Error - * Return PEAR_Error if the item could not be added. - * Error code 555 is a scheduling conflict. - */ - public function add($p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) { - global $CC_CONFIG, $CC_DBC; - if (!is_null($p_audioFileId)) { - // Schedule a single audio track - - // Load existing track - $track = StoredFile::Recall($p_audioFileId); - if (is_null($track)) { - return new PEAR_Error("Could not find audio track."); - } - - // Check if there are any conflicts with existing entries - $metadata = $track->getMetadata(); - $length = trim($metadata["length"]); - if (empty($length)) { - return new PEAR_Error("Length is empty."); - } - if (!Schedule::isScheduleEmptyInRange($p_datetime, $length)) { - return new PEAR_Error("Schedule conflict.", 555); - } - - // Insert into the table - $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); - $sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"] - ." (id, playlist_id, starts, ends, clip_length, group_id, file_id)" - ." VALUES ($id, 0, TIMESTAMP '$p_datetime', " - ." (TIMESTAMP '$p_datetime' + INTERVAL '$length')," - ." '$length'," - ." {$this->groupId}, $p_audioFileId)"; - $result = $CC_DBC->query($sql); - if (PEAR::isError($result)) { - //var_dump($sql); - return $result; - } - return $this->groupId; - - } elseif (!is_null($p_playlistId)){ - // Schedule a whole playlist - - // Load existing playlist - $playlist = Playlist::Recall($p_playlistId); - if (is_null($playlist)) { - return new PEAR_Error("Could not find playlist."); - } - - // Check if there are any conflicts with existing entries - $length = trim($playlist->getLength()); - //var_dump($length); - if (empty($length)) { - return new PEAR_Error("Length is empty."); - } - if (!Schedule::isScheduleEmptyInRange($p_datetime, $length)) { - return new PEAR_Error("Schedule conflict.", 555); - } - - // Insert all items into the schedule - $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); - $itemStartTime = $p_datetime; - - $plItems = $playlist->getContents(); - //var_dump($plItems); - foreach ($plItems as $row) { - $trackLength = $row["cliplength"]; - //var_dump($trackLength); - $sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"] - ." (id, playlist_id, starts, ends, group_id, file_id," - ." clip_length, cue_in, cue_out, fade_in, fade_out)" - ." VALUES ($id, $p_playlistId, TIMESTAMP '$itemStartTime', " - ." (TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength')," - ." '{$this->groupId}', '{$row['file_id']}', '$trackLength', '{$row['cuein']}'," - ." '{$row['cueout']}', '{$row['fadein']}','{$row['fadeout']}')"; - $result = $CC_DBC->query($sql); - if (PEAR::isError($result)) { - //var_dump($sql); - return $result; - } - $itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'"); - $id = $this->dateToId($itemStartTime); - } - return $this->groupId; - } - } - - public function addAfter($p_groupId, $p_audioFileId) { - global $CC_CONFIG, $CC_DBC; - // Get the end time for the given entry - $sql = "SELECT ends FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE group_id=$p_groupId"; - $startTime = $CC_DBC->GetOne($sql); - return $this->add($startTime, $p_audioFileId); - } - - public function update() { - - } - - /** - * Remove the group from the schedule. - * Note: does not check if it is in the past, you can remove anything. - * - * @return boolean - * TRUE on success, false if there is no group ID defined. - */ - public function remove() { - global $CC_CONFIG, $CC_DBC; - if (is_null($this->groupId) || !is_numeric($this->groupId)) { - return false; - } - $sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE group_id = ".$this->groupId; - //echo $sql; - return $CC_DBC->query($sql); - } - - /** - * Return the number of items in this group. - * @return string - */ - public function count() { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT COUNT(*) FROM {$CC_CONFIG['scheduleTable']}" - ." WHERE group_id={$this->groupId}"; - return $CC_DBC->GetOne($sql); - } - - /* - * Return the list of items in this group as a 2D array. - * @return array - */ - public function getItems() { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT * FROM {$CC_CONFIG['scheduleTable']}" - ." WHERE group_id={$this->groupId}"; - return $CC_DBC->GetAll($sql); - } - - public function reschedule($toDateTime) { - global $CC_CONFIG, $CC_DBC; - // $sql = "UPDATE ".$CC_CONFIG["scheduleTable"]. " SET id=, starts=,ends=" - } - - public function notifyGroupStartPlay() { - global $CC_CONFIG, $CC_DBC; - $sql = "UPDATE ".$CC_CONFIG['scheduleTable'] - ." SET schedule_group_played=TRUE" - ." WHERE group_id=".$this->groupId; - return $CC_DBC->query($sql); - } - - public function notifyMediaItemStartPlay($p_fileId) { - global $CC_CONFIG, $CC_DBC; - $sql = "UPDATE ".$CC_CONFIG['scheduleTable'] - ." SET media_item_played=TRUE" - ." WHERE group_id=".$this->groupId - ." AND file_id=".pg_escape_string($p_fileId); - return $CC_DBC->query($sql); - } -} - -class Schedule { - - function __construct() { - - } - - /** - * Return true if there is nothing in the schedule for the given start time - * up to the length of time after that. - * - * @param string $p_datetime - * In the format YYYY-MM-DD HH:MM:SS.mmmmmm - * @param string $p_length - * In the format HH:MM:SS.mmmmmm - * @return boolean|PEAR_Error - */ - public static function isScheduleEmptyInRange($p_datetime, $p_length) { - global $CC_CONFIG, $CC_DBC; - if (empty($p_length)) { - return new PEAR_Error("Schedule::isSchedulerEmptyInRange: param p_length is empty."); - } - $sql = "SELECT COUNT(*) FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE (starts >= '$p_datetime') " - ." AND (ends <= (TIMESTAMP '$p_datetime' + INTERVAL '$p_length'))"; - //$_SESSION["debug"] = $sql; - //var_dump($sql); - $count = $CC_DBC->GetOne($sql); - //var_dump($count); - return ($count == '0'); - } - - // public function onAddTrackToPlaylist($playlistId, $audioTrackId) { - // - // } - // - // public function onRemoveTrackFromPlaylist($playlistId, $audioTrackId) { - // - // } - - /** - * Return TRUE if file is going to be played in the future. - * - * @param string $p_fileId - */ - public function IsFileScheduledInTheFuture($p_fileId) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT COUNT(*) FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE file_id = {$p_fileId} AND starts > NOW()"; - $count = $CC_DBC->GetOne($sql); - if (is_numeric($count) && ($count != '0')) { - return TRUE; - } else { - return FALSE; - } - } - - - /** - * Returns array indexed numberically of: - * "playlistId"/"playlist_id" (aliases to the same thing) - * "start"/"starts" (aliases to the same thing) as YYYY-MM-DD HH:MM:SS.nnnnnn - * "end"/"ends" (aliases to the same thing) as YYYY-MM-DD HH:MM:SS.nnnnnn - * "group_id"/"id" (aliases to the same thing) - * "clip_length" (for audio clips this is the length of the audio clip, - * for playlists this is the length of the entire playlist) - * "name" (playlist only) - * "creator" (playlist only) - * "file_id" (audioclip only) - * "count" (number of items in the playlist, always 1 for audioclips. - * Note that playlists with one item will also have count = 1. - * - * @param string $p_fromDateTime - * In the format YYYY-MM-DD HH:MM:SS.nnnnnn - * @param string $p_toDateTime - * In the format YYYY-MM-DD HH:MM:SS.nnnnnn - * @param boolean $p_playlistsOnly - * Retreive playlists as a single item. - * @return array - * Returns empty array if nothing found - */ - public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true) { - global $CC_CONFIG, $CC_DBC; - $rows = array(); - if (!$p_playlistsOnly) { - $sql = "SELECT * FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE (starts >= TIMESTAMP '$p_fromDateTime') " - ." AND (ends <= TIMESTAMP '$p_toDateTime')"; - $rows = $CC_DBC->GetAll($sql); - foreach ($rows as &$row) { - $row["count"] = "1"; - $row["playlistId"] = $row["playlist_id"]; - $row["start"] = $row["starts"]; - $row["end"] = $row["ends"]; - $row["id"] = $row["group_id"]; - } - } else { - $sql = "SELECT MIN(name) AS name, MIN(creator) AS creator, group_id, " - ." SUM(clip_length) AS clip_length," - ." MIN(file_id) AS file_id, COUNT(*) as count," - ." MIN(playlist_id) AS playlist_id, MIN(starts) AS starts, MAX(ends) AS ends" - ." FROM ".$CC_CONFIG["scheduleTable"] - ." LEFT JOIN ".$CC_CONFIG["playListTable"]." ON playlist_id = ".$CC_CONFIG["playListTable"].".id" - ." WHERE (starts >= TIMESTAMP '$p_fromDateTime') AND (ends <= TIMESTAMP '$p_toDateTime')" - ." GROUP BY group_id" - ." ORDER BY starts"; - //var_dump($sql); - $rows = $CC_DBC->GetAll($sql); - if (!PEAR::isError($rows)) { - foreach ($rows as &$row) { - $row["playlistId"] = $row["playlist_id"]; - $row["start"] = $row["starts"]; - $row["end"] = $row["ends"]; - $row["id"] = $row["group_id"]; - } - } - } - return $rows; - } - - public function getSchedulerTime() { - - } - - public function getCurrentlyPlaying() { - - } - - public function getNextItem($nextCount = 1) { - - } - - public function getStatus() { - - } - - /** - * Convert a time string in the format "YYYY-MM-DD HH:mm:SS" - * to "YYYY-MM-DD-HH-mm-SS". - * - * @param string $p_time - * @return string - */ - private static function CcTimeToPypoTime($p_time) - { - $p_time = substr($p_time, 0, 19); - $p_time = str_replace(" ", "-", $p_time); - $p_time = str_replace(":", "-", $p_time); - return $p_time; - } - - /** - * Convert a time string in the format "YYYY-MM-DD-HH-mm-SS" to - * "YYYY-MM-DD HH:mm:SS". - * - * @param string $p_time - * @return string - */ - private static function PypoTimeToCcTime($p_time) - { - $t = explode("-", $p_time); - return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00"; - } - - /** - * Converts a time value as a string (with format HH:MM:SS.mmmmmm) to - * millisecs. - * - * @param string $p_time - * @return int - */ - private static function WallTimeToMillisecs($p_time) - { - $t = explode(":", $p_time); - $millisecs = 0; - if (strpos($t[2], ".")) { - $secParts = explode(".", $t[2]); - $millisecs = $secParts[1]; - $millisecs = substr($millisecs, 0, 3); - $millisecs = intval($millisecs); - $seconds = intval($secParts[0]); - } else { - $seconds = intval($t[2]); - } - $ret = $millisecs + ($seconds * 1000) + ($t[1] * 60 * 1000) + ($t[0] * 60 * 60 * 1000); - return $ret; - } - - - /** - * Compute the difference between two times in the format "HH:MM:SS.mmmmmm". - * Note: currently only supports calculating millisec differences. - * - * @param string $p_time1 - * @param string $p_time2 - * @return double - */ - private static function TimeDiff($p_time1, $p_time2) - { - $parts1 = explode(".", $p_time1); - $parts2 = explode(".", $p_time2); - $diff = 0; - if ( (count($parts1) > 1) && (count($parts2) > 1) ) { - $millisec1 = substr($parts1[1], 0, 3); - $millisec1 = str_pad($millisec1, 3, "0"); - $millisec1 = intval($millisec1); - $millisec2 = substr($parts2[1], 0, 3); - $millisec2 = str_pad($millisec2, 3, "0"); - $millisec2 = intval($millisec2); - $diff = abs(millisec1 - millisec2)/1000; - } - return $diff; - } - - - /** - * Export the schedule in json formatted for pypo (the liquidsoap scheduler) - * - * @param string $range - * In the format "YYYY-MM-DD HH:mm:ss" - * @param string $source - * In the format "YYYY-MM-DD HH:mm:ss" - */ - public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime) - { - global $CC_CONFIG, $CC_DBC; - $range_start = Schedule::PypoTimeToCcTime($p_fromDateTime); - $range_end = Schedule::PypoTimeToCcTime($p_toDateTime); - $range_dt = array('start' => $range_start, 'end' => $range_end); - //var_dump($range_dt); - - // Scheduler wants everything in a playlist - $data = Schedule::GetItems($range_start, $range_end, true); - //echo "
";var_dump($data);
-        $playlists = array();
-
-        if (is_array($data) && count($data) > 0)
-        {
-            foreach ($data as $dx)
-            {
-                // Is this the first item in the playlist?
-                $start = $dx['start'];
-                // chop off subseconds
-                $start = substr($start, 0, 19);
-
-                // Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss"
-                $pkey = Schedule::CcTimeToPypoTime($start);
-                $timestamp =  strtotime($start);
-                $playlists[$pkey]['source'] = "PLAYLIST";
-                $playlists[$pkey]['x_ident'] = $dx["playlist_id"];
-                $playlists[$pkey]['subtype'] = '1'; // Just needs to be between 1 and 4 inclusive
-                $playlists[$pkey]['timestamp'] = $timestamp;
-                $playlists[$pkey]['duration'] = $dx['clip_length'];
-                $playlists[$pkey]['played'] = '0';
-                $playlists[$pkey]['schedule_id'] = $dx['group_id'];
-                $playlists[$pkey]['user_id'] = 0;
-                $playlists[$pkey]['id'] = $dx["playlist_id"];
-            	$playlists[$pkey]['start'] = Schedule::CcTimeToPypoTime($dx["start"]);
-            	$playlists[$pkey]['end'] = Schedule::CcTimeToPypoTime($dx["end"]);
-            }
-        }
-
-        foreach ($playlists as &$playlist)
-        {
-            $scheduleGroup = new ScheduleGroup($playlist["schedule_id"]);
-            $items = $scheduleGroup->getItems();
-            $medias = array();
-            $playlist['subtype'] = '1';
-            foreach ($items as $item)
-            {
-                $storedFile = StoredFile::Recall($item["file_id"]);
-                $uri = $storedFile->getFileUrl();
-
-                // For pypo, a cueout of zero means no cueout
-                $cueOut = "0";
-                if (Schedule::TimeDiff($item["cue_out"], $item["clip_length"]) > 0.001) {
-                    $cueOut = Schedule::WallTimeToMillisecs($item["cue_out"]);
-                }
-                $medias[] = array(
-					'id' => $storedFile->getGunid(), //$item["file_id"],
-					'uri' => $uri,
-					'fade_in' => Schedule::WallTimeToMillisecs($item["fade_in"]),
-					'fade_out' => Schedule::WallTimeToMillisecs($item["fade_out"]),
-					'fade_cross' => 0,
-					'cue_in' => Schedule::WallTimeToMillisecs($item["cue_in"]),
-					'cue_out' => $cueOut,
-                    'export_source' => 'scheduler'
-                );
-            }
-            $playlist['medias'] = $medias;
-        }
-
-        $result = array();
-        $result['status'] = array('range' => $range_dt, 'version' => "0.2");
-        $result['playlists'] = $playlists;
-        $result['check'] = 1;
-
-        print json_encode($result);
-    }
-
-
-    /**
-     * Remove all items from the schedule in the given range.
-     *
-     * @param string $p_start
-     *    In the format YYYY-MM-DD HH:MM:SS.nnnnnn
-     * @param string $p_end
-     *    In the format YYYY-MM-DD HH:MM:SS.nnnnnn
-     */
-    public static function RemoveItemsInRange($p_start, $p_end)
-    {
-        $items = Schedule::GetItems($p_start, $p_end);
-        foreach ($items as $item) {
-            $scheduleGroup = new ScheduleGroup($item["group_id"]);
-            $scheduleGroup->remove();
-        }
-    }
-
-}
-
-?>
\ No newline at end of file
diff --git a/backend/SmilPlaylist.php b/backend/SmilPlaylist.php
deleted file mode 100644
index 739667dc8..000000000
--- a/backend/SmilPlaylist.php
+++ /dev/null
@@ -1,313 +0,0 @@
-lock($gb, $subjid);
-        if (PEAR::isError($r)) {
-            return $r;
-        }
-        $r = $pl->setMetadata($lspl, 'string', 'playlist');
-        if (PEAR::isError($r)) {
-            return $r;
-        }
-        $r = $pl->unlock($gb);
-        if (PEAR::isError($r)) {
-            return $r;
-        }
-        return $pl;
-    }
-
-
-    /**
-     * Import SMIL file to storage.
-     *
-     * @param GreenBox $gb
-     * @param string $data
-     * 		local path to SMIL file
-     * @param hasharray $gunids
-     * 		hash relation from filenames to gunids
-     * @param array $parr
-     * 		array of subjid, aPath, plid, rPath
-     * @return string
-     * 		XML of playlist in Campcaster playlist format
-     */
-    public static function convert2lspl(&$gb, $data, &$gunids, $parr)
-    {
-        extract($parr);
-        $tree = SmilPlaylist::parse($data);
-        if (PEAR::isError($tree)) {
-            return $tree;
-        }
-        if ($tree->name != 'smil') {
-            return PEAR::raiseError("SmilPlaylist::parse: smil tag expected");
-        }
-        if (isset($tree->children[1])) {
-            return PEAR::raiseError(sprintf(
-                "SmilPlaylist::parse: unexpected tag %s in tag smil",
-            $tree->children[1]->name
-            ));
-        }
-        $res = SmilPlaylistBodyElement::convert2lspl(
-        $gb, $tree->children[0], &$gunids, $parr);
-        return $res;
-    }
-
-} // SmilPlaylist
-
-
-/**
- * @package Campcaster
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class SmilPlaylistBodyElement {
-
-    public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
-    {
-        extract($parr);
-        $ind2 = $ind.INDCH;
-        if ($tree->name != 'body') {
-            return PEAR::raiseError("SmilPlaylist::parse: body tag expected");
-        }
-        if (isset($tree->children[1])) {
-            return PEAR::raiseError(sprintf(
-                "SmilPlaylist::parse: unexpected tag %s in tag body",
-            $tree->children[1]->name
-            ));
-        }
-        $res = SmilPlaylistParElement::convert2lspl(
-        $gb, $tree->children[0], &$gunids, $parr, $ind2);
-        if (PEAR::isError($res)) {
-            return $res;
-        }
-        $title = basename($rPath);
-        $playlength = '0';
-        $res = "$ind\n".
-            "$ind\n".
-            "$ind2\n".
-            "$res".
-            "$ind\n";
-        return $res;
-    }
-
-} // class SmilPlaylistBodyElement
-
-
-/**
- * @package Campcaster
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class SmilPlaylistParElement {
-
-    public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
-    {
-        extract($parr);
-        if ($tree->name != 'par') {
-            return PEAR::raiseError("SmilPlaylist::parse: par tag expected");
-        }
-        $res = '';
-        foreach ($tree->children as $i => $ch) {
-            $ch =& $tree->children[$i];
-            $r = SmilPlaylistAudioElement::convert2lspl($gb, $ch, &$gunids, $parr, $ind.INDCH);
-            if (PEAR::isError($r)) {
-                return $r;
-            }
-            $res .= $r;
-        }
-        return $res;
-    }
-}
-
-
-/**
- * @package Campcaster
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class SmilPlaylistAudioElement {
-    public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
-    {
-        extract($parr);
-        $uri = $tree->attrs['src']->val;
-        $gunid  = ( isset($gunids[basename($uri)]) ?  $gunids[basename($uri)] : NULL);
-        $ind2 = $ind.INDCH;
-        if ($tree->name != 'audio') {
-            return PEAR::raiseError("SmilPlaylist::parse: audio tag expected");
-        }
-        if (isset($tree->children[2])) {
-            return PEAR::raiseError(sprintf(
-                "SmilPlaylist::parse: unexpected tag %s in tag audio",
-            $tree->children[2]->name
-            ));
-        }
-        $res = ''; $fadeIn = 0; $fadeOut = 0;
-        foreach ($tree->children as $i => $ch) {
-            $ch =& $tree->children[$i];
-            $r = SmilPlaylistAnimateElement::convert2lspl($gb, $ch, &$gunids, $parr, $ind2);
-            if (PEAR::isError($r)) {
-                return $r;
-            }
-            switch ($r['type']) {
-                case "fadeIn":  $fadeIn  = $r['val']; break;
-                case "fadeOut": $fadeOut = $r['val']; break;
-            }
-        }
-        if ($fadeIn > 0 || $fadeOut > 0) {
-            $fiGunid = StoredFile::CreateGunid();
-            $fadeIn  = Playlist::secondsToPlaylistTime($fadeIn);
-            $fadeOut = Playlist::secondsToPlaylistTime($fadeOut);
-            $fInfo   = "$ind2\n";
-        } else {
-            $fInfo = '';
-        }
-        $plElGunid  = StoredFile::CreateGunid();
-        $acGunid     = $gunid;
-        $type = 'audioClip';
-        if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
-            switch (strtolower($ext = $va[1])) {
-                case "lspl":
-                case "xml":
-                case "smil":
-                case "m3u":
-                    $type = 'playlist';
-                    $acId = $gb->bsImportPlaylistRaw($gunid,
-                    $aPath, $uri, $ext, $gunids, $subjid);
-                    if (PEAR::isError($acId)) {
-                        return $r;
-                    }
-                    //break;
-                default:
-                    $ac = StoredFile::RecallByGunid($gunid);
-                    if (is_null($ac) || PEAR::isError($ac)) {
-                        return $ac;
-                    }
-                    $r = $ac->md->getMetadataElement('dcterms:extent');
-                    if (PEAR::isError($r)) {
-                        return $r;
-                    }
-                    $playlength = $r[0]['value'];
-            }
-        }
-
-        $title = basename($tree->attrs['src']->val);
-        $offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val);
-        $clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val);
-        $clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val);
-        $clipLength = Playlist::secondsToPlaylistTime($tree->attrs['clipLength']->val);
-        $res = "$ind\n".
-            "$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
-        $fInfo.
-            "$ind\n";
-        return $res;
-    }
-} // class SmilPlaylistAudioElement
-
-
-/**
- * @package Campcaster
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class SmilPlaylistAnimateElement {
-
-    public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
-    {
-        extract($parr);
-        if ($tree->name != 'animate') {
-            return PEAR::raiseError("SmilPlaylist::parse: animate tag expected");
-        }
-        if ($tree->attrs['attributeName']->val == 'soundLevel' &&
-        $tree->attrs['from']->val == '0%' &&
-        $tree->attrs['to']->val == '100%' &&
-        $tree->attrs['calcMode']->val == 'linear' &&
-        $tree->attrs['fill']->val == 'freeze' &&
-        $tree->attrs['begin']->val == '0s' &&
-        preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $va)
-        ) {
-            return array('type'=>'fadeIn', 'val'=>intval($va[1]));
-        }
-        if ($tree->attrs['attributeName']->val == 'soundLevel' &&
-        $tree->attrs['from']->val == '100%' &&
-        $tree->attrs['to']->val == '0%' &&
-        $tree->attrs['calcMode']->val == 'linear' &&
-        $tree->attrs['fill']->val == 'freeze' &&
-        preg_match("|^([0-9.]+)s$|", $tree->attrs['begin']->val, $vaBegin) &&
-        preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $vaEnd)
-        ) {
-            return array('type'=>'fadeOut', 'val'=>($vaEnd[1] - $vaBegin[1]));
-        }
-        return PEAR::raiseError(
-            "SmilPlaylistAnimateElement::convert2lspl: animate parameters too general"
-            );
-    }
-} // class SmilPlaylistAnimateElement
-
-?>
\ No newline at end of file
diff --git a/backend/StoredFile.php b/backend/StoredFile.php
deleted file mode 100644
index d1313c66d..000000000
--- a/backend/StoredFile.php
+++ /dev/null
@@ -1,1729 +0,0 @@
- "format",
-    "ls:bitrate" => "bit_rate",
-    "ls:samplerate" => "sample_rate",
-    "dcterms:extent" => "length",
-    "dc:title" => "track_title",
-    "dc:description" => "comments",
-    "dc:type" => "genre",
-    "dc:creator" => "artist_name",
-    "dc:source" => "album_title",
-    "ls:channels" => "channels",
-    "ls:filename" => "name",
-    "ls:year" => "year",
-    "ls:url" => "url",
-    "ls:track_num" => "track_number",
-    "ls:mood" => "mood",
-    "ls:bpm" => "bpm",
-    "ls:disc_num" => "disc_number",
-    "ls:rating" => "rating",
-    "ls:encoded_by" => "encoded_by",
-    "dc:publisher" => "label",
-    "ls:composer" => "composer",
-    "ls:encoder" => "encoder",
-    "ls:crc" => "checksum",
-    "ls:lyrics" => "lyrics",
-    "ls:orchestra" => "orchestra",
-    "ls:conductor" => "conductor",
-    "ls:lyricist" => "lyricist",
-    "ls:originallyricist" => "original_lyricist",
-    "ls:radiostationname" => "radio_station_name",
-    "ls:audiofileinfourl" => "info_url",
-    "ls:artisturl" => "artist_url",
-    "ls:audiosourceurl" => "audio_source_url",
-    "ls:radiostationurl" => "radio_station_url",
-    "ls:buycdurl" => "buy_this_url",
-    "ls:isrcnumber" => "isrc_number",
-    "ls:catalognumber" => "catalog_number",
-    "ls:originalartist" => "original_artist",
-    "dc:rights" => "copyright",
-    "dcterms:temporal" => "report_datetime",
-    "dcterms:spatial" => "report_location",
-    "dcterms:entity" => "report_organization",
-    "dc:subject" => "subject",
-    "dc:contributor" => "contributor",
-    "dc:language" => "language");
-
-/**
- * Track numbers in metadata tags can come in many formats:
- * "1 of 20", "1/20", "20/1".  This function parses the track
- * number and gets the real number so that we can sort by it
- * in the database.
- *
- * @param string $p_trackNumber
- * @return int
- */
-function camp_parse_track_number($p_trackNumber)
-{
-    $num = trim($p_trackNumber);
-    if (!is_numeric($num)) {
-        $matches = preg_match("/\s*([0-9]+)([^0-9]*)([0-9]*)\s*/", $num, $results);
-        $trackNum = 0;
-        foreach ($results as $result) {
-            if (is_numeric($result)) {
-                if ($trackNum == 0) {
-                    $trackNum = $result;
-                } elseif ($result < $trackNum) {
-                    $trackNum = $result;
-                }
-            }
-        }
-    } else {
-        $trackNum = $num;
-    }
-    return $trackNum;
-}
-
-
-/**
- * Add data to the global array $mdata, also sets global variables
- * $titleHaveSet and $titleKey.
- *
- * Converts the given string ($val) into UTF-8.
- *
- * @param array $p_mdata
- * 		The array to add the metadata to.
- * @param string $p_key
- * 		Metadata key.
- * @param string $p_val
- * 		Metadata value.
- * @param string $p_inputEncoding
- * 		Encoding type of the input value.
- */
-function camp_add_metadata(&$p_mdata, $p_key, $p_val, $p_inputEncoding='iso-8859-1')
-{
-    if (!is_null($p_val)) {
-        $data = $p_val;
-        $outputEncoding = 'UTF-8';
-        //if (function_exists('iconv') && ($p_inputEncoding != $outputEncoding) ) {
-        if (function_exists('iconv') && is_string($p_val)) {
-            $newData = @iconv($p_inputEncoding, $outputEncoding, $data);
-            if ($newData === FALSE) {
-                echo "Warning: convert $key data to unicode failed\n";
-            } elseif ($newData != $data) {
-                echo "Converted string: '$data' (".gettype($data).") -> '$newData' (".gettype($newData).").\n";
-                $data = $newData;
-            }
-        }
-        $p_mdata[$p_key] = trim($data);
-    }
-}
-
-
-/**
- * Return an array with the given audio file's ID3 tags.  The keys in the
- * array can be:
- * 
- * 		dc:format ("mime type")
- * 		dcterms:extent ("duration")
- * 		dc:title
- * 		dc:creator ("artist")
- * 		dc:source ("album")
- *      dc:type ("genre")
- * 		ls:bitrate
- * 		ls:encoded_by
- * 		ls:track_num
- * 		ls:channels
- * 		ls:year
- * 		ls:filename
- * 
- * - * @param string $p_filename - * @param boolean $p_testonly - * For diagnostic and debugging purposes - setting this to TRUE - * will print out the values found in the file and the ones assigned - * to the return array. - * @return array|PEAR_Error - */ -function camp_get_audio_metadata($p_filename, $p_testonly = false) -{ - $getID3 = new getID3(); - $infoFromFile = $getID3->analyze($p_filename); - if (PEAR::isError($infoFromFile)) { - return $infoFromFile; - } - if (isset($infoFromFile['error'])) { - return new PEAR_Error(array_pop($infoFromFile['error'])); - } - if (!$infoFromFile['bitrate']) { - return new PEAR_Error("File given is not an audio file."); - } - - if ($p_testonly) { - print_r($infoFromFile); - } - $titleKey = 'dc:title'; - $flds = array( - 'dc:format' => array( - array('path'=>"['mime_type']", 'ignoreEnc'=>TRUE), - ), - 'ls:bitrate' => array( - array('path'=>"['bitrate']", 'ignoreEnc'=>TRUE), - array('path'=>"['audio']['bitrate']", 'ignoreEnc'=>TRUE), - ), - 'ls:samplerate' => array( - array('path'=>"['audio']['sample_rate']", 'ignoreEnc'=>TRUE), - ), - 'ls:encoder' => array( - array('path'=>"['audio']['codec']", 'ignoreEnc'=>TRUE), - ), - 'dcterms:extent'=> array( - array('path'=>"['playtime_seconds']", 'ignoreEnc'=>TRUE), - ), - 'ls:composer'=> array( - array('path'=>"['id3v2']['comments']['composer']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - array('path'=>"['id3v2']['TCOM'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['id3v2']['composer']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - array('path'=>"['ogg']['comments']['composer']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['composer']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'dc:description'=> array( - array('path'=>"['id3v1']['comments']['comment']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['comments']['comments']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - array('path'=>"['id3v2']['COMM'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['id3v2']['comments']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - array('path'=>"['ogg']['comments']['comment']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['comment']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'dc:type'=> array( - array('path'=>"['id3v1']", 'dataPath'=>"['genre']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['comments']['content_type']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - array('path'=>"['id3v2']['TCON'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['genre']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['genre']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'dc:title' => array( - array('path'=>"['id3v2']['comments']['title']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TIT2'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TT2'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v1']", 'dataPath'=>"['title']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['title']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['title']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'dc:creator' => array( - array('path'=>"['id3v2']['comments']['artist']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TPE1'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TP1'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v1']", 'dataPath'=>"['artist']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['artist']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['artist']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'dc:source' => array( - array('path'=>"['id3v2']['comments']['album']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TALB'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TAL'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['album']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['album']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'ls:encoded_by' => array( - array('path'=>"['id3v2']['TENC'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TEN'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['encoded-by']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['encoded-by']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'ls:track_num' => array( - array('path'=>"['id3v2']['TRCK'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['id3v2']['TRK'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - array('path'=>"['ogg']['comments']['tracknumber']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['tracknumber']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - // 'ls:genre' => array( - // array('path'=>"['id3v1']", 'dataPath'=>"['genre']", 'encPath'=>"['encoding']"), - // array('path'=>"['id3v2']['TCON'][0]", 'dataPath'=>"['data']", 'encPath'=>"['encoding']"), - // array('path'=>"['id3v2']['comments']['content_type']", 'dataPath'=>"[0]", 'ignoreEnc'=>TRUE), - // array('path'=>"['ogg']['comments']['genre']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - // array('path'=>"['tags']['vorbiscomment']['genre']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - // ), - 'ls:channels' => array( - array('path'=>"['audio']['channels']", 'ignoreEnc'=>TRUE), - ), - 'ls:year' => array( - array('path'=>"['comments']['date']"), - array('path'=>"['ogg']['comments']['date']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - array('path'=>"['tags']['vorbiscomment']['date']", 'dataPath'=>"[0]", 'encPath'=>"['encoding']"), - ), - 'ls:filename' => array( - array('path'=>"['filename']"), - ), - ); - $mdata = array(); - if (isset($infoFromFile['audio'])) { - $mdata['audio'] = $infoFromFile['audio']; - } - if (isset($infoFromFile['playtime_seconds'])) { - $mdata['playtime_seconds'] = $infoFromFile['playtime_seconds']; - } - - $titleHaveSet = FALSE; - foreach ($flds as $key => $getid3keys) { - foreach ($getid3keys as $getid3key) { - $path = $getid3key["path"]; - $ignoreEnc = isset($getid3key["ignoreEnc"])? - $getid3key["ignoreEnc"]:FALSE; - $dataPath = isset($getid3key["dataPath"])?$getid3key["dataPath"]:""; - $encPath = isset($getid3key["encPath"])?$getid3key["encPath"]:""; - $enc = "UTF-8"; - - $tagElement = "\$infoFromFile$path$dataPath"; - eval("\$tagExists = isset($tagElement);"); - if ($tagExists) { - //echo "ignore encoding: ".($ignoreEnc?"yes":"no")."\n"; - //echo "tag exists\n"; - //echo "encode path: $encPath\n"; - eval("\$data = $tagElement;"); - if (!$ignoreEnc && $encPath != "") { - $encodedElement = "\$infoFromFile$path$encPath"; - eval("\$encodedElementExists = isset($encodedElement);"); - if ($encodedElementExists) { - eval("\$enc = $encodedElement;"); - } - } - - // Special case handling for track number - if ($key == "ls:track_num") { - $data = camp_parse_track_number($data); - } - camp_add_metadata($mdata, $key, $data, $enc); - if ($key == $titleKey) { - $titleHaveSet = TRUE; - } - break; - } - } - } - if ($p_testonly) { - var_dump($mdata); - } - - if (!$titleHaveSet || trim($mdata[$titleKey]) == '') { - camp_add_metadata($mdata, $titleKey, basename($p_filename)); - } - return $mdata; -} - - -/** - * StoredFile class - * - * Campcaster file storage support class.
- * Represents one virtual file in storage. Virtual file has up to two parts: - *
    - *
  • metadata in database - represented by MetaData class
  • - *
  • binary media data in real file
  • - *
- * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @see MetaData - */ -class StoredFile { - - // *** Variables stored in the database *** - - /** - * @var int - */ - private $id; - - /** - * Unique ID for the file. This is stored in HEX format. It is - * converted to a bigint whenever it is used in a database call. - * - * @var string - */ - public $gunid; - - /** - * The unique ID of the file as it is stored in the database. - * This is for debugging purposes and may not always exist in this - * class. - * - * @var string - */ - //private $gunidBigint; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $mime; - - /** - * Can be 'audioclip'...others might be coming, like webstream. - * - * @var string - */ - private $ftype; - - /** - * Can be 'ready', 'edited', 'incomplete'. - * - * @var string - */ - private $state; - - /** - * @var int - */ - private $currentlyaccessing; - - /** - * @var int - */ - private $editedby; - - /** - * @var timestamp - */ - private $mtime; - - /** - * @var string - */ - private $md5; - - /** - * @var string - */ - private $filepath; - - - // *** Variables NOT stored in the database *** - - /** - * Directory where the file is located. - * - * @var string - */ - private $resDir; - - /** - * @var boolean - */ - private $exists; - - /** - * @var MetaData - */ - public $md; - - /* ========================================================== constructor */ - /** - * Constructor, but shouldn't be externally called - * - * @param string $p_gunid - * globally unique id of file - */ - public function __construct($p_gunid=NULL) - { - $this->gunid = $p_gunid; - if (empty($this->gunid)) { - $this->gunid = StoredFile::generateGunid(); - } - else { - $this->loadMetadata(); - $this->exists = is_file($this->filepath) && is_readable($this->filepath); - } - } - - /** - * For testing only, do not use. - */ - public function __setGunid($p_guid) { - $this->gunid = $p_guid; - } - - /** - * Convert XML name to database column name. Used for backwards compatibility - * with old code. - * - * @param string $p_category - * @return string|null - */ - public static function xmlCategoryToDbColumn($p_category) - { - global $g_metadata_xml_to_db_mapping; - if (array_key_exists($p_category, $g_metadata_xml_to_db_mapping)) { - return $g_metadata_xml_to_db_mapping[$p_category]; - } - return null; - } - - - /** - * Convert database column name to XML name. - * - * @param string $p_dbColumn - * @return string|null - */ - public static function dbColumnToXmlCatagory($p_dbColumn) - { - global $g_metadata_xml_to_db_mapping; - $str = array_search($p_dbColumn, $g_metadata_xml_to_db_mapping); - // make return value consistent with xmlCategoryToDbColumn() - if ($str === FALSE) { - $str = null; - } - return $str; - } - - - /** - * GUNID needs to be set before you call this function. - * - */ - public function loadMetadata() - { - global $CC_CONFIG, $CC_DBC; - $escapedValue = pg_escape_string($this->gunid); - $sql = "SELECT * FROM ".$CC_CONFIG["filesTable"] - ." WHERE gunid='$escapedValue'"; - //var_dump($sql); - $this->md = $CC_DBC->getRow($sql); - //var_dump($this->md); - if (PEAR::isError($this->md)) { - $error = $this->md; - $this->md = null; - return $error; - } - $this->filepath = $this->md["filepath"]; - if (is_null($this->md)) { - $this->md = array(); - return; - } - $compatibilityData = array(); - foreach ($this->md as $key => $value) { - if ($xmlName = StoredFile::dbColumnToXmlCatagory($key)) { - $compatibilityData[$xmlName] = $value; - } - } - //var_dump($compatibilityData); - $this->md = array_merge($this->md, $compatibilityData); - //var_dump($this->md); - //$_SESSION["debug"] = $this->md; - } - - public function setFormat($p_value) - { - $this->md["format"] = $p_value; - } - - public function replaceMetadata($p_values) - { - global $CC_CONFIG, $CC_DBC; - foreach ($p_values as $category => $value) { - $escapedValue = pg_escape_string($value); - $columnName = StoredFile::xmlCategoryToDbColumn($category); - if (!is_null($columnName)) { - $sql = "UPDATE ".$CC_CONFIG["filesTable"] - ." SET $columnName='$escapedValue'" - ." WHERE gunid = '".$this->gunid."'"; - $CC_DBC->query($sql); - } - } - $this->loadMetadata(); - } - - public function clearMetadata() - { - $metadataColumns = array("format", "bit_rate", "sample_rate", "length", - "track_title", "comments", "genre", "artist_name", "channels", "name", - "year", "url", "track_number"); - foreach ($metadataColumns as $columnName) { - if (!is_null($columnName)) { - $sql = "UPDATE ".$CC_CONFIG["filesTable"] - ." SET $columnName=''" - ." WHERE gunid = '".$this->gunid."'"; - $CC_DBC->query($sql); - } - } - } - - - /* ========= 'factory' methods - should be called to construct StoredFile */ - /** - * Create instance of StoredFile object and insert new file - * - * @param array $p_values - * "filepath" - required, local path to media file (where it is before import) - * "id" - optional, local object id, will be generated if not given - * "gunid" - optional, unique id, for insert file with gunid, will be generated if not given - * "filename" - optional, will use "filepath" if not given - * "metadata" - optional, array of extra metadata, will be automatically calculated if not given. - * "mime" - optional, MIME type, highly recommended to pass in, will be automatically calculated if not given. - * "md5" - optional, MD5 sum, highly recommended to pass in, will be automatically calculated if not given. - * - * @param boolean $p_copyMedia - * copy the media file if true, make symlink if false - * - * @return StoredFile|NULL|PEAR_Error - */ - public static function Insert($p_values, $p_copyMedia=TRUE) - { - global $CC_CONFIG, $CC_DBC; - - if (!isset($p_values["filepath"])) { - return new PEAR_Error("StoredFile::Insert: filepath not set."); - } - if (!file_exists($p_values['filepath'])) { - return PEAR::raiseError("StoredFile::Insert: ". - "media file not found ({$p_values['filepath']})"); - } - - $gunid = isset($p_values['gunid'])?$p_values['gunid']:NULL; - - // Create the StoredFile object - $storedFile = new StoredFile($gunid); - - // Get metadata - if (isset($p_values["metadata"])) { - $metadata = $p_values['metadata']; - } else { - $metadata = camp_get_audio_metadata($p_values["filepath"]); - } - - $storedFile->name = isset($p_values['filename']) ? $p_values['filename'] : $p_values["filepath"]; - $storedFile->id = isset($p_values['id']) && is_integer($p_values['id'])?(int)$p_values['id']:null; - // NOTE: POSTGRES-SPECIFIC KEYWORD "DEFAULT" BEING USED, WOULD BE "NULL" IN MYSQL - $sqlId = !is_null($storedFile->id)?"'".$storedFile->id."'":'DEFAULT'; - $storedFile->ftype = isset($p_values['filetype']) ? strtolower($p_values['filetype']) : "audioclip"; - $storedFile->mime = (isset($p_values["mime"]) ? $p_values["mime"] : NULL ); - // $storedFile->filepath = $p_values['filepath']; - if (isset($p_values['md5'])) { - $storedFile->md5 = $p_values['md5']; - } elseif (file_exists($p_values['filepath'])) { - //echo "StoredFile::Insert: WARNING: Having to recalculate MD5 value\n"; - $storedFile->md5 = md5_file($p_values['filepath']); - } - - // Check for duplicates -- return duplicate - $duplicate = StoredFile::RecallByMd5($storedFile->md5); - if ($duplicate) { - return $duplicate; - } - - $storedFile->exists = FALSE; - - // Insert record into the database - $escapedName = pg_escape_string($storedFile->name); - $escapedFtype = pg_escape_string($storedFile->ftype); - $sql = "INSERT INTO ".$CC_CONFIG['filesTable'] - ."(id, name, gunid, mime, state, ftype, mtime, md5)" - ."VALUES ({$sqlId}, '{$escapedName}', " - ." '{$storedFile->gunid}'," - ." '{$storedFile->mime}', 'incomplete', '$escapedFtype'," - ." now(), '{$storedFile->md5}')"; - //$_SESSION["debug"] .= "sql: ".$sql."
"; - //echo $sql."\n"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - - if (!is_integer($storedFile->id)) { - // NOTE: POSTGRES-SPECIFIC - $sql = "SELECT currval('".$CC_CONFIG["filesSequence"]."_seq')"; - $storedFile->id = $CC_DBC->getOne($sql); - } - $storedFile->setMetadataBatch($metadata); - - // Save media file - $res = $storedFile->addFile($p_values['filepath'], $p_copyMedia); - if (PEAR::isError($res)) { - echo "StoredFile::Insert -- addFile(): '".$res->getMessage()."'\n"; - return $res; - } - - if (empty($storedFile->mime)) { - //echo "StoredFile::Insert: WARNING: Having to recalculate MIME value\n"; - $storedFile->setMime($storedFile->getMime()); - } - - // Save state - $storedFile->setState('ready'); - - // Recall the object to get all the proper values - $storedFile = StoredFile::RecallByGunid($storedFile->gunid); - return $storedFile; - } - - /** - * Fetch instance of StoreFile object.
- * Should be supplied with only ONE parameter, all the rest should - * be NULL. - * - * @param int $p_id - * local id - * @param string $p_gunid - * global unique id of file - * @param string $p_md5sum - * MD5 sum of the file - * @return StoredFile|Playlist|NULL - * Return NULL if the object doesnt exist in the DB. - */ - public static function Recall($p_id=null, $p_gunid=null, $p_md5sum=null) - { - global $CC_DBC; - global $CC_CONFIG; - if (!is_null($p_id)) { - $cond = "id='".intval($p_id)."'"; - } elseif (!is_null($p_gunid)) { - $cond = "gunid='$p_gunid'"; - } elseif (!is_null($p_md5sum)) { - $cond = "md5='$p_md5sum'"; - } else { - return null; - } - $sql = "SELECT *" - ." FROM ".$CC_CONFIG['filesTable'] - ." WHERE $cond"; - //echo $sql; - $row = $CC_DBC->getRow($sql); - if (PEAR::isError($row) || is_null($row)) { - return $row; - } - $gunid = $row['gunid']; - $storedFile = new StoredFile($gunid); - $storedFile->id = $row['id']; - $storedFile->name = $row['name']; - $storedFile->mime = $row['mime']; - $storedFile->ftype = $row['ftype']; - $storedFile->state = $row['state']; - $storedFile->currentlyaccessing = $row['currentlyaccessing']; - $storedFile->editedby = $row['editedby']; - $storedFile->mtime = $row['mtime']; - $storedFile->md5 = $row['md5']; - $storedFile->filepath = $row['filepath']; - $storedFile->exists = TRUE; - $storedFile->setFormat($row['ftype']); - return $storedFile; - } - - - /** - * Create instance of StoreFile object and recall existing file - * by gunid. - * - * @param string $p_gunid - * global unique id of file - * @return StoredFile - */ - public static function RecallByGunid($p_gunid='') - { - return StoredFile::Recall(null, $p_gunid); - } - - - /** - * Fetch the StoredFile by looking up the MD5 value. - * - * @param string $p_md5sum - * @return StoredFile|NULL|PEAR_Error - */ - public static function RecallByMd5($p_md5sum) - { - return StoredFile::Recall(null, null, $p_md5sum); - } - - - /** - * Create instance of StoreFile object and recall existing file - * by access token. - * - * @param string $p_token - * access token - * @return StoredFile - */ - public static function RecallByToken($p_token) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT gunid" - ." FROM ".$CC_CONFIG['accessTable'] - ." WHERE token=x'$p_token'::bigint"; - $gunid = $CC_DBC->getOne($sql); - if (PEAR::isError($gunid)) { - return $gunid; - } - if (is_null($gunid)) { - return PEAR::raiseError( - "StoredFile::RecallByToken: invalid token ($p_token)", GBERR_AOBJNEX); - } - return StoredFile::Recall(null, $gunid); - } - - - /** - * Generate the location to store the file. - * It creates the subdirectory if needed. - */ - private function generateFilePath() - { - global $CC_CONFIG, $CC_DBC; - $resDir = $CC_CONFIG['storageDir']."/".substr($this->gunid, 0, 3); - // see Transport::_getResDir too for resDir name create code - if (!is_dir($resDir)) { - mkdir($resDir, 02775); - chmod($resDir, 02775); - } - $info = pathinfo($this->name); - $fileExt = strtolower($info["extension"]); - return "{$resDir}/{$this->gunid}.{$fileExt}"; - } - - /** - * Insert media file to filesystem - * - * @param string $p_localFilePath - * local path - * @param boolean $p_copyMedia - * copy the media file if true, make symlink if false - * @return TRUE|PEAR_Error - */ - public function addFile($p_localFilePath, $p_copyMedia=TRUE) - { - global $CC_CONFIG, $CC_DBC; - if ($this->exists) { - return FALSE; - } - // for files downloaded from remote instance: - if ($p_localFilePath == $this->filepath) { - $this->exists = TRUE; - return TRUE; - } - umask(0002); - $dstFile = ''; - if ($p_copyMedia) { - $dstFile = $this->generateFilePath(); - $r = @copy($p_localFilePath, $dstFile); - if (!$r) { - $this->exists = FALSE; - return PEAR::raiseError( - "StoredFile::addFile: file save failed". - " ($p_localFilePath, {$this->filepath})",GBERR_FILEIO - ); - } - } else { - $dstFile = $p_localFilePath; - $r = TRUE; - //$r = @symlink($p_localFilePath, $dstFile); - } - $this->filepath = $dstFile; - $sqlPath = pg_escape_string($this->filepath); - $sql = "UPDATE ".$CC_CONFIG["filesTable"] - ." SET filepath='{$sqlPath}'" - ." WHERE id={$this->id}"; - //echo $sql."\n"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $this->exists = TRUE; - return TRUE; - } - - - /** - * Find and return the first exact match for the original file name - * that was used on import. - * @param string $p_name - */ - public static function findByOriginalName($p_name) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT id FROM ".$CC_CONFIG["filesTable"] - ." WHERE name='".pg_escape_string($p_name)."'"; - $id = $CC_DBC->getOne($sql); - if (is_numeric($id)) { - return StoredFile::Recall($id); - } else { - return NULL; - } - } - - - /** - * Delete and insert media file - * - * @param string $p_localFilePath - * local path - * @return TRUE|PEAR_Error - */ - public function replaceFile($p_localFilePath) - { - // Dont do anything if the source and destination files are - // the same. - if ($this->name == $p_localFilePath) { - return TRUE; - } - - if ($this->exists) { - $r = $this->deleteFile(); - if (PEAR::isError($r)) { - return $r; - } - } - return $this->addFile($p_localFilePath); - } - - - /** - * Return true if file corresponding to the object exists - * - * @return boolean - */ - public function existsFile() - { - return $this->exists; - } - - - /** - * Delete media file from filesystem. - * You cant delete a file if it is being accessed. - * You cant delete a file if it is scheduled to be played in the future. - * The file will be removed from all playlists it is a part of. - * - * @return boolean|PEAR_Error - */ - public function deleteFile() - { - global $CC_CONFIG; - if (!$this->exists) { - return FALSE; - } - if ($this->isAccessed()) { - return PEAR::raiseError( - 'Cannot delete a file that is currently accessed.' - ); - } - - // Check if the file is scheduled to be played in the future - if (Schedule::IsFileScheduledInTheFuture($this->id)) { - return PEAR::raiseError( - 'Cannot delete a file that is scheduled in the future.' - ); - } - - // Delete it from all playlists - //Playlist::DeleteFileFromAllPlaylists($this->id); - - // Only delete the file from filesystem if it has been copied to the - // storage directory. (i.e. dont delete linked files) - if (substr($this->filepath, 0, strlen($CC_CONFIG["storageDir"])) == $CC_CONFIG["storageDir"]) { - // Delete the file - if (!file_exists($this->filepath) || @unlink($this->filepath)) { - $this->exists = FALSE; - return TRUE; - } else { - return PEAR::raiseError( - "StoredFile::deleteFile: unlink failed ({$this->filepath})", - GBERR_FILEIO - ); - } - } else { - $this->exists = FALSE; - return TRUE; - } - } - - - /** - * Analyze file with getid3 module.
- * Obtain some metadata stored in media file.
- * This method should be used for prefilling metadata input form. - * - * @return array - * hierarchical hasharray with information about media file - */ - public function analyzeFile() - { - if (!$this->exists) { - return FALSE; - } - $ia = camp_get_audio_metadata($this->filepath); - return $ia; - } - - - /** - * Create instance of StoredFile object and make copy of existing file - * - * @param StoredFile $p_src - * source object - * @param int $p_nid - * new local id - * @return StoredFile - */ - public static function CopyOf(&$p_src, $p_nid) - { - $values = array( - "id" => $p_nid, - "filename" => $p_src->name, - "filepath" => $p_src->getRealFilePath(), - "filetype" => $p_src->getType() - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - $storedFile->replaceMetadata($p_src->getAllMetadata(), 'string'); - return $storedFile; - } - - - /** - * Replace existing file with new data. - * - * @param int $p_oid - * NOT USED - * @param string $p_name - * name of file - * @param string $p_localFilePath - * local path to media file - * @param string $p_metadata - * local path to metadata XML file or XML string - * @param string $p_mdataLoc - * 'file'|'string' - * @return TRUE|PEAR_Error - */ - // public function replace($p_oid, $p_name, $p_localFilePath='', $p_metadata='', - // $p_mdataLoc='file') - // { - // global $CC_CONFIG, $CC_DBC; - // $CC_DBC->query("BEGIN"); - // $res = $this->setName($p_name); - // if (PEAR::isError($res)) { - // $CC_DBC->query("ROLLBACK"); - // return $res; - // } - // if ($p_localFilePath != '') { - // $res = $this->setRawMediaData($p_localFilePath); - // } else { - // $res = $this->deleteFile(); - // } - // if (PEAR::isError($res)) { - // $CC_DBC->query("ROLLBACK"); - // return $res; - // } - // if ($p_metadata != '') { - // $res = $this->setMetadata($p_metadata, $p_mdataLoc); - // } else { - //// $res = $this->md->delete(); - // $res = $this->clearMetadata(); - // } - // if (PEAR::isError($res)) { - // $CC_DBC->query("ROLLBACK"); - // return $res; - // } - // $res = $CC_DBC->query("COMMIT"); - // if (PEAR::isError($res)) { - // $CC_DBC->query("ROLLBACK"); - // return $res; - // } - // return TRUE; - // } - - - /** - * Increase access counter, create access token, insert access record. - * - * @param int $parent - * parent token - * @return array - * array with: access URL, access token - */ - public function accessRawMediaData($p_parent='0') - { - $realFname = $this->getRealFilePath(); - $ext = $this->getFileExtension(); - $res = BasicStor::bsAccess($realFname, $ext, $this->gunid, 'access', $p_parent); - if (PEAR::isError($res)) { - return $res; - } - $resultArray = - array('url'=>"file://{$res['fname']}", 'token'=>$res['token']); - return $resultArray; - } - - - /** - * Decrease access couter, delete access record. - * - * @param string $p_token - * access token - * @return boolean - */ - public function releaseRawMediaData($p_token) - { - $res = BasicStor::bsRelease($p_token); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Replace media file only with new binary file - * - * @param string $p_localFilePath - * local path to media file - * @return TRUE|PEAR_Error - */ - public function setRawMediaData($p_localFilePath) - { - $res = $this->replaceFile($p_localFilePath); - if (PEAR::isError($res)) { - return $res; - } - $mime = $this->getMime(); - if ($mime !== FALSE) { - $res = $this->setMime($mime); - if (PEAR::isError($res)) { - return $res; - } - } - // $r = $this->md->regenerateXmlFile(); - // if (PEAR::isError($r)) { - // return $r; - // } - return TRUE; - } - - - private static function NormalizeExtent($v) - { - if (!preg_match("|^\d{2}:\d{2}:\d{2}.\d{6}$|", $v)) { - $s = Playlist::playlistTimeToSeconds($v); - $t = Playlist::secondsToPlaylistTime($s); - return $t; - } - return $v; - } - - - /** - * Replace metadata with new XML file - * - * @param string $p_metadata - * local path to metadata XML file or XML string - * @param string $p_mdataLoc - * 'file'|'string' - * @param string $p_format - * metadata format for validation - * ('audioclip' | 'playlist' | 'webstream' | NULL) - * (NULL = no validation) - * @return boolean - */ - // public function setMetadata($p_metadata, $p_mdataLoc='file', $p_format=NULL) - // { - // global $CC_CONFIG, $CC_DBC; - // $CC_DBC->query("BEGIN"); - // $res = $this->md->replace($p_metadata, $p_mdataLoc, $p_format); - // if (PEAR::isError($res)) { - // $CC_DBC->query("ROLLBACK"); - // return $res; - // } - // $res = $CC_DBC->query("COMMIT"); - // if (PEAR::isError($res)) { - // return $res; - // } - // return TRUE; - // } - - /** - * Set metadata element value - * - * @param string $category - * Metadata element identification (e.g. dc:title) - * @param string $value - * value to store, if NULL then delete record - * @return boolean - */ - public function setMetadataValue($p_category, $p_value) - { - global $CC_CONFIG, $CC_DBC; - if (!is_string($p_category) || is_array($p_value)) { - return FALSE; - } - if ($p_category == 'dcterms:extent') { - $p_value = StoredFile::NormalizeExtent($p_value); - } - $columnName = StoredFile::xmlCategoryToDbColumn($p_category); // Get column name - - if (!is_null($columnName)) { - $escapedValue = pg_escape_string($p_value); - $sql = "UPDATE ".$CC_CONFIG["filesTable"] - ." SET $columnName='$escapedValue'" - ." WHERE id={$this->id}"; - //var_dump($sql); - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - } - return TRUE; - } - - - /** - * Set metadata values in 'batch' mode - * - * @param array $values - * array of key/value pairs - * (e.g. 'dc:title'=>'New title') - * @return boolean - */ - public function setMetadataBatch($values) - { - global $CC_CONFIG, $CC_DBC; - if (!is_array($values)) { - $values = array($values); - } - if (count($values) == 0) { - return true; - } - foreach ($values as $category => $oneValue) { - $columnName = StoredFile::xmlCategoryToDbColumn($category); - if (!is_null($columnName)) { - if ($category == 'dcterms:extent') { - $oneValue = StoredFile::NormalizeExtent($oneValue); - } - // Since track_number is an integer, you cannot set - // it to be the empty string, so we NULL it instead. - if ($columnName == 'track_number' && empty($oneValue)) { - $sqlPart = "$columnName = NULL"; - } elseif (($columnName == 'length') && (strlen($oneValue) > 8)) { - // Postgres doesnt like it if you try to store really large hour - // values. TODO: We need to fix the underlying problem of getting the - // right values. - $parts = explode(':', $oneValue); - $hour = intval($parts[0]); - if ($hour > 24) { - continue; - } else { - $sqlPart = "$columnName = '$oneValue'"; - } - } else { - $escapedValue = pg_escape_string($oneValue); - $sqlPart = "$columnName = '$escapedValue'"; - } - $sqlValues[] = $sqlPart; - } - } - if (count($sqlValues)==0) { - return TRUE; - } - $sql = "UPDATE ".$CC_CONFIG["filesTable"] - ." SET ".join(",", $sqlValues) - ." WHERE id={$this->id}"; - $CC_DBC->query($sql); - return TRUE; - } - - - /** - * Get metadata as array, indexed by the column names in the database. - * - * @return array - */ - public function getMetadata() - { - return $this->md; - } - - /** - * Get one metadata value. - * - * @param string $p_name - * @return string - */ - public function getMetadataValue($p_name) - { - if (isset($this->md[$p_name])){ - return $this->md[$p_name]; - } else { - return ""; - } - } - - /** - * Rename stored virtual file - * - * @param string $p_newname - * @return TRUE|PEAR_Error - */ - public function setName($p_newname) - { - global $CC_CONFIG, $CC_DBC; - $escapedName = pg_escape_string($p_newname); - $sql = "UPDATE ".$CC_CONFIG['filesTable'] - ." SET name='$escapedName', mtime=now()" - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $this->name = $p_newname; - return TRUE; - } - - - /** - * Set state of virtual file - * - * @param string $p_state - * 'empty'|'incomplete'|'ready'|'edited' - * @param int $p_editedby - * user id | 'NULL' for clear editedBy field - * @return TRUE|PEAR_Error - */ - public function setState($p_state, $p_editedby=NULL) - { - global $CC_CONFIG, $CC_DBC; - $escapedState = pg_escape_string($p_state); - $eb = (!is_null($p_editedby) ? ", editedBy=$p_editedby" : ''); - $sql = "UPDATE ".$CC_CONFIG['filesTable'] - ." SET state='$escapedState'$eb, mtime=now()" - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $this->state = $p_state; - $this->editedby = $p_editedby; - return TRUE; - } - - /** - * Set mime-type of virtual file - * - * @param string $p_mime - * mime-type - * @return boolean|PEAR_Error - */ - public function setMime($p_mime) - { - global $CC_CONFIG, $CC_DBC; - if (!is_string($p_mime)) { - $p_mime = 'application/octet-stream'; - } - $escapedMime = pg_escape_string($p_mime); - $sql = "UPDATE ".$CC_CONFIG['filesTable'] - ." SET mime='$escapedMime', mtime=now()" - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $this->mime = $p_mime; - return TRUE; - } - - - /** - * Set md5 of virtual file - * - * @param string $p_md5sum - * @return boolean|PEAR_Error - */ - public function setMd5($p_md5sum) - { - global $CC_CONFIG, $CC_DBC; - $escapedMd5 = pg_escape_string($p_md5sum); - $sql = "UPDATE ".$CC_CONFIG['filesTable'] - ." SET md5='$escapedMd5', mtime=now()" - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $this->md5 = $p_md5sum; - return TRUE; - } - - - /** - * Delete stored virtual file - * - * @param boolean $p_deleteFile - * - * @return TRUE|PEAR_Error - */ - public function delete($p_deleteFile = true) - { - global $CC_CONFIG, $CC_DBC; - if ($p_deleteFile) { - $res = $this->deleteFile(); - if (PEAR::isError($res)) { - return $res; - } - } - $sql = "SELECT to_hex(token)as token, ext " - ." FROM ".$CC_CONFIG['accessTable'] - ." WHERE gunid='{$this->gunid}'"; - $tokens = $CC_DBC->getAll($sql); - if (is_array($tokens)) { - foreach ($tokens as $i => $item) { - $file = $this->_getAccessFileName($item['token'], $item['ext']); - if (file_exists($file)) { - @unlink($file); - } - } - } - $sql = "DELETE FROM ".$CC_CONFIG['accessTable'] - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - $sql = "DELETE FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='{$this->gunid}'"; - $res = $CC_DBC->query($sql); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Returns an array of playlist objects that this file is a part of. - * @return array - */ - public function getPlaylists() { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT playlist_id " - ." FROM ".$CC_CONFIG['playistTable'] - ." WHERE file_id='{$this->id}'"; - $ids = $CC_DBC->getAll($sql); - $playlists = array(); - if (is_array($ids) && count($ids) > 0) { - foreach ($ids as $id) { - $playlists[] = Playlist::Recall($id); - } - } - return $playlists; - } - - - /** - * Returns true if virtual file is currently in use.
- * Static or dynamic call is possible. - * - * @param string $p_gunid - * optional (for static call), global unique id - * @return boolean|PEAR_Error - */ - public function isAccessed($p_gunid=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (is_null($p_gunid)) { - return ($this->currentlyaccessing > 0); - } - $sql = "SELECT currentlyAccessing FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='$p_gunid'"; - $ca = $CC_DBC->getOne($sql); - if (is_null($ca)) { - return PEAR::raiseError( - "StoredFile::isAccessed: invalid gunid ($p_gunid)", - GBERR_FOBJNEX - ); - } - return ($ca > 0); - } - - - /** - * Returns true if virtual file is edited - * - * @param string $p_playlistId - * playlist global unique ID - * @return boolean - */ - public function isEdited($p_playlistId=NULL) - { - if (is_null($p_playlistId)) { - return ($this->state == 'edited'); - } - $state = $this->getState($p_playlistId); - if ($state != 'edited') { - return FALSE; - } - return TRUE; - } - - - /** - * Returns id of user editing playlist - * - * @param string $p_playlistId - * playlist global unique ID - * @return int|null|PEAR_Error - * id of user editing it - */ - public function isEditedBy($p_playlistId=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (is_null($p_playlistId)) { - $p_playlistId = $this->gunid; - } - $sql = "SELECT editedBy FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='$p_playlistId'"; - $ca = $CC_DBC->getOne($sql); - if (PEAR::isError($ca)) { - return $ca; - } - if (is_null($ca)) { - return $ca; - } - return intval($ca); - } - - - /** - * Return local ID of virtual file. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - - /** - * Return global ID of virtual file. - * - * @return string - */ - public function getGunid() - { - return $this->gunid; - } - - - /** - * Returns true if raw media file exists - * @return boolean|PEAR_Error - */ - public function exists() - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT gunid " - ." FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='{$this->gunid}'"; - $indb = $CC_DBC->getRow($sql); - if (PEAR::isError($indb)) { - return $indb; - } - if (is_null($indb)) { - return FALSE; - } - if ($this->ftype == 'audioclip') { - return $this->existsFile(); - } - return TRUE; - } - - - /** - * Create new global unique id - * @return string - */ - public static function generateGunid() - { - return md5(uniqid("", true)); - - // $ip = (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : ''); - // $initString = microtime().$ip.rand(); - // $hash = md5($initString); - // // non-negative int8 - // $hsd = substr($hash, 0, 1); - // $res = dechex(hexdec($hsd)>>1).substr($hash, 1, 15); - // return StoredFile::NormalizeGunid($res); - } - - - /** - * Pad the gunid with zeros if it isnt 16 digits. - * - * @return string - */ - // public static function NormalizeGunid($p_gunid) - // { - // return str_pad($p_gunid, 16, "0", STR_PAD_LEFT); - // } - - - /** - * Return suitable extension. - * - * @todo make it general - is any tool for it? - * - * @return string - * file extension without a dot - */ - public function getFileExtension() - { - $fname = $this->getName(); - $pos = strrpos($fname, '.'); - if ($pos !== FALSE) { - $ext = substr($fname, $pos+1); - if ($ext !== FALSE) { - return $ext; - } - } - switch (strtolower($this->mime)) { - case "audio/mpeg": - $ext = "mp3"; - break; - case "audio/x-wav": - case "audio/x-wave": - $ext = "wav"; - break; - case "audio/x-ogg": - case "application/x-ogg": - $ext = "ogg"; - break; - default: - $ext = "bin"; - break; - } - return $ext; - } - - - /** - * Get mime-type stored in the file. - * Warning: this function is slow! - * - * @return string - */ - public function getMime() - { - $a = $this->analyzeFile(); - if (PEAR::isError($a)) { - return $a; - } - if (isset($a['dc:format'])) { - return $a['dc:format']; - } - return ''; - } - - - /** - * Convenience function. - * @return string - */ - public function getTitle() - { - return $this->md["title"]; - } - - public function getType() - { - return $this->ftype; - } - - /** - * Get storage-internal file state - * - * @param string $p_gunid - * global unique id of file - * @return string - * see install() - */ - public function getState($p_gunid=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (is_null($p_gunid)) { - return $this->state; - } - $sql = "SELECT state FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='$p_gunid'"; - return $CC_DBC->getOne($sql); - } - - - /** - * Get mnemonic file name - * - * @param string $p_gunid - * global unique id of file - * @return string - */ - public function getName($p_gunid=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (is_null($p_gunid)) { - return $this->name; - } - $sql = "SELECT name FROM ".$CC_CONFIG['filesTable'] - ." WHERE gunid='$p_gunid'"; - return $CC_DBC->getOne($sql); - } - - - /** - * Get real filename of raw media data - * - * @return string - */ - public function getRealFilePath() - { - return $this->filepath; - } - - /** - * Get the URL to access this file. - */ - public function getFileUrl() - { - global $CC_CONFIG; - return "http://".$CC_CONFIG["storageUrlHost"] - .$CC_CONFIG["apiPath"]."get_media.php?file=" - .$this->gunid.".".$this->getFileExtension(); - } - - /** - * Get real filename of metadata file - * - * @return string - * @see MetaData - */ - public function getRealMetadataFileName() - { - //return $this->md->getFileName(); - return $this->md["name"]; - } - - - /** - * Create and return name for temporary symlink. - * - * @todo Should be more unique - * @return string - */ - private function _getAccessFileName($p_token, $p_ext='EXT') - { - global $CC_CONFIG; - return $CC_CONFIG['accessDir']."/$p_token.$p_ext"; - } - -} // class StoredFile -?> \ No newline at end of file diff --git a/backend/Subjects.php b/backend/Subjects.php deleted file mode 100644 index f99cea1c6..000000000 --- a/backend/Subjects.php +++ /dev/null @@ -1,683 +0,0 @@ -raiseError("Subjects::AddSubj: empty login"); - } - $id = $CC_DBC->nextId($CC_CONFIG['subjSequence']); - if (PEAR::isError($id)) { - return $id; - } - if (!is_null($p_pass) && !$p_passenc) { - $p_pass = md5($p_pass); - } - $sql = "INSERT INTO ".$CC_CONFIG['subjTable']." (id, login, pass, type, realname)" - ." VALUES ($id, '$p_login', ". - (is_null($p_pass) ? "'!', 'G'" : "'$p_pass', 'U'").", - '$p_realname')"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - return $id; - } - - - /** - * Remove subject by uid or by login - * - * @param string $login - * @param int $uid - * @return boolean|PEAR_Error - */ - public static function RemoveSubj($login, $uid=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (is_null($uid)) { - $uid = Subjects::GetSubjId($login); - } - if (PEAR::isError($uid)) { - return $uid; - } - $sql = "DELETE FROM ".$CC_CONFIG['smembTable'] - ." WHERE (uid='$uid' OR gid='$uid') AND mid is null"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - $sql2 = "DELETE FROM ".$CC_CONFIG['subjTable'] - ." WHERE login='$login'"; - $r = $CC_DBC->query($sql2); - if (PEAR::isError($r)) { - return $r; - } - return Subjects::_rebuildRels(); - } // fn removeSubj - - - /** - * Check login and password - * - * @param string $login - * @param string $pass - * optional - * @return boolean|int|PEAR_Error - */ - public static function Authenticate($login, $pass='') - { - global $CC_CONFIG, $CC_DBC; - $cpass = md5($pass); - $sql = "SELECT id FROM ".$CC_CONFIG['subjTable'] - ." WHERE login='$login' AND pass='$cpass' AND type='U'"; - $id = $CC_DBC->getOne($sql); - if (PEAR::isError($id)) { - return $id; - } - return (is_null($id) ? FALSE : $id); - } // fn authenticate - - - /** - * Set lastlogin or lastfail timestamp - * - * @param string $login - * @param boolean $failed - * true=> set lastfail, false=> set lastlogin - * @return boolean|int|PEAR_Error - */ - public static function SetTimeStamp($login, $failed=FALSE) - { - global $CC_CONFIG, $CC_DBC; - $fld = ($failed ? 'lastfail' : 'lastlogin'); - $sql = "UPDATE ".$CC_CONFIG['subjTable']." SET $fld=now()" - ." WHERE login='$login'"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } // fn setTimeStamp - - - /** - * Change user password - * - * @param string $login - * @param string $oldpass - * old password (optional for 'superuser mode') - * @param string $pass - * optional - * @param boolean $passenc - * optional, password already encrypted if true - * @return boolean|PEAR_Error - */ - public static function Passwd($login, $oldpass=null, $pass='', $passenc=FALSE) - { - global $CC_CONFIG, $CC_DBC; - if (!$passenc) { - $cpass = md5($pass); - } else { - $cpass = $pass; - } - if (!is_null($oldpass)) { - $oldcpass = md5($oldpass); - $oldpCond = "AND pass='$oldcpass'"; - } else { - $oldpCond = ''; - } - $sql = "UPDATE ".$CC_CONFIG['subjTable']." SET pass='$cpass'" - ." WHERE login='$login' $oldpCond AND type='U'"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } // fn passwd - - - /* --------------------------------------------------------------- groups */ - - /** - * Add {login} and direct/indirect members to {gname} and to groups, - * where {gname} is [in]direct member - * - * @param string $login - * @param string $gname - * @return int|PEAR_Error - */ - public static function AddSubjectToGroup($login, $gname) - { - $uid = Subjects::GetSubjId($login); - if (PEAR::isError($uid)) { - return $uid; - } - $gid = Subjects::GetSubjId($gname); - if (PEAR::isError($gid)) { - return $gid; - } - $isgr = Subjects::IsGroup($gid); - if (PEAR::isError($isgr)) { - return $isgr; - } - if (!$isgr) { - return PEAR::raiseError("Subjects::addSubj2Gr: Not a group ($gname)", ALIBERR_NOTGR); - } - // add subject and all [in]direct members to group $gname: - $mid = Subjects::_plainAddSubjectToGroup($uid, $gid); - if (PEAR::isError($mid)) { - return $mid; - } - // add it to all groups where $gname is [in]direct member: - $marr = Subjects::_listRMemb($gid); - if (PEAR::isError($marr)) { - return $marr; - } - foreach ($marr as $k => $v) { - $r = Subjects::_plainAddSubjectToGroup( - $uid, $v['gid'], intval($v['level'])+1, $v['id']); - if (PEAR::isError($r)) { - return $r; - } - } - return $mid; - } // fn addSubj2Gr - - - /** - * Remove subject from group - * - * @param string $login - * @param string $gname - * @return boolean|PEAR_Error - */ - public static function RemoveSubjectFromGroup($login, $gname) - { - global $CC_CONFIG, $CC_DBC; - $uid = Subjects::GetSubjId($login); - if (PEAR::isError($uid)) { - return $uid; - } - $gid = Subjects::GetSubjId($gname); - if (PEAR::isError($gid)) { - return $gid; - } - $sql = "SELECT id FROM ".$CC_CONFIG['smembTable'] - ." WHERE uid='$uid' AND gid='$gid' AND mid is null"; - $mid = $CC_DBC->getOne($sql); - if (is_null($mid)) { - return FALSE; - } - if (PEAR::isError($mid)) { - return $mid; - } - // remove it: - $r = Subjects::_removeMemb($mid); - if (PEAR::isError($r)) { - return $r; - } - // and rebuild indirect memberships: - $r = Subjects::_rebuildRels(); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } // fn removeSubjFromGr - - - /* --------------------------------------------------------- info methods */ - - /** - * Get subject id from login - * - * @param string $login - * @return int|PEAR_Error - */ - public static function GetSubjId($login) - { - global $CC_CONFIG; - global $CC_DBC; - $sql = "SELECT id FROM ".$CC_CONFIG['subjTable'] - ." WHERE login='$login'"; - return $CC_DBC->getOne($sql); - } // fn getSubjId - - - /** - * Get subject name (login) from id - * - * @param int $id - * @param string $fld - * @return string|PEAR_Error - */ - public static function GetSubjName($id, $fld='login') - { - global $CC_CONFIG; - global $CC_DBC; - $sql = "SELECT $fld FROM ".$CC_CONFIG['subjTable'] - ." WHERE id='$id'"; - return $CC_DBC->getOne($sql); - } // fn getSubjName - - - /** - * Get one subject from the table. - * - * @param string $p_fieldValue - * @param string $p_fieldName - * @return array - */ - public static function GetSubject($p_fieldValue, $p_fieldName='login') - { - global $CC_CONFIG, $CC_DBC; - if (!in_array($p_fieldName, array("login", "id"))) { - return null; - } - $escapedValue = pg_escape_string($p_fieldValue); - $sql = "SELECT * FROM ".$CC_CONFIG['subjTable'] - ." WHERE $p_fieldName='$escapedValue'"; - $row = $CC_DBC->GetRow($sql); - return $row; - } - - - /** - * Get all subjects - * - * @param string $flds - * @return array|PEAR_Error - */ - public static function GetSubjects($flds='id, login') - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT $flds FROM ".$CC_CONFIG['subjTable']; - return $CC_DBC->getAll($sql); - } // fn getSubjects - - - /** - * Get subjects with count of direct members - * - * @return array|PEAR_Error - */ - public static function GetSubjectsWCnt() - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT count(m.uid)as cnt, s.id, s.login, s.type" - ." FROM ".$CC_CONFIG['subjTable']." s" - ." LEFT JOIN ".$CC_CONFIG['smembTable']." m ON m.gid=s.id" - ." WHERE m.mid is null" - ." GROUP BY s.id, s.login, s.type" - ." ORDER BY s.id"; - return $CC_DBC->getAll($sql); - } // fn getSubjectsWCnt - - - /** - * Return true if subject is a group - * - * @param int $gid - * @return boolean|PEAR_Error - */ - public static function IsGroup($gid) - { - global $CC_CONFIG, $CC_DBC; - if (empty($gid)) { - return FALSE; - } - $sql = "SELECT type FROM ".$CC_CONFIG['subjTable'] - ." WHERE id='$gid'"; - $r = $CC_DBC->getOne($sql); - if (PEAR::isError($r)) { - return $r; - } - return ($r === 'G'); - } // fn isGroup - - - /** - * List direct members of group - * - * @param int $gid - * @return array|PEAR_Error - */ - public static function ListGroup($gid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT s.id, s.login, s.type" - ." FROM ".$CC_CONFIG['smembTable']." m, ".$CC_CONFIG['subjTable']." s" - ." WHERE m.uid=s.id AND m.mid is null AND m.gid='$gid'"; - return $CC_DBC->getAll($sql); - } // fn listGroup - - - /** - * Return true if uid is [id]direct member of gid - * - * @param int $uid - * local user id - * @param int $gid - * local group id - * @return boolean - */ - public static function IsMemberOf($uid, $gid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT count(*)as cnt" - ." FROM ".$CC_CONFIG['smembTable'] - ." WHERE uid='$uid' AND gid='$gid'"; - $res = $CC_DBC->getOne($sql); - if (PEAR::isError($res)) { - return $res; - } - return (intval($res) > 0); - } // fn isMemberOf - - - /* ==================================================== "private" methods */ - - /** - * Create membership record - * - * @param int $uid - * @param int $gid - * @param int $level - * @param int $mid - * @return int|PEAR_Error - */ - private static function _addMemb($uid, $gid, $level=0, $mid='null') - { - global $CC_CONFIG, $CC_DBC; - if ($uid == $gid) { - return PEAR::raiseError("Subjects::_addMemb: uid==gid ($uid)", ALIBERR_BADSMEMB); - } - $sql = "SELECT id, level, mid FROM ".$CC_CONFIG['smembTable'] - ." WHERE uid='$uid' AND gid='$gid' ORDER BY level ASC"; - $a = $CC_DBC->getAll($sql); - if (PEAR::isError($a)) { - return $a; - } - if (count($a) > 0) { - $a0 = $a[0]; - $id = $a0['id']; - if ($level < intval($a0['level'])){ - $sql2 = "UPDATE ".$CC_CONFIG['smembTable'] - ." SET level='$level', mid=$mid WHERE id='{$a0['id']}'"; - $r = $CC_DBC->query($sql2); - if (PEAR::isError($r)) { - return $r; - } - } - } else { - $id = $CC_DBC->nextId($CC_CONFIG['smembSequence']); - if (PEAR::isError($id)) { - return $id; - } - $sql3 = "INSERT INTO ".$CC_CONFIG['smembTable']." (id, uid, gid, level, mid)" - ." VALUES ($id, $uid, $gid, $level, $mid)"; - $r = $CC_DBC->query($sql3); - if (PEAR::isError($r)) { - return $r; - } - } - return $id; - } // fn _addMemb - - - /** - * Remove membership record - * - * @param int $mid - * @return null|PEAR_Error - */ - private static function _removeMemb($mid) - { - global $CC_CONFIG, $CC_DBC; - $sql = "DELETE FROM ".$CC_CONFIG['smembTable'] - ." WHERE id='$mid'"; - return $CC_DBC->query($sql); - } // fn _removeMemb - - - /** - * List [in]direct members of group - * - * @param int $gid - * @param int $uid - * @return array|PEAR_Error - */ - private static function _listMemb($gid, $uid=NULL) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT id, uid, level FROM ".$CC_CONFIG['smembTable'] - ." WHERE gid='$gid'".(is_null($uid) ? '' : " AND uid='$uid'"); - return $CC_DBC->getAll($sql); - } // fn _listMemb - - - /** - * List groups where uid is [in]direct member - * - * @param int $gid - * @param int $uid - * @return array|PEAR_Error - */ - private static function _listRMemb($uid, $gid=NULL) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT id, gid, level FROM ".$CC_CONFIG['smembTable'] - ." WHERE uid='$uid'".(is_null($gid) ? '' : " AND gid='$gid'"); - return $CC_DBC->getAll($sql); - } // fn listRMemb - - - /** - * Add uid and its [in]direct members to gid - * - * @param int $uid - * @param int $gid - * @param int $level - * @param int $rmid - * @return int|PEAR_Error - */ - private static function _plainAddSubjectToGroup($uid, $gid, $level=0, $rmid='null') - { - $mid = Subjects::_addMemb($uid, $gid, $level, $rmid); - if (PEAR::isError($mid)) { - return $mid; - } - $marr = Subjects::_listMemb($uid); - if (PEAR::isError($marr)) { - return $marr; - } - foreach ($marr as $k => $v) { - $r = Subjects::_addMemb( - $v['uid'], $gid, intval($v['level'])+$level+1, $mid - ); - if (PEAR::isError($r)) { - return $r; - } - } - return $mid; - } - - - /** - * Rebuild indirect membership records
- * it's probably more complicated to do removing without rebuild ... - * - * @return true|PEAR_Error - */ - private static function _rebuildRels() - { - global $CC_CONFIG, $CC_DBC; - $CC_DBC->query("BEGIN"); - $r = $CC_DBC->query("LOCK TABLE ".$CC_CONFIG['smembTable']); - if (PEAR::isError($r)) { - return $r; - } - $sql = "DELETE FROM ".$CC_CONFIG['smembTable'] - ." WHERE mid is not null"; - $r = $CC_DBC->query($sql); - if (PEAR::isError($r)) { - return $r; - } - $arr = $CC_DBC->getAll("SELECT uid, gid FROM ".$CC_CONFIG['smembTable']); - // WHERE mid is null - if (PEAR::isError($arr)) { - return $arr; - } - foreach ($arr as $it) { - $marr = Subjects::_listRMemb($it['gid']); - if (PEAR::isError($marr)) { - return $marr; - } - foreach ($marr as $k => $v) { - $r = Subjects::_plainAddSubjectToGroup( - $it['uid'], $v['gid'], intval($v['level'])+1, $v['id'] - ); - if (PEAR::isError($r)) { - return $r; - } - } - } - $r = $CC_DBC->query("COMMIT"); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } // fn _rebuildRels - - - /* =============================================== test and debug methods */ - - /** - * Dump subjects for debug - * - * @param string $indstr - * indentation string - * @param string $ind - * actual indentation - * @return string - */ - public static function DumpSubjects($indstr=' ', $ind='') - { - $r = $ind.join(', ', array_map( - create_function('$v', 'return "{$v[\'login\']}({$v[\'cnt\']})";'), - Subjects::GetSubjectsWCnt() - ))."\n"; - return $r; - } // fn dumpSubjects - - - /** - * Delete all subjects and membership records - * - * @return void - */ - public static function DeleteData() - { - global $CC_CONFIG, $CC_DBC; - $CC_DBC->query("DELETE FROM ".$CC_CONFIG['subjTable']); - $CC_DBC->query("DELETE FROM ".$CC_CONFIG['smembTable']); - //ObjClasses::DeleteData(); - } // fn deleteData - - - /** - * Insert test data - * - * @return array - */ - public function TestData() - { -// $tdata = ObjClasses::TestData(); -// $o['root'] = Subjects::AddSubj('root', 'q'); -// $o['test1'] = Subjects::AddSubj('test1', 'a'); -// $o['test2'] = Subjects::AddSubj('test2', 'a'); -// $o['test3'] = Subjects::AddSubj('test3', 'a'); -// $o['test4'] = Subjects::AddSubj('test4', 'a'); -// $o['test5'] = Subjects::AddSubj('test5', 'a'); -// $o['gr1'] = Subjects::AddSubj('gr1'); -// $o['gr2'] = Subjects::AddSubj('gr2'); -// $o['gr3'] = Subjects::AddSubj('gr3'); -// $o['gr4'] = Subjects::AddSubj('gr4'); -// Subjects::AddSubjectToGroup('test1', 'gr1'); -// Subjects::AddSubjectToGroup('test2', 'gr2'); -// Subjects::AddSubjectToGroup('test3', 'gr3'); -// Subjects::AddSubjectToGroup('test4', 'gr4'); -// Subjects::AddSubjectToGroup('test5', 'gr1'); -// Subjects::AddSubjectToGroup('gr4', 'gr3'); -// Subjects::AddSubjectToGroup('gr3', 'gr2'); -// $tdata['subjects'] = $o; -// return $tdata; - } // fn TestData - - - /** - * Make basic test - * - */ - public static function Test() - { -// $p = ObjClasses::Test(); -// if (PEAR::isError($p)) { -// return $p; -// } -// Subjects::DeleteData(); -// Subjects::TestData(); -// $test_correct = "root(0), test1(0), test2(0), test3(0),". -// " test4(0), test5(0), gr1(2), gr2(2), gr3(2), gr4(1)\n"; -// $test_dump = Subjects::DumpSubjects(); -// Subjects::RemoveSubj('test1'); -// Subjects::RemoveSubj('test3'); -// Subjects::RemoveSubjectFromGroup('test5', 'gr1'); -// Subjects::RemoveSubjectFromGroup('gr3', 'gr2'); -// $test_correct .= "root(0), test2(0), test4(0), test5(0),". -// " gr1(0), gr2(1), gr3(1), gr4(1)\n"; -// $test_dump .= Subjects::DumpSubjects(); -// Subjects::DeleteData(); -// if ($test_dump == $test_correct) { -// $test_log .= "subj: OK\n"; -// return TRUE; -// } else { -// return PEAR::raiseError( -// 'Subjects::test:', 1, PEAR_ERROR_DIE, '%s'. -// "
\ncorrect:\n{$test_correct}\n".
-//                "dump:\n{$test_dump}\n
\n"); -// } - } // fn test - -} // class Subjects -?> \ No newline at end of file diff --git a/backend/Transport.php b/backend/Transport.php deleted file mode 100644 index e5ee6f548..000000000 --- a/backend/Transport.php +++ /dev/null @@ -1,1833 +0,0 @@ - - * over unreliable network and from behind firewall

- * - * Transport states: - *
    - *
  • init: transport is prepared, but not started - * (e.g. no network connection is present)
  • - *
  • pending: transport is in progress, file is not fully transported to - * target system
  • - *
  • waiting: transport is in progress, but not running now
  • - *
  • finished: transport is finished, but file processing on target side - * is not completed
  • - *
  • closed: processing on target side is completed without errors
  • - *
  • failed: error - error message stored in errmsg field
  • - *
  • paused: transport have been paused
  • - *
- * - * Transport types: - *
    - *
  • audioclip
  • - *
  • playlist
  • - *
  • metadata
  • - *
  • file
  • - *
- * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class Transport -{ - /** - * @var GreenBox - */ - public $gb; - - /** - * File name - * @var string - */ - private $cronJobScript; - - /** - * wget --read-timeout parameter [s] - * @var int - */ - private $downTimeout = 900; - - /** - * wget --waitretry parameter [s] - * @var int - */ - private $downWaitretry = 10; - - /** - * wget --limit-rate parameter - */ - private $downLimitRate = NULL; - # private $downLimitRate = 500; - - /** - * wget -t parameter - * @var int - */ - private $downRetries = 6; - - /** - * curl --max-time parameter - * @var int - */ - private $upTrMaxTime = 1800; - - /** - * curl --speed-time parameter - * @var int - */ - private $upTrSpeedTime = 30; - - /** - * curl --speed-limit parameter - * @var int - */ - private $upTrSpeedLimit = 30; - - /** - * curl --connect-timeout parameter - * @var int - */ - private $upTrConnectTimeout = 20; - - /** - * curl --limit-rate parameter - * @var int - */ - private $upLimitRate = NULL; - # private $upLimitRate = 500; - - - /** - * Constructor - * - * @param LocStor $gb - * @return Transport - */ - public function __construct(&$gb) - { - $this->gb =& $gb; - $this->cronJobScript = realpath( - dirname(__FILE__). - '/../../storageServer/var/cron/transportCronJob.php' - ); - } - - - /* ==================================================== transport methods */ - /* ------------------------------------------------------- common methods */ - /** - * Common "check" method for transports - * - * @param string $trtok - * transport token - * @return array - * struct/hasharray with fields: - * trtype: string - - * audioclip | playlist | playlistPkg | metadata | file - * state: string - transport state - * init | pending | waiting | finished | closed | failed - * direction: string - up | down - * expectedsize: int - file size in bytes - * realsize: int - currently transported bytes - * expectedsum: string - orginal file checksum - * realsum: string - transported file checksum - * title: string - dc:title or filename etc. - * errmsg: string - error message for failed transports - * ... ? - */ - function getTransportInfo($trtok) - { - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $res = array(); - foreach (array( - 'trtype', 'state', 'direction', 'expectedsize', 'realsize', - 'expectedsum', 'realsum', 'title', 'errmsg' - ) as $k) { - $res[$k] = ( isset($trec->row[$k]) ? $trec->row[$k] : NULL ); - } - if ( ($trec->row['direction'] == 'down') && file_exists($trec->row['localfile']) ){ - $res['realsize'] = filesize($trec->row['localfile']); - $res['realsum'] = $this->_chsum($trec->row['localfile']); - } - if ( ($trec->row['direction'] == 'up') ){ - $check = $this->uploadCheck($trec->row['pdtoken']); - if (!PEAR::isError($check)) { - $res['realsize'] = $check['size']; - $res['realsum'] = $check['realsum']; - } - } - return $res; - } - - - /** - * Turn transports on/off, optionaly return current state. - * (true=On / false=off) - * - * @param string $sessid - * session id - * @param boolean $onOff - * optional (if not used, current state is returned) - * @return boolea - * previous state - */ - function turnOnOffTransports($sessid, $onOff=NULL) - { - require_once('Prefs.php'); - $pr = new Prefs($this->gb); - $group = $CC_CONFIG['StationPrefsGr']; - $key = 'TransportsDenied'; - $res = $pr->loadGroupPref($group, $key); - if (PEAR::isError($res)) { - if ($res->getCode() !== GBERR_PREF) { - return $res; - } else { - $res = FALSE; // default - } - } - $state = !$res; - if (is_null($onOff)) { - return $state; - } - $res = $pr->saveGroupPref($sessid, $group, $key, !$onOff); - if (PEAR::isError($res)) { - return $res; - } - return $state; - } - - - /** - * Pause, resume or cancel transport - * - * @param string $trtok - * transport token - * @param string $action - * pause | resume | cancel - * @return string - * resulting transport state - */ - function doTransportAction($trtok, $action) - { - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - if ($trec->getState() == 'closed') { - return PEAR::raiseError( - "Transport::doTransportAction:". - " closed transport token ($trtok)", TRERR_TOK - ); - } - switch ($action) { - case 'pause'; - $newState = 'paused'; - break; - case 'resume'; - $newState = 'waiting'; - break; - case 'cancel'; - $newState = 'closed'; - break; - default: - return PEAR::raiseError( - "Transport::doTransportAction:". - " unknown action ($action)" - ); - } - $res = $trec->setState($newState); - switch ($action) { - case 'pause'; - case 'cancel'; - $trec->killJob(); - } - return $res; - } - - /* ------------- special methods for audioClip/webstream object transport */ - - /** - * Start upload of audioClip/webstream/playlist from local storageServer - * to hub. - * - * @param string $gunid - * global unique id of object being transported - * @param boolean $withContent - * if true, transport playlist content too (optional) - * @param array $pars - * default parameters (optional, internal use) - * @return string - * transport token - */ - function upload2Hub($gunid, $withContent=TRUE, $pars=array()) - { - global $CC_CONFIG, $CC_DBC; - $this->trLog("upload2Hub start: ".strftime("%H:%M:%S")); - switch ($ftype = BasicStor::GetType($gunid)) { - case "audioclip": - case "webstream": - $storedFile = StoredFile::RecallByGunid($gunid); - if (is_null($storedFile) || PEAR::isError($storedFile)) { - return $storedFile; - } - // handle metadata: - $mdfpath = $storedFile->getRealMetadataFileName(); - if (PEAR::isError($mdfpath)) { - return $mdfpath; - } - $mdtrec = $this->_uploadGeneralFileToHub($mdfpath, 'metadata', - array_merge(array('gunid'=>$gunid, 'fname'=>'metadata',), $pars) - ); - if (PEAR::isError($mdtrec)) { - return $mdtrec; - } - // handle raw media file: - $fpath = $storedFile->getRealFilePath(); - if (PEAR::isError($fpath)) { - return $fpath; - } - $fname = $storedFile->getName(); - if (PEAR::isError($fname)) { - return $fname; - } - $trec = $this->_uploadGeneralFileToHub($fpath, 'audioclip', - array_merge(array( - 'gunid'=>$gunid, 'fname'=>$fname, 'mdtrtok'=>$mdtrec->trtok, - ), $pars) - ); - if (PEAR::isError($trec)) { - return $trec; - } - $this->startCronJobProcess($mdtrec->trtok); - break; - - case "playlist": - $plid = $gunid; - require_once("Playlist.php"); - $pl = StoredFile::RecallByGunid($plid); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - $fname = $pl->getName(); - if (PEAR::isError($fname)) { - return $fname; - } - if ($withContent) { - $this->trLog("upload2Hub exportPlaylistOpen BEGIN: ".strftime("%H:%M:%S")); - $res = $this->gb->bsExportPlaylistOpen($plid); - $this->trLog("upload2Hub exportPlaylistOpen END: ".strftime("%H:%M:%S")); - if (PEAR::isError($res)) { - return $res; - } - $tmpn = tempnam($CC_CONFIG['transDir'], 'plExport_'); - $plfpath = "$tmpn.lspl"; - $this->trLog("upload2Hub begin copy: ".strftime("%H:%M:%S")); - copy($res['fname'], $plfpath); - $this->trLog("upload2Hub end copy: ".strftime("%H:%M:%S")); - $res = $this->gb->bsExportPlaylistClose($res['token']); - if (PEAR::isError($res)) { - return $res; - } - $fname = $fname.".lspl"; - $trtype = 'playlistPkg'; - } else { - $plfpath = $pl->getRealMetadataFileName(); - if (PEAR::isError($plfpath)) { - return $plfpath; - } - $trtype = 'playlist'; - } - $trec = $this->_uploadGeneralFileToHub($plfpath, $trtype, - array_merge(array('gunid'=>$plid,'fname'=>$fname,), $pars)); - if (PEAR::isError($trec)) { - return $trec; - } - break; - default: - return PEAR::raiseError("Transport::upload2Hub: ftype not supported ($ftype)"); - } - $this->startCronJobProcess($trec->trtok); - $this->trLog("upload2Hub end: ".strftime("%H:%M:%S")); - return $trec->trtok; - } - - - /** - * Start download of audioClip/webstream/playlist from hub to local - * storageServer - * - * @param int $uid - * local user id of transport owner - * (for downloading file to homedir in storage) - * @param string $gunid - * global unique id of object being transported - * @param boolean $withContent - * if true, transport playlist content too (optional) - * @param array $pars - * default parameters (optional, internal use) - * @return string - * transport token - */ - function downloadFromHub($uid, $gunid, $withContent=TRUE, $pars=array()) - { - $trtype = ($withContent ? 'playlistPkg' : 'unknown' ); - $trec = TransportRecord::create($this, $trtype, 'down', - array_merge(array('gunid'=>$gunid, 'uid'=>$uid), $pars)); - if (PEAR::isError($trec)) { - return $trec; - } - $this->startCronJobProcess($trec->trtok); - return $trec->trtok; - } - - - /* ------------------------------------------------ remote-search methods */ - /** - * Start search job on remote Campcaster instance. - * - * @param array $criteria - * LS criteria format (see localSearch) - * @param string $resultMode - * 'php' | 'xmlrpc' - * @param array $pars - * default parameters (optional, internal use) - * @return string - * transport token - */ - function remoteSearch($criteria, $resultMode='php') - { - global $CC_CONFIG, $CC_DBC; - $criteria['resultMode'] = $resultMode; - - // testing of hub availability and hub account configuration. - $sessid = $this->loginToArchive(); - if (PEAR::isError($sessid)) { - switch(intval($sessid->getCode())) { - case 802: - return PEAR::raiseError("Can't login to Hub ({$sessid->getMessage()})", TRERR_XR_FAIL); - case TRERR_XR_FAIL: - return PEAR::raiseError("Can't connect to Hub ({$sessid->getMessage()})", TRERR_XR_FAIL); - } - return $sessid; - } - $params = array("sessid" => $sessid, "criteria" => $criteria); - $result = $this->xmlrpcCall("locstor.searchMetadata", $params); - //$result = $this->xmlrpcCall("locstor.ping", array("par" => "foo")); - $this->logoutFromArchive($sessid); - return $result; - } - - /** - * Start search job on network hub - * - * @param array $criteria - * LS criteria format (see localSearch) - * @param string $resultMode - * 'php' | 'xmlrpc' - * @param array $pars - * default parameters (optional, internal use) - * @return string - * transport token - */ - // function globalSearch($criteria, $resultMode='php', $pars=array()) - // { - // global $CC_CONFIG, $CC_DBC; - // // testing of hub availability and hub account configuration. - // // it makes searchjob not async - should be removed for real async - // $r = $this->loginToArchive(); - // if (PEAR::isError($r)) { - // switch(intval($r->getCode())) { - // case 802: - // return PEAR::raiseError("Can't login to Hub ({$r->getMessage()})", TRERR_XR_FAIL); - // case TRERR_XR_FAIL: - // return PEAR::raiseError("Can't connect to Hub ({$r->getMessage()})", TRERR_XR_FAIL); - // } - // return $r; - // } - // $this->logoutFromArchive($r); - // $criteria['resultMode'] = $resultMode; - // $localfile = tempnam($CC_CONFIG['transDir'], 'searchjob_'); - // @chmod($localfile, 0660); - // $len = file_put_contents($localfile, serialize($criteria)); - // $trec = $this->_uploadGeneralFileToHub($localfile, 'searchjob', $pars); - // if (PEAR::isError($trec)) { - // return $trec; - // } - // $this->startCronJobProcess($trec->trtok); - // return $trec->trtok; - // } - - - /** - * Get results from search job on network hub - * - * @param string $trtok - * transport token - * @param boolean $andClose - * if TRUE, close transport token - * @return array - * LS search result format (see localSearch) - */ - // function getSearchResults($trtok, $andClose=TRUE) - // { - // $trec = TransportRecord::recall($this, $trtok); - // if (PEAR::isError($trec)) { - // return $trec; - // } - // $row = $trec->row; - // switch ($st = $trec->getState()) { - // case "failed": - // return PEAR::raiseError( - // "Transport::getSearchResults:". - // " global search or results transport failed". - // " ({$trec->row['errmsg']})" - // ); - // case "closed": - ///* - // $res = file_get_contents($row['localfile']); - // $results = unserialize($res); - // return $results; - //*/ - // return PEAR::raiseError( - // "Transport::getSearchResults:". - // " closed transport token ($trtok)", TRERR_TOK - // ); - // case "finished": - // if ($row['direction'] == 'down') { - // // really finished - // $res = file_get_contents($row['localfile']); - // $results = unserialize($res); - // if ($andClose) { - // $ret = $this->xmlrpcCall('archive.downloadClose', - // array( - // 'token' => $row['pdtoken'] , - // 'trtype' => $row['trtype'] , - // )); - // if (PEAR::isError($ret)) { - // return $ret; - // } - // @unlink($row['localfile']); - // $r = $trec->close(); - // if (PEAR::isError($r)) { - // return $r; - // } - // } - // return $results; - // } - // // otherwise not really finished - only request upload finished - // default: - // return PEAR::raiseError( - // "Transport::getSearchResults: not finished ($st)", - // TRERR_NOTFIN - // ); - // } - // } - - - /* ------------------------ methods for ls-archive-format file transports */ - /** - * Open async file transfer from local storageServer to network hub, - * file should be ls-archive-format file. - * - * @param string $filePath - * local path to uploaded file - * @param array $pars - * default parameters (optional, internal use) - * @return string - * transport token - */ - function uploadFile2Hub($filePath, $pars=array()) - { - if (!file_exists($filePath)) { - return PEAR::raiseError( - "Transport::uploadFile2Hub: file not found ($filePath)" - ); - } - $trec = $this->_uploadGeneralFileToHub($filePath, 'file', $pars); - if (PEAR::isError($trec)) { - return $trec; - } - $this->startCronJobProcess($trec->trtok); - return $trec->trtok; - } - - - /** - * Open async file transfer from network hub to local storageServer, - * file should be ls-archive-format file. - * - * @param string $url - * readable url - * @param string $chsum - * checksum from remote side - * @param int $size - * filesize from remote side - * @param array $pars - * default parameters (internal use) - * @return array - * trtok: string - transport token - * localfile: string - filepath of downloaded file - */ - function downloadFileFromHub($url, $chsum=NULL, $size=NULL, $pars=array()) - { - global $CC_CONFIG, $CC_DBC; - $tmpn = tempnam($CC_CONFIG['transDir'], 'HITrans_'); - $trec = TransportRecord::create($this, 'file', 'down', - array_merge(array( - 'url' => $url, - 'localfile' => $tmpn, - 'expectedsum' => $chsum, - 'expectedsize' => $size, - ), $pars) - ); - if (PEAR::isError($trec)) { - return $trec; - } - $this->startCronJobProcess($trec->trtok); - return array('trtok'=>$trec->trtok, 'localfile'=>$tmpn); - } - - - /** - * Get list of prepared transfers initiated by hub - * - * @return array - * array of structs/hasharrays with fields: - * trtok: string transport token - */ - function getHubInitiatedTransfers() - { - $ret = $this->xmlrpcCall('archive.listHubInitiatedTransfers', - array('target' => HOSTNAME)); - if (PEAR::isError($ret)) { - return $ret; - } - $res = array(); - foreach ($ret as $it) { - $res[] = array('trtok'=>$it['trtok']); - } - return $res; - } - - - /** - * Start of download initiated by hub - * - * @param int $uid - * local user id of transport owner - * (for downloading file to homedir in storage) - * @param string $rtrtok - * transport token obtained from the getHubInitiatedTransfers method - * @return string - * transport token - */ - function startHubInitiatedTransfer($uid, $rtrtok) - { - $ret = $this->xmlrpcCall('archive.listHubInitiatedTransfers', - array( - 'target' => HOSTNAME, - 'trtok' => $rtrtok, - )); - if (PEAR::isError($ret)) { - return $ret; - } - if (count($ret) != 1) { - return PEAR::raiseError( - "Transport::startHubInitiatedTransfer:". - " wrong number of transports (".count($ret).")" - ); - } - $ta = $ret[0]; - // direction invertation to locstor point of view: - $direction = ( $ta['direction']=='up' ? 'down' : 'up' ); - $gunid = $ta['gunid']; - switch ($direction) { - case "up": - switch ($ta['trtype']) { - case "audioclip": - case "playlist": - case "playlistPkg": - $trtok = $this->upload2Hub($gunid, TRUE, - array('rtrtok'=>$rtrtok)); - if (PEAR::isError($trtok)) { - return $trtok; - } - break; - //case "searchjob": break; // not supported yet - //case "file": break; // probably unusable - default: - return PEAR::raiseError( - "Transport::startHubInitiatedTransfer:". - " wrong direction / transport type combination". - " ({$ta['direction']}/{$ta['trtype']})" - ); - } - break; - case "down": - switch ($ta['trtype']) { - case "audioclip": - case "playlist": - case "playlistPkg": - $trtok = $this->downloadFromHub($uid, $gunid, TRUE, - array('rtrtok'=>$rtrtok)); - if (PEAR::isError($trtok)) { - return $trtok; - } - break; - //case "searchjob": break; // probably unusable - case "file": - $r = $this->downloadFileFromHub( - $ta['url'], $ta['expectedsum'], $ta['expectedsize'], - array('rtrtok'=>$rtrtok)); - if (PEAR::isError($r)) { - return $r; - } - extract($r); // trtok, localfile - break; - default: - return PEAR::raiseError( - "Transport::startHubInitiatedTransfer:". - " wrong direction / transport type combination". - " ({$ta['direction']}/{$ta['trtype']})" - ); - } - break; - default: - return PEAR::raiseError( - "Transport::startHubInitiatedTransfer: ???" - ); - } - $ret = $this->xmlrpcCall('archive.setHubInitiatedTransfer', - array( - 'target' => HOSTNAME, - 'trtok' => $rtrtok, - 'state' => 'waiting', - )); - if (PEAR::isError($ret)) { - return $ret; - } - $this->startCronJobProcess($trtok); - return $trtok; - } - - - /* =============================================== authentication methods */ - - /** - * Login to archive server - * (account info is taken from storageServer's config) - * - * @return string - * sessid or error - */ - function loginToArchive() - { - global $CC_CONFIG; - $res = $this->xmlrpcCall('locstor.login', - array( - 'login' => $CC_CONFIG['archiveAccountLogin'], - 'pass' => $CC_CONFIG['archiveAccountPass'] - )); - if (PEAR::isError($res)) { - return $res; - } - return $res['sessid']; - } - - - /** - * Logout from archive server - * - * @param unknown $sessid - * session id - * @return string - * Bye or error - */ - function logoutFromArchive($sessid) - { - $res = $this->xmlrpcCall('locstor.logout', - array('sessid'=>$sessid)); - return $res; - } - - - /* ========================================================= cron methods */ - /* -------------------------------------------------- common cron methods */ - /** - * Main method for periodical transport tasks - called by cron - * - * @param string $direction - * optional - * @return boolean - * TRUE - */ - function cronMain($direction=NULL) - { - global $CC_CONFIG; - if (is_null($direction)) { - $r = $this->cronMain('up'); - if (PEAR::isError($r)) { - return $r; - } - $r = $this->cronMain('down'); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - // fetch all opened transports - $transports = $this->getTransports($direction); - if (PEAR::isError($transports)) { - $this->trLog("cronMain: DB error"); - return FALSE; - } - if (count($transports) == 0) { - if (TR_LOG_LEVEL > 1) { - $this->trLog("cronMain: $direction - nothing to do."); - } - return TRUE; - } - // ping to archive server: - $r = $this->ping(); - chdir($CC_CONFIG['transDir']); - // for all opened transports: - foreach ($transports as $i => $row) { - $r = $this->startCronJobProcess($row['trtok']); - } // foreach transports - return TRUE; - } - - - /** - * Cron job process starter - * - * @param string $trtok - * transport token - * @return boolean - * status - */ - function startCronJobProcess($trtok) - { - global $CC_CONFIG, $CC_DBC; - if (TR_LOG_LEVEL > 2) { - $redirect = $CC_CONFIG['transDir']."/debug.log"; - } else { - $redirect = "/dev/null"; - } - $redirect_escaped = escapeshellcmd($redirect); - $command = "{$this->cronJobScript} {$trtok}"; - $command_escaped = escapeshellcmd($command); - $command_final = "$command_escaped >> $redirect_escaped 2>&1 &"; - $res = system($command_final, $status); - if ($res === FALSE) { - $this->trLog( - "cronMain: Error on execute cronJobScript with trtok {$trtok}" - ); - return FALSE; - } - return TRUE; - } - - - /** - * Dynamic method caller - wrapper - * - * @param string $trtok - * transport token - * @return mixed - * inherited from called method - */ - function cronCallMethod($trtok) - { - global $CC_CONFIG; - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $row = $trec->row; - $state = $row['state']; - - $states = array('init'=>'init', - 'pending'=>'pending', - 'waiting'=>'waiting', - 'finished'=>'finished', - 'failed'=>'failed', - 'closed'=>'closed'); - $directions = array('up'=>'upload', 'down'=>'download'); - // method name construction: - $mname = "cron"; - if (isset($directions[$row['direction']])) { - $mname .= ucfirst($directions[$row['direction']]); - } else { - return PEAR::raiseError( - "Transport::cronCallMethod: invalid direction ({$row['direction']})" - ); - } - if (isset($states[$state])) { - $mname .= ucfirst($states[$state]); - } else { - return PEAR::raiseError( - "Transport::cronCallMethod: invalid state ({$state})" - ); - } - switch ($state) { - // do nothing if closed, penfing or failed: - case 'closed': // excluded in SQL query too, but let check it here - case 'failed': // -"- - case 'pending': - case 'paused': - return TRUE; - case 'waiting': - require_once('Prefs.php'); - $pr = new Prefs($this->gb); - $group = $CC_CONFIG['StationPrefsGr']; - $key = 'TransportsDenied'; - $res = $pr->loadGroupPref($group, $key); - if (PEAR::isError($res)) { - if ($res->getCode() !== GBERR_PREF) { - return $res; - } else { - $res = FALSE; // default - } - } - // transfers turned off - // if ($res) { return TRUE; break; } - if ($res) { - return PEAR::raiseError( - "Transport::cronCallMethod: transfers turned off" - ); - } - // NO break here! - default: - if (method_exists($this, $mname)) { - // lock the job: - $pid = getmypid(); - $r = $trec->setLock(TRUE, $pid); - if (PEAR::isError($r)) { - return $r; - } - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - $trec->setLock(FALSE); - return $trec; - } - $row = $trec->row; - $state = $row['state']; - - // login to archive server: - $r = $this->loginToArchive(); - if (PEAR::isError($r)) { - $r2 = $trec->setLock(FALSE); - return $r; - } - $asessid = $r; - // method call: - if (TR_LOG_LEVEL > 2) { - $this->trLog("cronCallMethod($pid): $mname($trtok) >"); - } - $ret = call_user_func(array($this, $mname), $row, $asessid); - if (PEAR::isError($ret)) { - $trec->setLock(FALSE); - return $this->_failFatal($ret, $trec); - } - if (TR_LOG_LEVEL > 2) { - $this->trLog("cronCallMethod($pid): $mname($trtok) <"); - } - // unlock the job: - $r = $trec->setLock(FALSE); - if (PEAR::isError($r)) { - return $r; - } - // logout: - $r = $this->logoutFromArchive($asessid); - if (PEAR::isError($r)) { - return $r; - } - return $ret; - } else { - return PEAR::raiseError( - "Transport::cronCallMethod: unknown method ($mname)" - ); - } - } - } - - - /** - * Upload initialization - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronUploadInit($row, $asessid) - { - $trtok = $row['trtok']; - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $ret = $this->xmlrpcCall('archive.uploadOpen', - array( - 'sessid' => $asessid , - 'chsum' => $row['expectedsum'], - )); - if (PEAR::isError($ret)) { - return $ret; - } - $r = $trec->setState('waiting', - array('url'=>$ret['url'], 'pdtoken'=>$ret['token'])); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /** - * Download initialization - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronDownloadInit($row, $asessid) - { - global $CC_CONFIG; - $trtok = $row['trtok']; - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $ret = $this->xmlrpcCall('archive.downloadOpen', - array( - 'sessid'=> $asessid, - 'trtype'=> $row['trtype'], - 'pars'=>array( - 'gunid' => $row['gunid'], - 'token' => $row['pdtoken'], - ), - )); - if (PEAR::isError($ret)) { - return $ret; - } - $trtype = $ret['trtype']; - $title = $ret['title']; - $pars = array(); - switch ($trtype) { - // case "searchjob": - // $r = $trec->setState('waiting', $pars); - // break; - case "file": - $r = $trec->setState('waiting',array_merge($pars, array( - 'trtype'=>$trtype, - 'url'=>$ret['url'], 'pdtoken'=>$ret['token'], - 'expectedsum'=>$ret['chsum'], 'expectedsize'=>$ret['size'], - 'fname'=>$ret['filename'], - 'localfile'=>$CC_CONFIG['transDir']."/$trtok", - ))); - break; - case "audioclip": - $mdtrec = TransportRecord::create($this, 'metadata', 'down', - array('gunid'=>$row['gunid'], 'uid'=>$row['uid'], ) - ); - if (PEAR::isError($mdtrec)) { - return $mdtrec; - } - $this->startCronJobProcess($mdtrec->trtok); - $pars = array('mdtrtok'=>$mdtrec->trtok); - // NO break here ! - default: - $r = $trec->setState('waiting',array_merge($pars, array( - 'trtype'=>$trtype, - 'url'=>$ret['url'], 'pdtoken'=>$ret['token'], - 'expectedsum'=>$ret['chsum'], 'expectedsize'=>$ret['size'], - 'fname'=>$ret['filename'], 'title'=>$title, - 'localfile'=>$CC_CONFIG['transDir']."/$trtok", - ))); - } - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /** - * Upload next part of transported file - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronUploadWaiting($row, $asessid) - { - $trtok = $row['trtok']; - $check = $this->uploadCheck($row['pdtoken']); - if (PEAR::isError($check)) { - return $check; - } - // test filesize - if (!file_exists($row['localfile'])) { - return PEAR::raiseError("Transport::cronUploadWaiting:". - " file being uploaded does not exist! ({$row['localfile']})" - ); - } - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $size = escapeshellarg($check['size']); - $localfile = escapeshellarg($row['localfile']); - $url = escapeshellarg($row['url']); - $command = - "curl -f -s -C $size --max-time {$this->upTrMaxTime}". - " --speed-time {$this->upTrSpeedTime}". - " --speed-limit {$this->upTrSpeedLimit}". - " --connect-timeout {$this->upTrConnectTimeout}". - (!is_null($this->upLimitRate)? - " --limit-rate {$this->upLimitRate}" : ""). - " -T $localfile $url"; - $r = $trec->setState('pending', array(), 'waiting'); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - return TRUE; - } - $res = system($command, $status); - - // leave paused and closed transports - $trec2 = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $state2 = $trec2->row['state']; - if ($state2 == 'paused' || $state2 == 'closed' ) { - return TRUE; - } - - - // status 18 - Partial file. Only a part of the file was transported. - // status 28 - Timeout. Too long/slow upload, try to resume next time rather. - // status 6 - Couldn't resolve host. - // status 7 - Failed to connect to host. - // status 56 - Failure in receiving network data. Important - this status is - // returned if file is locked on server side - if ($status == 0 || $status == 18 || $status == 28 || $status == 6 || $status == 7 || $status == 56) { - $check = $this->uploadCheck($row['pdtoken']); - if (PEAR::isError($check)) { - return $check; - } - // test checksum - if ($check['status'] == TRUE) { - // finished - $r = $trec->setState('finished', - array('realsum'=>$check['realsum'], 'realsize'=>$check['size'])); - if (PEAR::isError($r)) { - return $r; - } - } else { - if (intval($check['size']) < $row['expectedsize']) { - $r = $trec->setState('waiting', - array('realsum'=>$check['realsum'], 'realsize'=>$check['size'])); - if (PEAR::isError($r)) { - return $r; - } - } else { - // wrong md5 at finish - TODO: start again - // $this->xmlrpcCall('archive.uploadReset', array()); - $trec->fail('file uploaded with bad md5'); - return PEAR::raiseError("Transport::cronUploadWaiting:". - " file uploaded with bad md5 ". - "($trtok: {$check['realsum']}/{$check['expectedsum']})" - ); - } - } - } else { - return PEAR::raiseError("Transport::cronUploadWaiting:". - " wrong return status from curl: $status on $url". - "($trtok)" - ); - } - return TRUE; - } - - - /** - * Download next part of transported file - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronDownloadWaiting($row, $asessid) - { - $trtok = $row['trtok']; - // wget the file - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $localfile = escapeshellarg($row['localfile']); - $url = escapeshellarg($row['url']); - $command = - "wget -q -c". - " --read-timeout={$this->downTimeout}". - " --waitretry={$this->downWaitretry}". - " -t {$this->downRetries}". - (!is_null($this->downLimitRate)? - " --limit-rate={$this->downLimitRate}" : ""). - " -O $localfile $url" - ; - $r = $trec->setState('pending', array(), 'waiting'); - if (PEAR::isError($r)) { - return $r; - } - if ($r === FALSE) { - return TRUE; - } - $res = system($command, $status); - - // leave paused and closed transports - $trec2 = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - $state2 = $trec2->row['state']; - if ($state2 == 'paused' || $state2 == 'closed' ) { - return TRUE; - } - - // check consistency - $size = filesize($row['localfile']); - if ($size < $row['expectedsize']) { - // not finished - return to the 'waiting' state - $r = $trec->setState('waiting', array('realsize'=>$size)); - if (PEAR::isError($r)) { - return $r; - } - } elseif ($size >= $row['expectedsize']) { - $chsum = $this->_chsum($row['localfile']); - if ($chsum == $row['expectedsum']) { - // mark download as finished - $r = $trec->setState('finished', - array('realsum'=>$chsum, 'realsize'=>$size)); - if (PEAR::isError($r)) { - return $r; - } - } else { - // bad checksum, retry from the scratch - @unlink($row['localfile']); - $r = $trec->setState('waiting', - array('realsum'=>$chsum, 'realsize'=>$size)); - if (PEAR::isError($r)) { - return $r; - } - } - } - return TRUE; - } - - - /** - * Finish the upload - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronUploadFinished($row, $asessid) - { - global $CC_CONFIG; - $trtok = $row['trtok']; - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - // don't close metadata transport - audioclip will close it - if ($row['trtype'] == 'metadata') { - return TRUE; - } - // handle metadata transport on audioclip trtype: - if ($row['trtype'] == 'audioclip') { - $mdtrec = TransportRecord::recall($this, $trec->row['mdtrtok']); - if (PEAR::isError($mdtrec)) { - return $mdtrec; - } - switch ($mdtrec->row['state']) { - case 'failed': - case 'closed': - return PEAR::raiseError("Transport::cronUploadFinished:". - " metadata transport in wrong state: {$mdtrec->row['state']}". - " ({$this->trtok})" - ); - break; - // don't close transport with nonfinished metadata transport: - case 'init': - case 'waiting': - case 'pending': - case 'paused': - return TRUE; - default: // finished - ok close parent transport - $mdpdtoken = $mdtrec->row['pdtoken']; - } - } else { - $mdpdtoken = NULL; - } - $ret = $this->xmlrpcCall('archive.uploadClose', - array( - 'token' => $row['pdtoken'] , - 'trtype' => $row['trtype'], - 'pars' => array( - 'gunid' => $row['gunid'], - 'name' => $row['fname'], - 'mdpdtoken' => $mdpdtoken, - ), - )); - if (PEAR::isError($ret)) { - if ($row['trtype'] == 'audioclip') { - $r2 = $mdtrec->close(); - } - return $ret; - } - - // if ($row['trtype'] == 'searchjob') { - // @unlink($row['localfile']); - // $r = $trec->setState('init', array( - // 'direction' => 'down', - // 'pdtoken' => $ret['token'], - // 'expectedsum' => $ret['chsum'], - // 'expectedsize' => $ret['size'], - // 'url' => $ret['url'], - // 'realsize' => 0, - // )); - // $this->startCronJobProcess($trec->trtok); - // } else { - $r = $trec->close(); - // } - if (PEAR::isError($r)) { - return $r; - } - switch ($row['trtype']) { - case 'audioclip': - // close metadata transport: - $r = $mdtrec->close(); - if (PEAR::isError($r)) { - return $r; - } - break; - case 'playlistPkg': - // remove exported playlist (playlist with content) - $ep = $row['localfile']; - @unlink($ep); - if (preg_match("|/(plExport_[^\.]+)\.lspl$|", $ep, $va)) { - list(,$tmpn) = $va; $tmpn = $CC_CONFIG['transDir']."/$tmpn"; - if (file_exists($tmpn)) { - @unlink($tmpn); - } - } - - break; - default: - } - - return TRUE; - } - - - /** - * Finish the download - * - * @param array $row - * row from getTransport results - * @param string $asessid - * session id (from network hub) - * @return mixed - * boolean TRUE or error object - */ - function cronDownloadFinished($row, $asessid) - { - $trtok = $row['trtok']; - $trec = TransportRecord::recall($this, $trtok); - if (PEAR::isError($trec)) { - return $trec; - } - switch ($row['trtype']) { - case "audioclip": - $mdtrtok = $trec->row['mdtrtok']; - $mdtrec = TransportRecord::recall($this, $mdtrtok); - if (PEAR::isError($mdtrec)) { - return $mdtrec; - } - $pid = getmypid(); - $r = $mdtrec->setLock(TRUE, $pid); - if (PEAR::isError($r)) { - return $r; - } - switch ($mdtrec->row['state']) { - // don't close transport with nonfinished metadata transport: - case 'init': - case 'waiting': - case 'pending': - case 'paused': - $r = $mdtrec->setLock(FALSE); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - case 'finished': // metadata finished, close main transport - $values = array( - "filename" => $row['fname'], - "filepath" => $trec->row['localfile'], - "metadata" => $mdtrec->row['localfile'], - "gunid" => $row['gunid'], - "filetype" => "audioclip" - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - $mdtrec->setLock(FALSE); - return $storedFile; - } - $res = $storedFile->getId(); - $ret = $this->xmlrpcCall('archive.downloadClose', - array( - 'token' => $mdtrec->row['pdtoken'] , - 'trtype' => 'metadata' , - )); - if (PEAR::isError($ret)) { - $mdtrec->setLock(FALSE); - return $ret; - } - $r = $mdtrec->close(); - if (PEAR::isError($r)) { - $r2 = $mdtrec->setLock(FALSE); - return $r; - } - @unlink($trec->row['localfile']); - @unlink($mdtrec->row['localfile']); - break; - default: - $r = $mdtrec->setLock(FALSE); - return PEAR::raiseError("Transport::cronDownloadFinished:". - " metadata transport in wrong state: {$mdtrec->row['state']}". - " ({$this->trtok})" - ); - } - $r = $mdtrec->setLock(FALSE); - if (PEAR::isError($r)) { - return $r; - } - break; - case "metadata": - // case "searchjob": - return TRUE; // don't close - getSearchResults should close it - break; - } - $ret = $this->xmlrpcCall('archive.downloadClose', - array( - 'token' => $row['pdtoken'] , - 'trtype' => $row['trtype'] , - )); - if (PEAR::isError($ret)) { - return $ret; - } - switch ($row['trtype']) { - case "playlist": - $values = array( - "filename" => $row['fname'], - "metadata" => $trec->row['localfile'], - "gunid" => $row['gunid'], - "filetype" => "playlist" - ); - $storedFile = StoredFile::Insert($values); - if (PEAR::isError($storedFile)) { - return $storedFile; - } - $res = $storedFile->getId(); - @unlink($row['localfile']); - break; - case "playlistPkg": - $subjid = $trec->row['uid']; - $fname = $trec->row['localfile']; - $res = $this->gb->bsImportPlaylist($fname, $subjid); - if (PEAR::isError($res)) { - return $res; - } - @unlink($fname); - break; - case "audioclip": - case "metadata": - // case "searchjob": - case "file": - break; - default: - return PEAR::raiseError("DEBUG: NotImpl ".var_export($row,TRUE)); - } - if (!is_null($rtrtok = $trec->row['rtrtok'])) { - $ret = $this->xmlrpcCall('archive.setHubInitiatedTransfer', - array( - 'target' => HOSTNAME, - 'trtok' => $rtrtok, - 'state' => 'closed', - )); - if (PEAR::isError($ret)) { - return $ret; - } - } - $r = $trec->close(); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /* ==================================================== auxiliary methods */ - /** - * Prepare upload for general file - * - * @param string $fpath - * local filepath of uploaded file - * @param string $trtype - * transport type - * @param array $pars - * default parameters (optional, internal use) - * @return object - transportRecord instance - */ - function _uploadGeneralFileToHub($fpath, $trtype, $pars=array()) - { - $chsum = $this->_chsum($fpath); - $size = filesize($fpath); - $trec = TransportRecord::create($this, $trtype, 'up', - array_merge(array( - 'localfile'=>$fpath, 'fname'=>basename($fpath), - 'expectedsum'=>$chsum, 'expectedsize'=>$size - ), $pars) - ); - if (PEAR::isError($trec)) { - return $trec; - } - return $trec; - } - - - /** - * Create new transport token - * - * @return string - * transport token - */ - function _createTransportToken() - { - $ip = (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : ''); - $initString = microtime().$ip.rand()."org.mdlf.campcaster"; - $hash = md5($initString); - $res = substr($hash, 0, 16); - return $res; - } - - - /** - * Get all relevant transport records - * - * @param string $direction - * 'up' | 'down' - * @param string $target - * target hostname - * @param string $trtok - * transport token for specific query - * @return array - * array of transportRecords (as hasharrays) - */ - function getTransports($direction=NULL, $target=NULL, $trtok=NULL) - { - global $CC_CONFIG, $CC_DBC; - switch ($direction) { - case 'up': - $dirCond = "direction='up' AND"; - break; - case 'down': - $dirCond = "direction='down' AND"; - break; - default: - $dirCond = ''; - break; - } - if (is_null($target)) { - $targetCond = ""; - } else { - $targetCond = "target='$target' AND"; - } - if (is_null($trtok)) { - $trtokCond = ""; - } else { - $trtokCond = "trtok='$trtok' AND"; - } - $rows = $CC_DBC->getAll(" - SELECT - id, trtok, state, trtype, direction, - to_hex(gunid)as gunid, to_hex(pdtoken)as pdtoken, - fname, localfile, expectedsum, expectedsize, url, - uid, target - FROM ".$CC_CONFIG['transTable']." - WHERE $dirCond $targetCond $trtokCond - state not in ('closed', 'failed', 'paused') - ORDER BY start DESC - "); - if (PEAR::isError($rows)) { - return $rows; - } - foreach ($rows as $i => $row) { - $rows[$i]['pdtoken'] = StoredFile::NormalizeGunid($row['pdtoken']); - $rows[$i]['gunid'] = StoredFile::NormalizeGunid($row['gunid']); - } - return $rows; - } - - - /** - * Check remote state of uploaded file - * - * @param string $pdtoken - * put/download token (from network hub) - * @return array - * hash: chsum, size, url - */ - function uploadCheck($pdtoken) - { - $ret = $this->xmlrpcCall('archive.uploadCheck', - array('token'=>$pdtoken)); - return $ret; - } - - - /** - * Ping to remote Campcaster server - * - * @return string - * network hub response or error object - */ - function ping() - { - $res = $this->xmlrpcCall('ping', - array('par'=>'ping_'.date('H:i:s'))); - return $res; - } - - - /** - * XMLRPC call to network hub. - * - * @param string $method - * method name - * @param array $pars - * call parameters - * @return mixed - * response - */ - function xmlrpcCall($method, $pars=array()) - { - global $CC_CONFIG; - $xrp = XML_RPC_encode($pars); - - $pr = new Prefs($this->gb); - $group = $CC_CONFIG["StationPrefsGr"]; - $key = 'archiveServerLocation'; - $archiveUrl = $pr->loadGroupPref($group, $key, false); - - if ($archiveUrl) { - $archiveUrlInfo = parse_url($archiveUrl); - if ($archiveUrlInfo['port']) { - $port = $archiveUrlInfo['port']; - } - else { - $port = 80; - } - - $c = new XML_RPC_Client($archiveUrlInfo['path'], $archiveUrlInfo['host'], $port); - } - else { - $c = new XML_RPC_Client( - $CC_CONFIG['archiveUrlPath']."/".$CC_CONFIG['archiveXMLRPC'], - $CC_CONFIG['archiveUrlHost'], $CC_CONFIG['archiveUrlPort'] - ); - } - - $f = new XML_RPC_Message($method, array($xrp)); - $r = $c->send($f); - if (!$r) { - return PEAR::raiseError("XML-RPC request failed", TRERR_XR_FAIL); - } elseif ($r->faultCode() > 0) { - return PEAR::raiseError($r->faultString(), $r->faultCode()); - // return PEAR::raiseError($r->faultString(). - // " (code ".$r->faultCode().")", TRERR_XR_FAIL); - } else { - $v = $r->value(); - return XML_RPC_decode($v); - } - } - - - /** - * Checksum of local file - * - * @param string $fpath - * local filepath - * @return string - * checksum - */ - function _chsum($fpath) - { - return md5_file($fpath); - } - - - /** - * Check exception and eventually mark transport as failed - * - * @param mixed $res - * result object to be checked - * @param unknown $trec - * transport record object - * @return unknown - */ - function _failFatal($res, $trec) - { - if (PEAR::isError($res)) { - switch ($res->getCode()) { - // non fatal: - case TRERR_XR_FAIL: - break; - // fatal: - default: - $trec->fail('', $res); - } - } - return $res; - } - - - /** - * Clean up transport jobs - * - * @param string $interval - * psql time interval - older closed jobs will be deleted - * @param boolean $forced - * if true, delete non-closed jobs too - * @return boolean true or error - */ - function _cleanUp($interval='1 minute'/*'1 hour'*/, $forced=FALSE) - { - global $CC_CONFIG, $CC_DBC; - $cond = ($forced ? '' : " AND state='closed' AND lock = 'N'"); - $r = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['transTable']." - WHERE ts < now() - interval '$interval'".$cond - ); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /** - * Logging wrapper for PEAR error object - * - * @param string $txt - * log message - * @param PEAR_Error $eo - * @param array $row - * array returned from getRow - * @return mixed - * void or error object - */ - function trLogPear($txt, $eo, $row=NULL) - { - $msg = $txt.$eo->getMessage()." ".$eo->getUserInfo(). - " [".$eo->getCode()."]"; - if (!is_null($row)) { - $trec = TransportRecord::recall($this, $row['trtok']); - if (!PEAR::isError($trec)) { - $trec->setState('failed', array('errmsg'=>$msg)); - } - $msg .= "\n ".serialize($row); - } - $this->trLog($msg); - } - - - /** - * Logging for debug transports - * - * @param string $msg - * log message - * @return mixed - * void or error object - */ - function trLog($msg) - { - global $CC_CONFIG; - $logfile = $CC_CONFIG['transDir']."/activity.log"; - if (FALSE === ($fp = fopen($logfile, "a"))) { - return PEAR::raiseError( - "Transport::trLog: Can't write to log ($logfile)" - ); - } - flock($fp,LOCK_SH); - fputs($fp, "---".date("H:i:s")."---\n $msg\n"); - flock($fp,LOCK_UN); - fclose($fp); - } - - - /* ====================================================== install methods */ - /** - * Delete all transports - * - * @return mixed - * void or error object - */ - function resetData() - { - global $CC_CONFIG, $CC_DBC; - return $CC_DBC->query("DELETE FROM ".$CC_CONFIG['transTable']); - } - -} - -?> \ No newline at end of file diff --git a/backend/TransportRecord.php b/backend/TransportRecord.php deleted file mode 100644 index 6c804279c..000000000 --- a/backend/TransportRecord.php +++ /dev/null @@ -1,419 +0,0 @@ -tr =& $tr; - $this->gb =& $tr->gb; - } - - - /** - * Factory method - * - * @param Transport $tr - * @param string $trtype - * transport type (see Transport::install) - * @param string $direction - * 'up' | 'down' - * @param array $defaults - * default parameters (optional, internal use) - * @return TransportRecord - */ - function create(&$tr, $trtype, $direction='up', $defaults=array()) - { - global $CC_DBC, $CC_CONFIG; - $trec = new TransportRecord($tr); - $trec->trtok = $trtok = $tr->_createTransportToken(); - $trec->row = array_merge($defaults, - array('trtype'=>$trtype, 'direction'=>$direction)); - $trec->recalled = TRUE; - if (!isset($defaults['title'])) { - $defaults['title'] = $trec->getTitle(); - if (PEAR::isError($defaults['title'])) { - return $defaults['title']; - } - } - $id = $CC_DBC->nextId($CC_CONFIG['transSequence']); - $names = "id, trtok, direction, state, trtype, start, ts"; - $values = "$id, '$trtok', '$direction', 'init', '$trtype', now(), now()"; - foreach ($defaults as $k => $v) { - $sqlVal = $trec->_getSqlVal($k, $v); - $names .= ", $k"; - $values .= ", $sqlVal"; - } - $query = " - INSERT INTO ".$CC_CONFIG['transTable']." - ($names) - VALUES - ($values) - "; - $res = $CC_DBC->query($query); - if (PEAR::isError($res)) { - return $res; - } - return $trec; - } - - - /** - * Recall transport record from DB - * - * @param Transport $tr - * @param string $trtok - * transport token - * @return TransportRecord - */ - function recall(&$tr, $trtok) - { - global $CC_DBC, $CC_CONFIG; - $trec = new TransportRecord($tr); - $trec->trtok = $trtok; - $row = $CC_DBC->getRow(" - SELECT - id, trtok, state, trtype, direction, - to_hex(gunid)as gunid, to_hex(pdtoken)as pdtoken, - fname, localfile, url, rtrtok, mdtrtok, uid, - expectedsize, realsize, expectedsum, realsum, - errmsg, title, jobpid - FROM ".$CC_CONFIG['transTable']." - WHERE trtok='$trtok' - "); - if (PEAR::isError($row)) { - return $row; - } - if (is_null($row)) { - return PEAR::raiseError("TransportRecord::recall:". - " invalid transport token ($trtok)", TRERR_TOK - ); - } - $row['pdtoken'] = StoredFile::NormalizeGunid($row['pdtoken']); - $row['gunid'] = StoredFile::NormalizeGunid($row['gunid']); - $trec->row = $row; - $trec->recalled = TRUE; - return $trec; - } - - - /** - * Set state of transport record - * - * @param string $newState - * @param array $data - * other data fields to set - * @param string $oldState - * check old state and do nothing if differ - * @param boolean $lock - * check lock and do nothing if differ - * @return boolean success - */ - function setState($newState, $data=array(), $oldState=NULL, $lock=NULL) - { - global $CC_CONFIG, $CC_DBC; - $set = " state='$newState', ts=now()"; - if (!is_null($lock)) { - $slock = ($lock ? 'Y' : 'N'); - $nlock = (!$lock); - $snlock = ($nlock ? 'Y' : 'N'); - $set .= ", lock='$snlock'"; - } - foreach ($data as $k => $v) { - $set .= ", $k=".$this->_getSqlVal($k, $v); - } - $r = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['transTable']." - SET $set - WHERE trtok='{$this->trtok}'". - (is_null($oldState) ? '' : " AND state='$oldState'"). - (is_null($lock) ? '' : " AND lock = '$slock'") - ); - if (PEAR::isError($r)) { - return $r; - } - // return TRUE; - $affRows = $CC_DBC->affectedRows(); - if (PEAR::isError($affRows)) { - return $affRows; - } - return ($affRows == 1); - } - - - /** - * Return state of transport record - * - * @return string - * state - */ - function getState() - { - if (!$this->recalled) { - return PEAR::raiseError("TransportRecord::getState:". - " not recalled ({$this->trtok})", TRERR_TOK - ); - } - return $this->row['state']; - } - - - /** - * Set lock on transport record and save/clear process id - * - * @param boolean $lock - * lock if true, release lock if false - * @param int $pid - * process id - * @return mixed - * true or error - */ - function setLock($lock, $pid=NULL) - { - global $CC_CONFIG, $CC_DBC; - $pidsql = (is_null($pid) ? "NULL" : "$pid" ); - if ($this->dropped) { - return TRUE; - } - $slock = ($lock ? 'Y' : 'N'); - $nlock = (!$lock); - $snlock = ($nlock ? 'Y' : 'N'); - $r = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['transTable']." - SET lock='$slock', jobpid=$pidsql, ts=now() - WHERE trtok='{$this->trtok}' AND lock = '$snlock'" - ); - if (PEAR::isError($r)) { - return $r; - } - $affRows = $CC_DBC->affectedRows(); - if (PEAR::isError($affRows)) { - return $affRows; - } - if ($affRows === 0) { - $ltxt = ($lock ? 'lock' : 'unlock' ); - return PEAR::raiseError( - "TransportRecord::setLock: can't $ltxt ({$this->trtok})" - ); - } - return TRUE; - } - - - /** - * Return type of transport - * - * @return string - * Transport type - */ - function getTransportType() - { - if (!$this->recalled) { - return PEAR::raiseError("TransportRecord::getTransportType:". - " not recalled ({$this->trtok})", TRERR_TOK - ); - } - return $this->row['trtype']; - } - - - /** - * Kill transport job (on pause or cancel) - * - * @return string - * Transport type - */ - function killJob() - { - if (!$this->recalled) { - return PEAR::raiseError("TransportRecord::getTransportType:". - " not recalled ({$this->trtok})", TRERR_TOK - ); - } - $jobpid = $this->row['jobpid']; - $res = system("pkill -P $jobpid", $status); - } - - - /** - * Set state to failed and set error message in transport record - * - * @param string $txt - * base part of error message - * @param PEAR_Error $eo - * (opt.) error msg can be construct from it - * @return mixed - * boolean true or error - */ - function fail($txt='', $eo=NULL) - { - if (!$this->recalled) { - return PEAR::raiseError("TransportRecord::fail:". - " not recalled ({$this->trtok})", TRERR_TOK - ); - } - $msg = $txt; - if (!is_null($eo)) { - $msg .= $eo->getMessage()." ".$eo->getUserInfo(). - " [".$eo->getCode()."]"; - } - $r = $this->setState('failed', array('errmsg'=>$msg)); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /** - * Close transport record - * - * @return mixed - * boolean true or error - */ - function close() - { - global $CC_CONFIG, $CC_DBC; - if (!$this->recalled) { - return PEAR::raiseError("TransportRecord::close:". - " not recalled ({$this->trtok})", TRERR_TOK - ); - } - if (TR_LEAVE_CLOSED) { - $r = $this->setState('closed'); - if (PEAR::isError($r)) { - return $r; - } - } else { - $r = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['transTable']." - WHERE trtok='{$this->trtok}' - "); - if (PEAR::isError($r)) { - return $r; - } - $this->recalled = FALSE; - $this->dropped = TRUE; - } - return TRUE; - } - - - /** - * Add field specific envelopes to values (e.g. ' around strings) - * - * @param string $fldName - * field name - * @param mixed $fldVal - * field value - * @return string - */ - function _getSqlVal($fldName, $fldVal) - { - switch ($fldName) { - case 'realsize': - case 'expectedsize': - case 'uid': - return ("$fldVal"!='' ? "$fldVal" : "NULL"); - break; - case 'gunid': - case 'pdtoken': - return "x'$fldVal'::bigint"; - break; - default: - $fldVal = pg_escape_string($fldVal); - return "'$fldVal'"; - break; - } - } - - - /** - * Get title from transported object's metadata (if exists) - * - * @return string - * the title or descriptive string - */ - function getTitle() - { - $defStr = 'unknown'; - $trtype = $this->getTransportType(); //contains recall check - if (PEAR::isError($trtype)) { - return $trtype; - } - switch ($trtype) { - case "audioclip": - case "playlist": - case "playlistPkg": - case "metadata": - $title = $this->gb->bsGetTitle(NULL, $this->row['gunid']); - if (is_null($title)) { - $title = $defStr; - } - if (PEAR::isError($title)) { - if ($title->getCode() == GBERR_FOBJNEX) { - $title = $defStr; - } else { - return $title; - } - } - break; - case "searchjob": - $title = 'searchjob'; - break; - case "file": - $title = ( isset($this->row['localfile']) ? - basename($this->row['localfile']) : 'regular file'); - break; - default: - $title = $defStr; - } - return $title; - } - -} // class TransportRecord -?> \ No newline at end of file diff --git a/backend/Validator.php b/backend/Validator.php deleted file mode 100644 index d730aee10..000000000 --- a/backend/Validator.php +++ /dev/null @@ -1,385 +0,0 @@ - - *
  • audioClipFormat.php
  • - *
  • webstreamFormat.php
  • - *
  • playlistFormat.php
  • - * - * It probably should be replaced by XML schema validation in the future. - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - */ -class Validator { - /** - * Format type of validated document - * @var string - */ - private $format = NULL; - - /** - * Preloaded format tree structure - * @var array - */ - private $formTree = NULL; - - /** - * Gunid of validated file for identification in mass input - * @var string - */ - private $gunid = NULL; - - - /** - * Constructor - * - * @param string $format - * format type of validated document - * @param string $gunid - * gunid of validated file for identification in mass input - */ - public function __construct($format, $gunid) - { - $format = strtolower($format); - $this->format = $format; - $this->gunid = $gunid; - $formats = array( - 'audioclip' => "audioClipFormat", - 'playlist' => "playlistFormat", - 'webstream' => "webstreamFormat", - ); - if (!isset($formats[$format])) { - return $this->_err(VAL_FORMAT); - } - $formatName = $formats[$format]; - $formatFile = dirname(__FILE__)."/$formatName.php"; - if (!file_exists($formatFile)) { - return $this->_err(VAL_FORMAT); - } - require($formatFile); - $this->formTree = $$formatName; - } - - - /** - * Validate document - only wrapper for validateNode method - * - * @param object $data - * validated object tree - * @return mixed - * TRUE or PEAR::error - */ - function validate(&$data) - { - $r = $this->validateNode($data, $this->formTree['_root']); - return $r; - } - - - /** - * Validate one metadata value (on insert/update) - * - * @param string $fname - * parent element name - * @param string $category - * qualif.category name - * @param string $predxml - * 'A' | 'T' (attr or tag) - * @param string $value - * validated element value - * @return TRUE|PEAR_Error - */ - function validateOneValue($fname, $category, $predxml, $value) - { - $formTree =& $this->formTree; - switch ($predxml) { - case 'T': - if (!$this->isChildInFormat($fname, $category)) { - return $this->_err(VAL_UNKNOWNE, "$category in $fname"); - } - break; - case 'A': - if (!$this->isAttrInFormat($fname, $category)) { - return $this->_err(VAL_UNKNOWNA, "$category in $fname"); - } - break; - case 'N': - return TRUE; - break; - default: - return $this->_err(VAL_PREDXML, $predxml); - } - if (isset($formTree[$category]['regexp'])) { - // echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n"; - if (!preg_match("|{$formTree[$category]['regexp']}|", $value)) { - return $this->_err(VAL_CONTENT, "$category/$value"); - } - } - } - - - /** - * Validation of one element node from object tree - * - * @param object $node - * validated node - * @param string $fname - * actual name in format structure - * @return mixed - * TRUE or PEAR::error - */ - function validateNode(&$node, $fname) - { - $dname = (($node->ns? $node->ns.":" : '').$node->name); - $formTree =& $this->formTree; - if (DEBUG) { - echo"\nVAL::validateNode: 1 $dname/$fname\n"; - } - // check root node name: - if ($dname != $fname) { - return $this->_err(VAL_ROOT, $fname); - } - // check if this element is defined in format: - if (!isset($formTree[$fname])) { - return $this->_err(VAL_NOTDEF, $fname); - } - // check element content - if (isset($formTree[$fname]['regexp'])) { - // echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n"; - if (!preg_match("|{$formTree[$fname]['regexp']}|", $node->content)) { - return $this->_err(VAL_CONTENT, "$fname/{$node->content}"); - } - } - // validate attributes: - $ra = $this->validateAttributes($node, $fname); - if (PEAR::isError($ra)) { - return $ra; - } - // validate children: - $r = $this->validateChildren($node, $fname); - if (PEAR::isError($r)) { - return $r; - } - return TRUE; - } - - - /** - * Validation of attributes - * - * @param object $node - * validated node - * @param string $fname - * actual name in format structure - * @return mixed - * TRUE or PEAR::error - */ - function validateAttributes(&$node, $fname) - { - $formTree =& $this->formTree; - $attrs = array(); - // check if all attrs are permitted here: - foreach ($node->attrs as $i => $attr) { - $aname = (($attr->ns? $attr->ns.":" : '').$attr->name); - $attrs[$aname] =& $node->attrs[$i]; - if (!$this->isAttrInFormat($fname, $aname)) { - return $this->_err(VAL_UNKNOWNA, $aname); - } - // check attribute format - // echo "XXA $aname\n"; - if (isset($formTree[$aname]['regexp'])) { - // echo "XAR {$formTree[$fname]['regexp']} / ".$node->content."\n"; - if (!preg_match("|{$formTree[$aname]['regexp']}|", $attr->val)) { - return $this->_err(VAL_ATTRIB, "$aname [".var_export($attr->val,TRUE)."]"); - } - } - } - // check if all required attrs are here: - if (isset($formTree[$fname]['attrs'])) { - $fattrs =& $formTree[$fname]['attrs']; - if (isset($fattrs['required'])) { - foreach ($fattrs['required'] as $i => $attr) { - if (!isset($attrs[$attr])) { - return $this->_err(VAL_NOREQA, $attr); - } - } - } - } - return TRUE; - } - - - /** - * Validation children nodes - * - * @param object $node - * validated node - * @param string $fname - * actual name in format structure - * @return mixed - * TRUE or PEAR::error - */ - function validateChildren(&$node, $fname) - { - $formTree =& $this->formTree; - $childs = array(); - // check if all children are permitted here: - foreach ($node->children as $i => $ch) { - $chname = (($ch->ns? $ch->ns.":" : '').$ch->name); - // echo "XXE $chname\n"; - if (!$this->isChildInFormat($fname, $chname)) { - return $this->_err(VAL_UNKNOWNE, $chname); - } - // call children recursive: - $r = $this->validateNode($node->children[$i], $chname); - if (PEAR::isError($r)) { - return $r; - } - $childs[$chname] = TRUE; - } - // check if all required children are here: - if (isset($formTree[$fname]['childs'])) { - $fchilds =& $formTree[$fname]['childs']; - if (isset($fchilds['required'])) { - foreach ($fchilds['required'] as $i => $ch) { - if (!isset($childs[$ch])) return $this->_err(VAL_NOREQE, $ch); - } - } - // required one from set - if (isset($fchilds['oneof'])) { - $one = FALSE; - foreach ($fchilds['oneof'] as $i => $ch) { - if (isset($childs[$ch])) { - if ($one) { - return $this->_err(VAL_UNEXPONEOF, "$ch in $fname"); - } - $one = TRUE; - } - } - if (!$one) { - return $this->_err(VAL_NOONEOF); - } - } - } - return TRUE; - } - - - /** - * Test if child is presented in format structure - * - * @param string $fname - * node name in format structure - * @param string $chname - * child node name - * @return boolean - */ - function isChildInFormat($fname, $chname) - { - $listo = $this->isInFormatAs($fname, $chname, 'childs', 'optional'); - $listr = $this->isInFormatAs($fname, $chname, 'childs', 'required'); - $list1 = $this->isInFormatAs($fname, $chname, 'childs', 'oneof'); - return ($listo!==FALSE || $listr!==FALSE || $list1!==FALSE); - } - - - /** - * Test if attribute is presented in format structure - * - * @param string $fname - * node name in format structure - * @param string $aname - * attribute name - * @return boolean - */ - function isAttrInFormat($fname, $aname) - { - $listr = $this->isInFormatAs($fname, $aname, 'attrs', 'required'); - $listi = $this->isInFormatAs($fname, $aname, 'attrs', 'implied'); - $listn = $this->isInFormatAs($fname, $aname, 'attrs', 'normal'); - return ($listr!==FALSE || $listi!==FALSE || $listn!==FALSE); - } - - - /** - * Check if node/attribute is presented in format structure - * - * @param string $fname - * node name in format structure - * @param string $chname - * node/attribute name - * @param string $nType - * 'childs' | 'attrs' - * @param string $reqType - *
      - *
    • for elements: 'required' | 'optional' | 'oneof'
    • - *
    • for attributes: 'required' | 'implied' | 'normal'
    • - *
    - * @return mixed - * boolean/int (index int format array returned if found) - */ - function isInFormatAs($fname, $chname, $nType='childs', $reqType='required') - { - $formTree =& $this->formTree; - $listed = ( - isset($formTree[$fname][$nType][$reqType]) ? - array_search($chname, $formTree[$fname][$nType][$reqType]) : - FALSE - ); - return $listed; - } - - - /** - * Error exception generator - * - * @param int $errno - * erron code - * @param string $par - * optional string for more descriptive error messages - * @return PEAR_Error - */ - function _err($errno, $par='') - { - $msg = array( - VAL_ROOT => 'Wrong root element', - VAL_NOREQE => 'Required element missing', - VAL_NOONEOF => 'One-of element missing', - VAL_UNKNOWNE => 'Unknown element', - VAL_UNKNOWNA => 'Unknown attribute', - VAL_NOTDEF => 'Not defined', - VAL_UNEXPONEOF => 'Unexpected second object from one-of set', - VAL_FORMAT => 'Unknown format', - VAL_CONTENT => 'Invalid content', - VAL_NOREQA => 'Required attribute missing', - VAL_ATTRIB => 'Invalid attribute format', - VAL_PREDXML => 'Invalid predicate type', - ); - return PEAR::raiseError( - "Validator: {$msg[$errno]} #$errno ($par, gunid={$this->gunid})", - $errno - ); - } - - -} // class Validator - -?> \ No newline at end of file diff --git a/backend/XmlParser.php b/backend/XmlParser.php deleted file mode 100644 index 7d440460b..000000000 --- a/backend/XmlParser.php +++ /dev/null @@ -1,398 +0,0 @@ -ns = $a['namespace']; - $this->name = $a['localPart']; - $this->attrs = $attrs; - $this->nSpaces = $nSpaces; - $this->children = $children; - } -} // class XmlElement - - -/* ================================================================ Attribute */ -/** - * Object representation of one XML attribute - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @see MetaData - */ -class XmlAttrib { - /** - * Namespace prefix - * @var string - */ - public $ns; - - /** - * Attribute name - * @var string - */ - public $name; - - /** - * Attribute value - * @var string - */ - public $val; - - /** - * @param string $atns - * namespace prefix - * @param string $atnm - * attribute name - * @param string $atv - * attribute value - */ - public function __construct($atns, $atnm, $atv) - { - $this->ns = $atns; - $this->name = $atnm; - $this->val = $atv; - } -} // fn XmlAttrib - - -/* =================================================================== Parser */ -/** - * XML parser object encapsulation - * - * @package Campcaster - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @see MetaData - */ -class XmlParser { - /** - * Tree of nodes - * @var array - */ - private $tree = NULL; - - /** - * Parse stack - * @var array - */ - private $stack = array(); - - /** - * Error structure - * @var array - */ - private $err = array(FALSE, ''); - - /** - * @param string $data - * XML string to be parsed - */ - public function __construct($data){ - $xml_parser = xml_parser_create('UTF-8'); - xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, FALSE); - xml_set_object($xml_parser, $this); - xml_set_element_handler($xml_parser, "startTag", "endTag"); - xml_set_character_data_handler($xml_parser, 'characterData'); - $res = xml_parse($xml_parser, $data, TRUE); - if (!$res) { - $this->err = array(TRUE, - sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser) - ) - ); - // var_dump($data); - } - xml_parser_free($xml_parser); - } - - - /** - * Parse XML file or string - * - * @param string $data - * local path to XML file or XML string - * @param string $loc - * location: 'file'|'string' - * @return array - * reference, parse result tree (or PEAR::error) - */ - function &parse($data='', $loc='file') - { - switch ($loc) { - case "file": - if (!is_file($data)) { - return PEAR::raiseError( - "XmlParser::parse: file not found ($data)" - ); - } - if (!is_readable($data)) { - return PEAR::raiseError( - "XmlParser::parse: can't read file ($data)" - ); - } - $data = file_get_contents($data); - case "string": - $parser = new XmlParser($data); - if ($parser->isError()) { - return PEAR::raiseError( - "XmlParser::parse: ".$parser->getError() - ); - } - $tree = $parser->getTree(); - break; - default: - return PEAR::raiseError( - "XmlParser::parse: unsupported source location ($loc)" - ); - } - return $tree; - } - - - /** - * Start tag handler - * - * @param resource $parser - * reference to parser resource - * @param string $fullname - * element name - * @param array $attrs - * array of attributes - * @return none - */ - function startTag($parser, $fullname, $attrs) { - $nSpaces = array(); - foreach ($attrs as $atn => $atv) { - $a = XML_Util::splitQualifiedName($atn); - $atns = $a['namespace']; - $atnm = $a['localPart']; - unset($attrs[$atn]); - if ($atns == 'xmlns') { - $nSpaces[$atnm] = $atv; - } else if ($atns == NULL && $atnm == 'xmlns') { - $nSpaces[''] = $atv; - } else { - $attrs[$atn] = new XmlAttrib($atns, $atnm, $atv); - } - } - $el = new XmlElement($fullname, $attrs, $nSpaces); - array_push($this->stack, $el); - } - - - /** - * End tag handler - * - * @param resource $parser - * reference to parser resource - * @param string $fullname - * element name - * @return none - */ - function endTag($parser, $fullname) { - $cnt = count($this->stack); - if ($cnt > 1) { - $this->stack[$cnt-2]->children[] = $this->stack[$cnt-1]; - $lastEl = array_pop($this->stack); - } else { - $this->tree = $this->stack[0]; - } - } - - - /** - * Character data handler - * - * @param resource $parser - * reference to parser resource - * @param string $data - * @return none - */ - function characterData($parser, $data) { - $cnt = count($this->stack); - if (trim($data)!='') { - $this->stack[$cnt-1]->content .= $data; - } - } - - - /** - * Default handler - * - * @param resource $parser - * reference to parser resource - * @param string $data - * @return none - */ - function defaultHandler($parser, $data) - { - $cnt = count($this->stack); - //if(substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";"){ - // $this->stack[$cnt-1]->content .= trim($data); - //}else{ - $this->stack[$cnt-1]->content .= "*** $data ***"; - //} - } - - - /** - * Return result tree - * - * @return array - * tree structure - */ - function getTree() - { - return $this->tree; - } - - - /** - * Return error string - * - * @return boolean - * whether error occured - */ - function isError() - { - return $this->err[0]; - } - - - /** - * Return error string - * - * @return string - * error message - */ - function getError() - { - return $this->err[1]; - } - - - /* ----------------------------------- auxiliary methos for serialization */ - /** - * Serialize metadata of one file - * - * @return string, serialized XML - */ - function serialize() - { - $res = ''; - $res .= $this->serializeEl($this->tree); - $res .= "\n"; - return $res; - } - - - /** - * Serialize one metadata element - * - * @param el object, element object - * @param lvl int, level for indentation - * @return string, serialized XML - */ - function serializeEl($el, $lvl=0) - { - $ind = str_repeat(" ", $lvl); - $elNs = $el->ns; - $elName = $el->name; - $attrs = XML_Util::attributesToString($el->attrs); - $fullName = ($elNs=='' ? '' : "$elNs:")."$elName"; - $res = "\n{$ind}<{$fullName}{$attrs}>"; - $haveCh = (count($el->children)>0); - foreach ($el->children as $ch) { - $res .= $this->serializeEl($ch, $lvl+1); - } - $res .= XML_Util::replaceEntities("{$el->content}"); - if ($haveCh) { - $res .= "\n{$ind}"; - } - $res .= ""; - return $res; - } - - - /* -------------------------------------------------------- debug methods */ - /** - * Debug dump of tree - * - * @return hash, tree structure - */ - function dump() - { - var_dump($this->tree); - } - -} -?> \ No newline at end of file diff --git a/backend/audioClipFormat.php b/backend/audioClipFormat.php deleted file mode 100644 index f7fd506b7..000000000 --- a/backend/audioClipFormat.php +++ /dev/null @@ -1,328 +0,0 @@ -'audioClip', - 'audioClip'=>array( - 'childs'=>array( - 'required'=>array('metadata'), - ), - ), - 'metadata'=>array( - 'childs'=>array( - 'required'=>array( - 'dc:title', 'dcterms:extent' - ), - 'optional'=>array( - 'dc:identifier', - 'dc:creator', 'dc:source', 'ls:genre', - 'ls:year', 'dc:type', 'dc:description', 'dc:format', - 'ls:bpm', 'ls:rating', 'ls:encoded_by', 'ls:track_num', - 'ls:disc_num', 'ls:disc_num', 'dc:publisher', 'ls:composer', - 'ls:bitrate', 'ls:channels', 'ls:samplerate', 'ls:encoder', - 'ls:crc', 'ls:lyrics', 'ls:orchestra', 'ls:conductor', - 'ls:lyricist', 'ls:originallyricist', 'ls:radiostationname', - 'ls:audiofileinfourl', 'ls:artisturl', 'ls:audiosourceurl', - 'ls:radiostationurl', 'ls:buycdurl', 'ls:isrcnumber', - 'ls:catalognumber', 'ls:originalartist', 'dc:rights', - 'ls:license', 'dc:title', 'dcterms:temporal', - 'dcterms:spatial', 'dcterms:entity', 'dc:description', - 'dc:creator', 'dc:subject', 'dc:type', 'dc:format', - 'dc:contributor', 'dc:language', 'dc:rights', - 'dcterms:isPartOf', 'dc:date', - 'dc:publisher', - // extra - 'dcterms:alternative', 'ls:filename', 'ls:mtime', - // added lately by sebastian - 'ls:mood', - ), - ), - 'namespaces'=>array( - 'dc'=>"http://purl.org/dc/elements/1.1/", - 'dcterms'=>"http://purl.org/dc/terms/", - 'xbmf'=>"http://www.streamonthefly.org/xbmf", - 'xsi'=>"http://www.w3.org/2001/XMLSchema-instance", - 'xml'=>"http://www.w3.org/XML/1998/namespace", - ), - ), - 'dc:identifier'=>array( - 'type'=>'Text', - 'auto'=>TRUE, - ), - 'dc:title'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:alternative'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:extent'=>array( - 'type'=>'Time', -// 'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$', - 'regexp'=>'^((\d{1,2}:)?\d{1,2}:)?\d{1,20}(.\d{1,6})?$', - ), - 'dc:creator'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:source'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:genre'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:year'=>array( - 'type'=>'Menu', - 'area'=>'Music', - ), - 'dc:type'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:description'=>array( - 'type'=>'Longtext', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:format'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:bpm'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:rating'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:encoded_by'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:track_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:disc_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:disc_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:publisher'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:composer'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:bitrate'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:channels'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:samplerate'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:encoder'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:crc'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:lyrics'=>array( - 'type'=>'Longtext', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:orchestra'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:conductor'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:lyricist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:originallyricist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:radiostationname'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:audiofileinfourl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:artisturl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:audiosourceurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:radiostationurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:buycdurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:isrcnumber'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:catalognumber'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:originalartist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:rights'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:license'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:title'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:temporal'=>array( - 'type'=>'Time/Date', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:spatial'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:entity'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:description'=>array( - 'type'=>'Longtext', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:creator'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:subject'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:type'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:format'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:contributor'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:language'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:rights'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:isPartOf'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:date'=>array( - 'type'=>'Date', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:publisher'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - - 'ls:filename'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:mtime'=>array( - 'type'=>'Int', -// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$', - ), -); - -?> \ No newline at end of file diff --git a/backend/configure b/backend/configure deleted file mode 100755 index 30c0822dd..000000000 --- a/backend/configure +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Run this script to configure the environment. -# -# This script in effect calls the real automake / autoconf configure script -#------------------------------------------------------------------------------- - -# assume we're in $basedir -reldir=`dirname $0` -basedir=`cd $reldir; pwd;` -test -z "$basedir" && basedir=. - -bindir=$basedir/bin -tmpdir=$basedir/tmp - - -autogen=$bindir/autogen.sh -configure=$tmpdir/configure - -if [ ! -x $configure ]; then - (cd $basedir && $autogen $*) -fi - -(cd $tmpdir && $configure $*) - diff --git a/backend/cron/Cron.php b/backend/cron/Cron.php deleted file mode 100755 index fba702b62..000000000 --- a/backend/cron/Cron.php +++ /dev/null @@ -1,214 +0,0 @@ - - * $cron = new Cron(); - * $access = $cron->openCrontab('write'); - * if ($access != 'write') { - * do { - * $access = $cron->forceWriteable(); - * } while ($access != 'write'); - * } - * $cron->addCronJob('*','*','*','*','*', - * 'ClassName', - * array('first','secound','third') - * ); - * $cron->closeCrontab(); - *
    - * @package Campcaster - * @subpackage StorageServer.Cron - */ -class Cron { - /** - * @var Crontab - */ - public $ct; - - /** - * @var array This array created with getCommand() function - */ - private $params; - - /** - * @var string available values: read | write - */ - private $ctAccess = 'read'; - - private $lockfile; - private $cronfile; - private $paramdir; - private $cronUserName; - - /** - * Constructor - */ - function Cron() { - global $CC_CONFIG; - $this->lockfile = $CC_CONFIG['lockfile']; - $this->cronfile = $CC_CONFIG['cronfile']; - $this->paramdir = $CC_CONFIG['paramdir']; - $this->cronUserName = $CC_CONFIG['cronUserName']; - } - - - /* ==================================================== Cronjob functions */ - /** - * Add a cronjob to the crontab - * - * @access public - * @param string $m minute - * @param string $h hour - * @param string $dom day of month - * @param string $mo month - * @param string $dow day of week - * @param string $className name of class, which's execute() is called by croncall.php - * @param string $params the parameter(s) - * @return bool true if success else PEAR error. - */ - function addCronJob($m, $h, $dom, $mo, $dow, $className, $params) - { - if ($this->ctAccess == 'write') { - $this->ct->addCron($m, $h, $dom, $mo, $dow, - $this->getCommand($className, $params)); - return true; - } else { - return PEAR::raiseError('CronJob::addCronJob : '. - 'The crontab is not writable'); - } - } - - /** - * This function return with the active cronjobs - * - * @access public - * @return array array of cronjob struct - */ - function listCronJob() - { - return $this->ct->getByType(CRON_CMD); - } - - /** - * Remove a cronjob. - * - * @access public - * @param int $index index of the cronjobs' array. - * @return bool true if success else PEAR error. - */ - function removeCronJob($index) - { - if ($this->ctAccess == 'write') { - $this->crontab->delEntry($index); - return true; - } else { - return PEAR::raiseError('CronJob::removeCronJob : '. - 'The crontab is not writable'); - } - } - - /* ==================================================== Crontab functions */ - /** - * Open the crontab - * - * @access public - * @param string $access only for listing 'read', for add and delete 'write' - * @return string sucessed access - available values read | write - */ - function openCrontab($access = 'read') - { - $access = strtolower($access); - $this->ct = new Crontab($this->cronUserName); - if ($access == 'write' && - $this->isCrontabWritable() && - $this->lockCrontab()) { - $this->ctAccess = $access; - } else { - $this->ctAccess = 'read'; - } - return $this->ctAccess; - } - - /** - * Close the crontab - * - * @access public - * @return bool true if everything is ok, false is the lock file can't delete - */ - function closeCrontab() - { - if ($this->ctAccess == 'write') { - $this->ct->writeCrontab(); - } - return $this->ctAccess == 'write' ? $this->unlockCrontab() : true; - } - - /** - * Check the crontab is writable - * - * @access private - * @return bool - */ - function isCrontabWritable() - { - return !is_file($this->lockfile); - } - - /** - * Try to lock the crontab - * - * @access private - * @return bool true if the locking is success - */ - function lockCrontab() - { - return @touch($this->lockfile); - } - - /** - * Try to unlock the crontab - * - * @access private - * @return bool true if the unlocking is success - */ - function unlockCrontab() - { - return unlink($this->lockfile); - } - - /** - * If the crontab opened with read access. This function force set - * the access to write. - * - * @access public - * @return bool true if the setting is success - */ - function forceWriteable() - { - if ($this->isCrontabWritable() && $this->lockCrontab()) { - $this->ctAccess = 'write'; - return true; - } - return false; - } - - /* ======================================================= Misc functions */ - /** - * Get the shell command for the cronjob - * - * @param string $className name of the class what is called by croncall.php - * @param mixed $params with this parameter could be called the execute() of class - * @return string shell command - */ - function getCommand($className, $params) - { - $this->params = array ( - 'class' => $className, - 'params' => $params - ); - return $this->cronfile.' "'.str_replace('"','\"',serialize($this->params)).'"'; - } -} -?> \ No newline at end of file diff --git a/backend/cron/CronJob.php b/backend/cron/CronJob.php deleted file mode 100755 index bcd1c82d6..000000000 --- a/backend/cron/CronJob.php +++ /dev/null @@ -1,17 +0,0 @@ - \ No newline at end of file diff --git a/backend/cron/Crontab.php b/backend/cron/Crontab.php deleted file mode 100755 index 92b40ac38..000000000 --- a/backend/cron/Crontab.php +++ /dev/null @@ -1,284 +0,0 @@ - "value" - * or a line can be a comment (string beginning with #) - * or it can be a special command (beginning with an @) - * @var array - */ - private $crontabs; - - /** - * The user for whom the crontab will be manipulated - * @var string - */ - private $user; - - /** - * Lists the type of line of each line in $crontabs. - * can be: any of the CRON_* constants. - * so $linetype[5] is the type of $crontabs[5]. - * @var string - */ - private $linetypes; - - // }}} - - /** - * Constructor - * - * Initialises $this->crontabs - * - * @param string $user the user for whom the crontab will be manipulated - */ - function Crontab($user) - { - $this->user = $user; - $this->readCrontab(); - } - - /** - * This reads the crontab of $this->user and parses it in $this->crontabs - * - */ - function readCrontab() - { - // return code is 0 or 1 if crontab was empty, elsewhere stop here - $cmd = "crontab -u {$this->user} -l"; - @exec("crontab -u {$this->user} -l", $crons, $return); - if ($return > 1) { - return PEAR::raiseError("*** Can't read crontab ***\n". - " Set crontab manually!\n"); - } - - foreach ($crons as $line) - { - $line = trim($line); // discarding all prepending spaces and tabs - - // empty lines.. - if (!$line) { - $this->crontabs[] = "empty line"; - $this->linetypes[] = CRON_EMPTY; - continue; - } - - // checking if this is a comment - if ($line[0] == "#") { - $this->crontabs[] = trim($line); - $this->linetypes[] = CRON_COMMENT; - continue; - } - - // Checking if this is an assignment - if (ereg("(.*)=(.*)", $line, $assign)) { - $this->crontabs[] = array ("name" => $assign[1], "value" => $assign[2]); - $this->linetypes[] = CRON_ASSIGN; - continue; - } - - // Checking if this is a special @-entry. check man 5 crontab for more info - if ($line[0] == '@') { - $this->crontabs[] = split("[ \t]", $line, 2); - $this->linetypes[] = CRON_SPECIAL; - continue; - } - - // It's a regular crontab-entry - $ct = split("[ \t]", $line, 6); - $this->addCron($ct[0], $ct[1], $ct[2], $ct[3], $ct[4], $ct[5]); - } - } - - /** - * Writes the current crontab - */ - function writeCrontab() - { - global $DEBUG, $PATH; - - if (empty($this->linetypes)) { - return; - } - $filename = ($DEBUG ? tempnam("$PATH/crons", "cron") : tempnam("/tmp", "cron")); - $file = fopen($filename, "w"); - - foreach($this->linetypes as $i => $line) { - switch ($this->linetypes[$i]) { - case CRON_COMMENT: - $line = $this->crontabs[$i]; - break; - case CRON_ASSIGN: - $line = $this->crontabs[$i][name]." = ".$this->crontabs[$i][value]; - break; - case CRON_CMD: - $line = implode(" ", $this->crontabs[$i]); - break; - case CRON_SPECIAL: - $line = implode(" ", $this->crontabs[$i]); - break; - case CRON_EMPTY: - $line = "\n"; // an empty line in the crontab-file - break; - default: - unset($line); - echo "Something very weird is going on. This line ($i) has an unknown type.\n"; - break; - } - - // echo "line $i : $line\n"; - - if ($line) { - $r = @fwrite($file, $line."\n"); - if($r === FALSE) { - return PEAR::raiseError("*** Can't write crontab ***\n". - " Set crontab manually!\n"); - } - } - } - fclose($file); - - if ($DEBUG) { - echo "DEBUGMODE: not updating crontab. writing to $filename instead.\n"; - } else { - exec("crontab -u {$this->user} $filename", $returnar, $return); - if ($return != 0) { - echo "Error running crontab ($return). $filename not deleted\n"; - } else { - unlink($filename); - } - } - } - - - /** - * Add a item of type CRON_CMD to the end of $this->crontabs - * - * @param string $m - * minute - * @param string $h - * hour - * @param string $dom - * day of month - * @param string $mo - * month - * @param string $dow - * day of week - * @param string $cmd - * command - * - */ - function addCron($m, $h, $dom, $mo, $dow, $cmd) - { - $this->crontabs[] = array ("minute" => $m, "hour" => $h, "dayofmonth" => $dom, "month" => $mo, "dayofweek" => $dow, "command" => $cmd); - $this->linetypes[] = CRON_CMD; - } - - - /** - * Add a comment to the cron to the end of $this->crontabs - * - * @param string $comment - */ - function addComment($comment) - { - $this->crontabs[] = "# $comment\n"; - $this->linetypes[] = CRON_COMMENT; - } - - - /** - * Add a special command (check man 5 crontab for more information) - * - * @param string $sdate special date - * string meaning - * ------ ------- - * @reboot Run once, at startup. - * @yearly Run once a year, "0 0 1 1 *". - * @annually (same as @yearly) - * @monthly Run once a month, "0 0 1 * *". - * @weekly Run once a week, "0 0 * * 0". - * @daily Run once a day, "0 0 * * *". - * @midnight (same as @daily) - * @hourly Run once an hour, "0 * * * *". - * @param string $cmd command - */ - function addSpecial($sdate, $cmd) - { - $this->crontabs[] = array ("special" => $sdate, "command" => $cmd); - $this->linetypes[] = CRON_SPECIAL; - } - - - /** - * Add an assignment (name = value) - * - * @param string $name - * @param string $value - */ - function addAssign($name, $value) - { - $this->crontabs[] = array ("name" => $name, "value" => $value); - $this->linetypes[] = CRON_ASSIGN; - } - - - /** - * Delete a line from the arrays. - * - * @param int $index the index in $this->crontabs - */ - function delEntry($index) - { - unset ($this->crontabs[$index]); - unset ($this->linetypes[$index]); - } - - - /** - * Get all the lines of a certain type in an array - * - * @param string $type - */ - function getByType($type) - { - if ($type < CRON_COMMENT || $type > CRON_EMPTY) - { - trigger_error("Wrong type: $type", E_USER_WARNING); - return 0; - } - - $returnar = array (); - for ($i = 0; $i < count($this->linetypes); $i ++) - if ($this->linetypes[$i] == $type) - $returnar[] = $this->crontabs[$i]; - - return $returnar; - } -} -?> \ No newline at end of file diff --git a/backend/cron/croncall.php b/backend/cron/croncall.php deleted file mode 100755 index bae49815b..000000000 --- a/backend/cron/croncall.php +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/php -execute($p['params']); -exit(0); -?> \ No newline at end of file diff --git a/backend/cron/transportCron.php b/backend/cron/transportCron.php deleted file mode 100755 index 63845ee9d..000000000 --- a/backend/cron/transportCron.php +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/php -setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -$gb = new LocStor(); -$tr = new Transport($gb); - -$r = $tr->cronMain(); -if (!$r) { - exit(1); -} - -exit(0); -?> \ No newline at end of file diff --git a/backend/cron/transportCronJob.php b/backend/cron/transportCronJob.php deleted file mode 100755 index 795dd659a..000000000 --- a/backend/cron/transportCronJob.php +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/php -setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -$gb = new LocStor(); -$tr = new Transport($gb); - -$pid = getmypid(); -list(, $trtok) = $_SERVER['argv']; -if (TR_LOG_LEVEL > 1) { - $tr->trLog("transportCronJob($pid) start ($trtok)"); -} - -// 4-pass on job: -$cnt = 4; -for ($i = 0; $i < $cnt; $i++, sleep(1)) { - // run the action: - $r = $tr->cronCallMethod($trtok); - if (PEAR::isError($r)) { - $tr->trLogPear("transportCronJob($pid): ($trtok): ", $r); - } else { -# $tr->trLog("X transportCronJob: ".var_export($r, TRUE)); - if ($r !== TRUE) { - $tr->trLog("transportCronJob($pid): ($trtok): nonTRUE returned"); - } - } - #if(!$r) exit(1); - #sleep(2); -} - -if (TR_LOG_LEVEL>1) { - $tr->trLog("transportCronJob($pid) end ($trtok)"); -} -exit(0); -?> \ No newline at end of file diff --git a/backend/etc/Makefile.in b/backend/etc/Makefile.in deleted file mode 100644 index 96be1711a..000000000 --- a/backend/etc/Makefile.in +++ /dev/null @@ -1,259 +0,0 @@ -#------------------------------------------------------------------------------- -# StorageServer - file storage component -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# @configure_input@ -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# General command definitions -#------------------------------------------------------------------------------- -SHELL = /bin/bash -MKDIR = mkdir -p -RM = rm -f -RMDIR = rm -rf -DOXYGEN = doxygen -CP = cp -rP -SED = sed -ECHO = echo -CAT = cat -PHP = php - - -#------------------------------------------------------------------------------- -# Misc -#------------------------------------------------------------------------------- - -MODULE_NAME = storageServer -TAR_C = tar -cj --exclude .svn --exclude '*~' -C ${BASE_DIR} -f -DIST_EXT = .tgz -DATE = `date +%y%m%d` - -#------------------------------------------------------------------------------- -# Basic directory and file definitions -#------------------------------------------------------------------------------- -#BASE_DIR = @builddir@ -BASE_DIR = . -BIN_DIR = ${BASE_DIR}/bin -DOC_DIR = ${BASE_DIR}/doc -DOXYGEN_DIR = ${DOC_DIR}/doxygen -ETC_DIR = ${BASE_DIR}/etc -INCLUDE_DIR = ${BASE_DIR}/include -LIB_DIR = ${BASE_DIR}/lib -SRC_DIR = ${BASE_DIR}/src -TMP_DIR = ${BASE_DIR}/tmp -VAR_DIR = ${BASE_DIR}/var - -prefix = @prefix@ - -USR_DIR = ${prefix} -USR_INCLUDE_DIR = ${USR_DIR}/include -USR_LIB_DIR = ${USR_DIR}/lib -USR_VAR_DIR = ${USR_DIR}/var - -DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config - -PHP_DIR = ${VAR_DIR} -INSTALL_DIR = ${PHP_DIR}/install -STOR_DIR = ${PHP_DIR}/stor -ACCESS_DIR = ${PHP_DIR}/access -TRANS_DIR = ${PHP_DIR}/trans -BUFF_DIR = ${STOR_DIR}/buffer -TEST_RUNNER = ${PHP_DIR}/xmlrpc/testRunner.sh - -DEST_DIR = ${USR_VAR_DIR}/Campcaster/storageServer -DEST_VAR_DIR = ${DEST_DIR}/var -DEST_BIN_DIR = ${DEST_DIR}/bin - -HOSTNAME = @HOSTNAME@ -APACHE_GROUP = @APACHE_GROUP@ -WWW_PORT = @WWW_PORT@ -DB_SERVER = @DB_SERVER@ -DATABASE = @DATABASE@ -DB_USER = @DB_USER@ -DB_PASSWORD = @DB_PASSWORD@ -SCHEDULER_PORT = @SCHEDULER_PORT@ -WWW_DOCROOT = @WWW_DOCROOT@ -PHP_URL_PREFIX = @URL_PREFIX@ - -SCHEDULER_URL_PREFIX = -SCHEDULER_XML_RPC_PREFIX = RC2 - -USR_LIB_DIR_S=$(shell ${ECHO} ${USR_LIB_DIR} | ${SED} -e "s/\//\\\\\\\\\//g") -PHP_URL_PREFIX_S=$(shell ${ECHO} ${PHP_URL_PREFIX} | ${SED} -e "s/\//\\\\\\\\\//g") - -REPLACE_SED_STRING="s/ls_lib_dir/${USR_LIB_DIR_S}/; \ - s/ls_dbuser/${DB_USER}/; \ - s/ls_dbpassword/${DB_PASSWORD}/; \ - s/ls_dbserver/${DB_SERVER}/; \ - s/ls_database/${DATABASE}/; \ - s/ls_apache_group/${APACHE_GROUP}/; \ - s/ls_storageUrlPath/\/${PHP_URL_PREFIX_S}\/storageServer\/var/; \ - s/ls_php_host/${HOSTNAME}/; \ - s/ls_php_port/${WWW_PORT}/; \ - s/ls_archiveUrlPath/\/${PHP_URL_PREFIX_S}\/archiveServer\/var/; \ - s/ls_scheduler_urlPrefix/${SCHEDULER_URL_PREFIX}/; \ - s/ls_scheduler_xmlRpcPrefix/${SCHEDULER_XML_RPC_PREFIX}/; \ - s/ls_scheduler_host/${HOSTNAME}/; \ - s/ls_scheduler_port/${SCHEDULER_PORT}/;" - - -#------------------------------------------------------------------------------- -# Configuration parameters -#------------------------------------------------------------------------------- -#CPPFLAGS = @CPPFLAGS@ -#CXXFLAGS = @CXXFLAGS@ @DEFS@ -I${USR_INCLUDE_DIR} -I${INCLUDE_DIR} -I${TMP_DIR}\ -# -pedantic -Wall -#LDFLAGS = @LDFLAGS@ -L${USR_LIB_DIR} -L${LIB_DIR} - - -#------------------------------------------------------------------------------- -# Dependencies -#------------------------------------------------------------------------------- -#HELLO_LIB_OBJS = ${TMP_DIR}/Hello.o -#TEST_RUNNER_OBJS = ${TMP_DIR}/HelloTest.o ${TMP_DIR}/TestRunner.o - - -#------------------------------------------------------------------------------- -# Targets -#------------------------------------------------------------------------------- -.PHONY: all dir_setup doc clean docclean depclean distclean dist install -.PHONY: db_init db_clean testonly transtest storage reset -.PHONY: copy_files create_database init_database - -all: - -doc: - ${DOXYGEN} ${DOXYGEN_CONFIG} - -clean: db_clean - ${RMDIR} ${STOR_DIR} - ${RMDIR} ${ACCESS_DIR} - ${RMDIR} ${TRANS_DIR} - -docclean: - ${RMDIR} ${DOXYGEN_DIR}/html - -depclean: clean - -dist: - ${TAR_C} ${MODULE_NAME}${DATE}${DIST_EXT} * - -distclean: clean docclean - -testonly: ${TEST_RUNNER} - ${TEST_RUNNER} - -check: all testonly - -install: copy_files create_database init_database - -copy_files: - ${MKDIR} ${DEST_DIR} - ${MKDIR} ${DEST_VAR_DIR} - ${MKDIR} ${DEST_BIN_DIR} - ${MKDIR} ${DEST_VAR_DIR}/access - ${MKDIR} ${DEST_VAR_DIR}/cron - ${MKDIR} ${DEST_VAR_DIR}/install - ${MKDIR} ${DEST_VAR_DIR}/install/upgrade - ${MKDIR} ${DEST_VAR_DIR}/stor - ${MKDIR} ${DEST_VAR_DIR}/stor/buffer - ${MKDIR} ${DEST_VAR_DIR}/trans - ${MKDIR} ${DEST_VAR_DIR}/xmlrpc - ${CP} ${VAR_DIR}/*.{php,xml} ${DEST_VAR_DIR} - ${CP} ${VAR_DIR}/cron/*.php ${DEST_VAR_DIR}/cron - ${CP} ${VAR_DIR}/install/*.php \ - ${DEST_VAR_DIR}/install - ${CP} ${VAR_DIR}/install/upgrade/*.php \ - ${DEST_VAR_DIR}/install/upgrade - ${CP} ${VAR_DIR}/xmlrpc/*.php \ - ${DEST_VAR_DIR}/xmlrpc - ${CAT} ${VAR_DIR}/conf.php.template | ${SED} -e ${REPLACE_SED_STRING} \ - > ${DEST_VAR_DIR}/conf.php - ${CP} ${BIN_DIR}/backup.sh ${BIN_DIR}/restore.php \ - ${DEST_BIN_DIR} - - chgrp ${APACHE_GROUP} ${DEST_VAR_DIR}/access - chgrp ${APACHE_GROUP} ${DEST_VAR_DIR}/stor - chgrp ${APACHE_GROUP} ${DEST_VAR_DIR}/stor/buffer - chgrp ${APACHE_GROUP} ${DEST_VAR_DIR}/trans - chmod g+sw ${DEST_VAR_DIR}/access - chmod g+sw ${DEST_VAR_DIR}/stor - chmod g+sw ${DEST_VAR_DIR}/stor/buffer - chmod g+sw ${DEST_VAR_DIR}/trans - - ${RM} ${WWW_DOCROOT}/${PHP_URL_PREFIX} - ln -sf ${USR_VAR_DIR}/Campcaster ${WWW_DOCROOT}/${PHP_URL_PREFIX} - -create_database: -ifeq (@CREATE_LS_DATABASE@,yes) - ${BIN_DIR}/createDatabase.sh --database=${DATABASE} \ - --dbserver=${DB_SERVER} \ - --dbuser=${DB_USER} \ - --dbpassword=${DB_PASSWORD} -endif - -init_database: -ifeq (@INIT_LS_DATABASE@,yes) - -cd ${DEST_VAR_DIR}/install && ${PHP} -q install.php -endif - - -recheck: clean check - - -#------------------------------------------------------------------------------- -# Specific targets -#------------------------------------------------------------------------------- -storage: db_init dir_setup - -storagecheck: storage testonly - -dir_setup: - bin/setupDirs.sh ${STOR_DIR} ${ACCESS_DIR} ${TRANS_DIR} ${BUFF_DIR} - -db_init: - -cd var/install && php -q install.php - chgrp ${APACHE_GROUP} ${STOR_DIR} ${ACCESS_DIR} ${TRANS_DIR} ${BUFF_DIR} - chmod g+sw ${STOR_DIR} ${ACCESS_DIR} ${TRANS_DIR} ${BUFF_DIR} - -db_clean: - -cd var/install && php -q uninstall.php - -reset: - ./bin/resetStorage.sh - -transtest: - ./var/tests/transTest.sh -# cd var/tests; php -q transTest.php - -${TMP_DIR}: - ${MKDIR} ${TMP_DIR} - -${DOXYGEN_DIR}: - ${MKDIR} ${DOXYGEN_DIR} - -${TEST_RUNNER}: - -#------------------------------------------------------------------------------- -# Pattern rules -#------------------------------------------------------------------------------- -#${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx -# ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $< - diff --git a/backend/etc/configure.ac b/backend/etc/configure.ac deleted file mode 100644 index df1aad37d..000000000 --- a/backend/etc/configure.ac +++ /dev/null @@ -1,220 +0,0 @@ -dnl----------------------------------------------------------------------------- -dnl Copyright (c) 2010 Sourcefabric O.P.S. -dnl -dnl This file is part of the Campcaster project. -dnl http://campcaster.sourcefabric.org/ -dnl -dnl Campcaster is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl Campcaster is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with Campcaster; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl----------------------------------------------------------------------------- - -dnl----------------------------------------------------------------------------- -dnl NOTE: Run all configure related scripts from the tmp directory of the -dnl project. -dnl This is due to the fact that configure spreads a lot of trash around, -dnl like atom4te cache directories, config.* files, etc. into the directory -dnl it is being run from. We clearly don't want these in our base directory. -dnl----------------------------------------------------------------------------- -AC_INIT(StorageServer, 0.0, bugs@campware.org) -AC_PREREQ(2.59) -AC_COPYRIGHT([Copyright (c) 2010 Sourcefabric O.P.S. under the GNU GPL]) -AC_REVISION($Revision$) - -AC_CONFIG_SRCDIR(../var/BasicStor.php) - -dnl----------------------------------------------------------------------------- -dnl specify wether the Campcaster database and user should be created -dnl----------------------------------------------------------------------------- -AC_SUBST(CREATE_LS_DATABASE) - -AC_ARG_WITH([create-database], - AC_HELP_STRING([--with-create-database], - [specify wether the Campcaster database and database user - should be created (no)]), - [CREATE_LS_DATABASE=${withval}], - [CREATE_LS_DATABASE=no]) - -AC_MSG_RESULT([creating Campcaster database: ${CREATE_LS_DATABASE}]) - - -dnl----------------------------------------------------------------------------- -dnl specify wether the Campcaster database tables should be initialized -dnl----------------------------------------------------------------------------- -AC_SUBST(INIT_LS_DATABASE) - -AC_ARG_WITH([init-database], - AC_HELP_STRING([--with-init-database], - [specify wether the Campcaster database tables should be - initialized (no)]), - [INIT_LS_DATABASE=${withval}], - [INIT_LS_DATABASE=no]) - -AC_MSG_RESULT([initializing Campcaster database: ${INIT_LS_DATABASE}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the FQDN -dnl----------------------------------------------------------------------------- -AC_SUBST(HOSTNAME) - -AC_ARG_WITH([hostname], - AC_HELP_STRING([--with-hostname], - [use the specified hostname (guess)]), - [HOSTNAME=${withval}], [HOSTNAME=`hostname -f`]) - -AC_MSG_RESULT([using hostname: ${HOSTNAME}]) - - -dnl----------------------------------------------------------------------------- -dnl specify group in which apache is running -dnl----------------------------------------------------------------------------- -AC_SUBST(APACHE_GROUP) - -AC_ARG_WITH([apache-group], - AC_HELP_STRING([--with-apache-group], - [use apache running in the specified group (apache)]), - [APACHE_GROUP=${withval}], [APACHE_GROUP=apache]) - -AC_MSG_RESULT([using apache group: ${APACHE_GROUP}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the web server port -dnl----------------------------------------------------------------------------- -AC_SUBST(WWW_PORT) - -AC_ARG_WITH([www-port], - AC_HELP_STRING([--with-www-port], - [use the specified www port (80)]), - [WWW_PORT=${withval}], [WWW_PORT=80]) - -AC_MSG_RESULT([using www port: ${WWW_PORT}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the scheduler server port -dnl----------------------------------------------------------------------------- -AC_SUBST(SCHEDULER_PORT) - -AC_ARG_WITH([scheduler-port], - AC_HELP_STRING([--with-scheduler-port], - [use the specified scheduler port (3344)]), - [SCHEDULER_PORT=${withval}], [SCHEDULER_PORT=3344]) - -AC_MSG_RESULT([using scheduler port: ${SCHEDULER_PORT}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the database server name -dnl----------------------------------------------------------------------------- -AC_SUBST(DB_SERVER) - -AC_ARG_WITH([database-server], - AC_HELP_STRING([--with-database-server], - [use the specified database server (localhost)]), - [DB_SERVER=${withval}], [DB_SERVER=localhost]) - -AC_MSG_RESULT([using database server: ${DB_SERVER}]) - - -dnl----------------------------------------------------------------------------- -dnl get the name of the Campcaster database -dnl----------------------------------------------------------------------------- -AC_SUBST(DATABASE) - -AC_ARG_WITH([database], - AC_HELP_STRING([--with-database], - [the name of the postgresql database to use (Campcaster)]), - [DATABASE=${withval}], [DATABASE=Campcaster]) - -AC_MSG_RESULT([using database: ${DATABASE}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the database server user -dnl----------------------------------------------------------------------------- -AC_SUBST(DB_USER) - -AC_ARG_WITH([database-user], - AC_HELP_STRING([--with-database-user], - [use the specified database server user (campcaster)]), - [DB_USER=${withval}], [DB_USER=campcaster]) - -AC_MSG_RESULT([using database server user: ${DB_USER}]) - - -dnl----------------------------------------------------------------------------- -dnl specify the database server user password -dnl----------------------------------------------------------------------------- -AC_SUBST(DB_PASSWORD) - -AC_ARG_WITH([database-password], - AC_HELP_STRING([--with-database-password], - [use the specified database server user password (campcaster)]), - [DB_PASSWORD=${withval}], [DB_PASSWORD=campcaster]) - -AC_MSG_RESULT([using database server user password: ${DB_PASSWORD}]) - - -dnl----------------------------------------------------------------------------- -dnl specify web document root -dnl----------------------------------------------------------------------------- -AC_SUBST(WWW_DOCROOT) - -AC_ARG_WITH([www-docroot], - AC_HELP_STRING([--with-www-docroot], - [deploy Campcaster under the specified docroot (/var/www)]), - [WWW_DOCROOT=${withval}], [WWW_DOCROOT=/var/www]) - -AC_MSG_RESULT([using www document root: ${WWW_DOCROOT}]) - - -dnl----------------------------------------------------------------------------- -dnl specify url prefix -dnl----------------------------------------------------------------------------- -AC_SUBST(URL_PREFIX) - -AC_ARG_WITH([url-prefix], - AC_HELP_STRING([--with-url-prefix], - [use the specified url prefix (campcaster)]), - [URL_PREFIX=${withval}], [URL_PREFIX=campcaster]) - -AC_MSG_RESULT([using url prefix: ${URL_PREFIX}]) - - -dnl display status info on what libraries will get compiled - -AC_MSG_NOTICE( -[using the following configuration settings: - - hostname: ${HOSTNAME} - www port: ${WWW_PORT} - scheduler port: ${SCHEDULER_PORT} - database server: ${DB_SERVER} - database name: ${DATABASE} - database user: ${DB_USER} - database user password: ${DB_PASSWORD} - creating Campcaster database: ${CREATE_LS_DATABASE} - initialize Campcaster database: ${INIT_LS_DATABASE} - www document root: ${WWW_DOCROOT} - url prefix: ${URL_PREFIX} - -]) - - - -AC_CONFIG_FILES(../Makefile:../etc/Makefile.in) - -AC_OUTPUT() diff --git a/backend/genres.xml b/backend/genres.xml deleted file mode 100644 index 9afb92275..000000000 --- a/backend/genres.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/backend/index.php b/backend/index.php deleted file mode 100644 index cc0d4bdf3..000000000 --- a/backend/index.php +++ /dev/null @@ -1,17 +0,0 @@ - - -StorageServer module - -

    StorageServer module

    -
    -HTML client
    -XmlRpc test
    -Test
    - - \ No newline at end of file diff --git a/backend/playlistFormat.php b/backend/playlistFormat.php deleted file mode 100644 index 457feb938..000000000 --- a/backend/playlistFormat.php +++ /dev/null @@ -1,117 +0,0 @@ -'playlist', - 'playlist'=>array( - 'childs'=>array( - // 'repeatable'=>array('playlistElement'), - 'optional'=>array('metadata', 'playlistElement'), - ), - 'attrs'=>array( - 'required'=>array('id'), - 'implied'=>array('title', 'playlength'), - ), - ), - 'playlistElement'=>array( - 'childs'=>array( - 'oneof'=>array('audioClip', 'playlist'), - 'optional'=>array('fadeInfo'), - ), - 'attrs'=>array( - 'required'=>array('id', 'relativeOffset', 'clipStart', 'clipEnd', 'clipLength'), - ), - ), - 'audioClip'=>array( - 'childs'=>array( - 'optional'=>array('metadata'), - ), - 'attrs'=>array( - 'implied'=>array('id', 'title', 'playlength', 'uri'), - ), - ), - 'fadeInfo'=>array( - 'attrs'=>array( - 'required'=>array('id', 'fadeIn', 'fadeOut'), - ), - ), - 'metadata'=>array( - 'childs'=>array( - 'optional'=>array( - 'dc:title', 'dcterms:extent', 'dc:creator', 'dc:description', - 'dcterms:alternative', 'ls:filename', 'ls:mtime', - ), - ), - 'namespaces'=>array( - 'dc'=>"http://purl.org/dc/elements/1.1/", - 'dcterms'=>"http://purl.org/dc/terms/", - 'xbmf'=>"http://www.streamonthefly.org/xbmf", - 'xsi'=>"http://www.w3.org/2001/XMLSchema-instance", - 'xml'=>"http://www.w3.org/XML/1998/namespace", - ), - ), - 'dc:title'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:alternative'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:extent'=>array( - 'type'=>'Time', - 'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$', - ), - 'dc:creator'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:description'=>array( - 'type'=>'Longtext', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'playlength'=>array( - 'type'=>'Time', - 'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$', - ), - 'id'=>array( - 'type'=>'Attribute', - 'regexp'=>'^[0-9a-f]{16}$', - ), - 'fadeIn'=>array( - 'type'=>'Attribute', - 'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$', - ), - 'fadeOut'=>array( - 'type'=>'Attribute', - 'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$', - ), - 'ls:filename'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:mtime'=>array( - 'type'=>'Int', -// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$', - ), -/* - ''=>array( - 'childs'=>array(''), - 'attrs'=>array('implied'=>array()), - ), -*/ -); - -/* -? -ls:filename Text auto -*/ -?> \ No newline at end of file diff --git a/backend/propel-db/build.properties b/backend/propel-db/build.properties deleted file mode 100644 index 81c06da7d..000000000 --- a/backend/propel-db/build.properties +++ /dev/null @@ -1,7 +0,0 @@ -#Database driver -propel.database = pgsql -propel.database.url = pgsql:host=localhost dbname=campcaster user=campcaster password=campcaster - -#Project name -propel.project = campcaster - diff --git a/backend/propel-db/build/classes/campcaster/CcAccess.php b/backend/propel-db/build/classes/campcaster/CcAccess.php deleted file mode 100644 index e3171bdfa..000000000 --- a/backend/propel-db/build/classes/campcaster/CcAccess.php +++ /dev/null @@ -1,18 +0,0 @@ -length; - } - - public function setDbLength($time) - { - $this->length = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::LENGTH; - return Common::setTimeInSub($this, 'LENGTH', $time); - } - - -} // CcFiles diff --git a/backend/propel-db/build/classes/campcaster/CcFilesPeer.php b/backend/propel-db/build/classes/campcaster/CcFilesPeer.php deleted file mode 100644 index 047a8d8bb..000000000 --- a/backend/propel-db/build/classes/campcaster/CcFilesPeer.php +++ /dev/null @@ -1,18 +0,0 @@ -prepare($sql); - $stmt->bindValue(':p1', $this->getDbId()); - $stmt->execute(); - return $stmt->fetchColumn(); - } - - public function computeLength() - { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME); - - $sql = 'SELECT SUM('.CcPlaylistcontentsPeer::CLIPLENGTH.') AS length' - . ' FROM ' .CcPlaylistcontentsPeer::TABLE_NAME - . ' WHERE ' .CcPlaylistcontentsPeer::PLAYLIST_ID. ' = :p1'; - - $stmt = $con->prepare($sql); - $stmt->bindValue(':p1', $this->getDbId()); - $stmt->execute(); - return $stmt->fetchColumn(); - } - - -} // CcPlaylist diff --git a/backend/propel-db/build/classes/campcaster/CcPlaylistPeer.php b/backend/propel-db/build/classes/campcaster/CcPlaylistPeer.php deleted file mode 100644 index 097895b10..000000000 --- a/backend/propel-db/build/classes/campcaster/CcPlaylistPeer.php +++ /dev/null @@ -1,18 +0,0 @@ -fadein; - } - - public function setDbFadein($time) - { - $this->fadein = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEIN; - return Common::setTimeInSub($this, 'FADEIN', $time); - } - - public function getDbFadeout() - { - return $this->fadeout; - } - - public function setDbFadeout($time) - { - $this->fadeout = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEOUT; - return Common::setTimeInSub($this, 'FADEOUT', $time); - } - - public function getDbCuein() - { - return $this->cuein; - } - - public function setDbCuein($time) - { - $this->cuein = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEIN; - return Common::setTimeInSub($this, 'CUEIN', $time); - } - - public function getDbCueout() - { - return $this->cueout; - } - - public function setDbCueout($time) - { - $this->cueout = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEOUT; - return Common::setTimeInSub($this, 'CUEOUT', $time); - } - - public function getDbCliplength() - { - return $this->cliplength; - } - - public function setDbCliplength($time) - { - $this->cliplength = $time; - //$this->modifiedColumns[] = CcPlaylistcontentsPeer::CLIPLENGTH; - return Common::setTimeInSub($this, 'CLIPLENGTH', $time); - } - -} // CcPlaylistcontents diff --git a/backend/propel-db/build/classes/campcaster/CcPlaylistcontentsPeer.php b/backend/propel-db/build/classes/campcaster/CcPlaylistcontentsPeer.php deleted file mode 100644 index 5fe6cf288..000000000 --- a/backend/propel-db/build/classes/campcaster/CcPlaylistcontentsPeer.php +++ /dev/null @@ -1,18 +0,0 @@ -prepare($sql); - $stmt->bindValue(':f1', $time); - $stmt->bindValue(':p1', $row->getDbId()); - $stmt->execute(); - } -} diff --git a/backend/propel-db/build/classes/campcaster/map/CcAccessTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcAccessTableMap.php deleted file mode 100644 index 5da2dae21..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcAccessTableMap.php +++ /dev/null @@ -1,61 +0,0 @@ -setName('cc_access'); - $this->setPhpName('CcAccess'); - $this->setClassname('CcAccess'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_access_id_seq'); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('GUNID', 'Gunid', 'CHAR', false, 32, null); - $this->addColumn('TOKEN', 'Token', 'BIGINT', false, null, null); - $this->addColumn('CHSUM', 'Chsum', 'CHAR', true, 32, ''); - $this->addColumn('EXT', 'Ext', 'VARCHAR', true, 128, ''); - $this->addColumn('TYPE', 'Type', 'VARCHAR', true, 20, ''); - $this->addColumn('PARENT', 'Parent', 'BIGINT', false, null, null); - $this->addForeignKey('OWNER', 'Owner', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('TS', 'Ts', 'TIMESTAMP', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('owner' => 'id', ), null, null); - } // buildRelations() - -} // CcAccessTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcBackupTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcBackupTableMap.php deleted file mode 100644 index a2c3f3af7..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcBackupTableMap.php +++ /dev/null @@ -1,55 +0,0 @@ -setName('cc_backup'); - $this->setPhpName('CcBackup'); - $this->setClassname('CcBackup'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('TOKEN', 'Token', 'VARCHAR', true, 64, null); - $this->addColumn('SESSIONID', 'Sessionid', 'VARCHAR', true, 64, null); - $this->addColumn('STATUS', 'Status', 'VARCHAR', true, 32, null); - $this->addColumn('FROMTIME', 'Fromtime', 'TIMESTAMP', true, null, null); - $this->addColumn('TOTIME', 'Totime', 'TIMESTAMP', true, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - } // buildRelations() - -} // CcBackupTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcFilesTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcFilesTableMap.php deleted file mode 100644 index 5c8fe05f1..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcFilesTableMap.php +++ /dev/null @@ -1,107 +0,0 @@ -setName('cc_files'); - $this->setPhpName('CcFiles'); - $this->setClassname('CcFiles'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_files_id_seq'); - // columns - $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); - $this->addColumn('GUNID', 'Gunid', 'CHAR', true, 32, null); - $this->addColumn('NAME', 'Name', 'VARCHAR', true, 255, ''); - $this->addColumn('MIME', 'Mime', 'VARCHAR', true, 255, ''); - $this->addColumn('FTYPE', 'Ftype', 'VARCHAR', true, 128, ''); - $this->addColumn('FILEPATH', 'filepath', 'LONGVARCHAR', false, null, ''); - $this->addColumn('STATE', 'State', 'VARCHAR', true, 128, 'empty'); - $this->addColumn('CURRENTLYACCESSING', 'Currentlyaccessing', 'INTEGER', true, null, 0); - $this->addForeignKey('EDITEDBY', 'Editedby', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('MTIME', 'Mtime', 'TIMESTAMP', false, 6, null); - $this->addColumn('MD5', 'Md5', 'CHAR', false, 32, null); - $this->addColumn('TRACK_TITLE', 'TrackTitle', 'VARCHAR', false, 512, null); - $this->addColumn('ARTIST_NAME', 'ArtistName', 'VARCHAR', false, 512, null); - $this->addColumn('BIT_RATE', 'BitRate', 'VARCHAR', false, 32, null); - $this->addColumn('SAMPLE_RATE', 'SampleRate', 'VARCHAR', false, 32, null); - $this->addColumn('FORMAT', 'Format', 'VARCHAR', false, 128, null); - $this->addColumn('LENGTH', 'DbLength', 'TIME', false, null, null); - $this->addColumn('ALBUM_TITLE', 'AlbumTitle', 'VARCHAR', false, 512, null); - $this->addColumn('GENRE', 'Genre', 'VARCHAR', false, 64, null); - $this->addColumn('COMMENTS', 'Comments', 'LONGVARCHAR', false, null, null); - $this->addColumn('YEAR', 'Year', 'VARCHAR', false, 16, null); - $this->addColumn('TRACK_NUMBER', 'TrackNumber', 'INTEGER', false, null, null); - $this->addColumn('CHANNELS', 'Channels', 'INTEGER', false, null, null); - $this->addColumn('URL', 'Url', 'VARCHAR', false, 1024, null); - $this->addColumn('BPM', 'Bpm', 'VARCHAR', false, 8, null); - $this->addColumn('RATING', 'Rating', 'VARCHAR', false, 8, null); - $this->addColumn('ENCODED_BY', 'EncodedBy', 'VARCHAR', false, 255, null); - $this->addColumn('DISC_NUMBER', 'DiscNumber', 'VARCHAR', false, 8, null); - $this->addColumn('MOOD', 'Mood', 'VARCHAR', false, 64, null); - $this->addColumn('LABEL', 'Label', 'VARCHAR', false, 512, null); - $this->addColumn('COMPOSER', 'Composer', 'VARCHAR', false, 512, null); - $this->addColumn('ENCODER', 'Encoder', 'VARCHAR', false, 64, null); - $this->addColumn('CHECKSUM', 'Checksum', 'VARCHAR', false, 256, null); - $this->addColumn('LYRICS', 'Lyrics', 'LONGVARCHAR', false, null, null); - $this->addColumn('ORCHESTRA', 'Orchestra', 'VARCHAR', false, 512, null); - $this->addColumn('CONDUCTOR', 'Conductor', 'VARCHAR', false, 512, null); - $this->addColumn('LYRICIST', 'Lyricist', 'VARCHAR', false, 512, null); - $this->addColumn('ORIGINAL_LYRICIST', 'OriginalLyricist', 'VARCHAR', false, 512, null); - $this->addColumn('RADIO_STATION_NAME', 'RadioStationName', 'VARCHAR', false, 512, null); - $this->addColumn('INFO_URL', 'InfoUrl', 'VARCHAR', false, 512, null); - $this->addColumn('ARTIST_URL', 'ArtistUrl', 'VARCHAR', false, 512, null); - $this->addColumn('AUDIO_SOURCE_URL', 'AudioSourceUrl', 'VARCHAR', false, 512, null); - $this->addColumn('RADIO_STATION_URL', 'RadioStationUrl', 'VARCHAR', false, 512, null); - $this->addColumn('BUY_THIS_URL', 'BuyThisUrl', 'VARCHAR', false, 512, null); - $this->addColumn('ISRC_NUMBER', 'IsrcNumber', 'VARCHAR', false, 512, null); - $this->addColumn('CATALOG_NUMBER', 'CatalogNumber', 'VARCHAR', false, 512, null); - $this->addColumn('ORIGINAL_ARTIST', 'OriginalArtist', 'VARCHAR', false, 512, null); - $this->addColumn('COPYRIGHT', 'Copyright', 'VARCHAR', false, 512, null); - $this->addColumn('REPORT_DATETIME', 'ReportDatetime', 'VARCHAR', false, 32, null); - $this->addColumn('REPORT_LOCATION', 'ReportLocation', 'VARCHAR', false, 512, null); - $this->addColumn('REPORT_ORGANIZATION', 'ReportOrganization', 'VARCHAR', false, 512, null); - $this->addColumn('SUBJECT', 'Subject', 'VARCHAR', false, 512, null); - $this->addColumn('CONTRIBUTOR', 'Contributor', 'VARCHAR', false, 512, null); - $this->addColumn('LANGUAGE', 'Language', 'VARCHAR', false, 512, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('editedby' => 'id', ), null, null); - $this->addRelation('CcPlaylistcontents', 'CcPlaylistcontents', RelationMap::ONE_TO_MANY, array('id' => 'file_id', ), 'CASCADE', null); - } // buildRelations() - -} // CcFilesTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcPermsTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcPermsTableMap.php deleted file mode 100644 index 7a869b2c3..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcPermsTableMap.php +++ /dev/null @@ -1,56 +0,0 @@ -setName('cc_perms'); - $this->setPhpName('CcPerms'); - $this->setClassname('CcPerms'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('PERMID', 'Permid', 'INTEGER', true, null, null); - $this->addForeignKey('SUBJ', 'Subj', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('ACTION', 'Action', 'VARCHAR', false, 20, null); - $this->addColumn('OBJ', 'Obj', 'INTEGER', false, null, null); - $this->addColumn('TYPE', 'Type', 'CHAR', false, 1, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('subj' => 'id', ), 'CASCADE', null); - } // buildRelations() - -} // CcPermsTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcPlaylistTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcPlaylistTableMap.php deleted file mode 100644 index cfb6f23de..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcPlaylistTableMap.php +++ /dev/null @@ -1,61 +0,0 @@ -setName('cc_playlist'); - $this->setPhpName('CcPlaylist'); - $this->setClassname('CcPlaylist'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_playlist_id_seq'); - // columns - $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); - $this->addColumn('NAME', 'DbName', 'VARCHAR', true, 255, ''); - $this->addColumn('STATE', 'DbState', 'VARCHAR', true, 128, 'empty'); - $this->addColumn('CURRENTLYACCESSING', 'DbCurrentlyaccessing', 'INTEGER', true, null, 0); - $this->addForeignKey('EDITEDBY', 'DbEditedby', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('MTIME', 'DbMtime', 'TIMESTAMP', false, 6, null); - $this->addColumn('CREATOR', 'DbCreator', 'VARCHAR', false, 32, null); - $this->addColumn('DESCRIPTION', 'DbDescription', 'VARCHAR', false, 512, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('editedby' => 'id', ), null, null); - $this->addRelation('CcPlaylistcontents', 'CcPlaylistcontents', RelationMap::ONE_TO_MANY, array('id' => 'playlist_id', ), 'CASCADE', null); - } // buildRelations() - -} // CcPlaylistTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcPlaylistcontentsTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcPlaylistcontentsTableMap.php deleted file mode 100644 index 4ce59117e..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcPlaylistcontentsTableMap.php +++ /dev/null @@ -1,62 +0,0 @@ -setName('cc_playlistcontents'); - $this->setPhpName('CcPlaylistcontents'); - $this->setClassname('CcPlaylistcontents'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_playlistcontents_id_seq'); - // columns - $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); - $this->addForeignKey('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', 'cc_playlist', 'ID', false, null, null); - $this->addForeignKey('FILE_ID', 'DbFileId', 'INTEGER', 'cc_files', 'ID', false, null, null); - $this->addColumn('POSITION', 'DbPosition', 'INTEGER', false, null, null); - $this->addColumn('CLIPLENGTH', 'DbCliplength', 'TIME', false, null, '00:00:00'); - $this->addColumn('CUEIN', 'DbCuein', 'TIME', false, null, '00:00:00'); - $this->addColumn('CUEOUT', 'DbCueout', 'TIME', false, null, '00:00:00'); - $this->addColumn('FADEIN', 'DbFadein', 'TIME', false, null, '00:00:00'); - $this->addColumn('FADEOUT', 'DbFadeout', 'TIME', false, null, '00:00:00'); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcFiles', 'CcFiles', RelationMap::MANY_TO_ONE, array('file_id' => 'id', ), 'CASCADE', null); - $this->addRelation('CcPlaylist', 'CcPlaylist', RelationMap::MANY_TO_ONE, array('playlist_id' => 'id', ), 'CASCADE', null); - } // buildRelations() - -} // CcPlaylistcontentsTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcPrefTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcPrefTableMap.php deleted file mode 100644 index 7bc77534e..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcPrefTableMap.php +++ /dev/null @@ -1,56 +0,0 @@ -setName('cc_pref'); - $this->setPhpName('CcPref'); - $this->setClassname('CcPref'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_pref_id_seq'); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addForeignKey('SUBJID', 'Subjid', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('KEYSTR', 'Keystr', 'VARCHAR', false, 255, null); - $this->addColumn('VALSTR', 'Valstr', 'LONGVARCHAR', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('subjid' => 'id', ), 'CASCADE', null); - } // buildRelations() - -} // CcPrefTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcScheduleTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcScheduleTableMap.php deleted file mode 100644 index 757998697..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcScheduleTableMap.php +++ /dev/null @@ -1,61 +0,0 @@ -setName('cc_schedule'); - $this->setPhpName('CcSchedule'); - $this->setClassname('CcSchedule'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('ID', 'Id', 'BIGINT', true, null, null); - $this->addColumn('PLAYLIST_ID', 'PlaylistId', 'INTEGER', true, null, null); - $this->addColumn('STARTS', 'Starts', 'TIMESTAMP', true, null, null); - $this->addColumn('ENDS', 'Ends', 'TIMESTAMP', true, null, null); - $this->addColumn('GROUP_ID', 'GroupId', 'INTEGER', false, null, null); - $this->addColumn('FILE_ID', 'FileId', 'INTEGER', false, null, null); - $this->addColumn('CLIP_LENGTH', 'ClipLength', 'TIME', false, null, '00:00:00'); - $this->addColumn('FADE_IN', 'FadeIn', 'TIME', false, null, '00:00:00'); - $this->addColumn('FADE_OUT', 'FadeOut', 'TIME', false, null, '00:00:00'); - $this->addColumn('CUE_IN', 'CueIn', 'TIME', false, null, '00:00:00'); - $this->addColumn('CUE_OUT', 'CueOut', 'TIME', false, null, '00:00:00'); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - } // buildRelations() - -} // CcScheduleTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcSessTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcSessTableMap.php deleted file mode 100644 index 8e928ab1c..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcSessTableMap.php +++ /dev/null @@ -1,55 +0,0 @@ -setName('cc_sess'); - $this->setPhpName('CcSess'); - $this->setClassname('CcSess'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('SESSID', 'Sessid', 'CHAR', true, 32, null); - $this->addForeignKey('USERID', 'Userid', 'INTEGER', 'cc_subjs', 'ID', false, null, null); - $this->addColumn('LOGIN', 'Login', 'VARCHAR', false, 255, null); - $this->addColumn('TS', 'Ts', 'TIMESTAMP', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('userid' => 'id', ), 'CASCADE', null); - } // buildRelations() - -} // CcSessTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcSmembTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcSmembTableMap.php deleted file mode 100644 index 5cdb44df5..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcSmembTableMap.php +++ /dev/null @@ -1,55 +0,0 @@ -setName('cc_smemb'); - $this->setPhpName('CcSmemb'); - $this->setClassname('CcSmemb'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('UID', 'Uid', 'INTEGER', true, null, 0); - $this->addColumn('GID', 'Gid', 'INTEGER', true, null, 0); - $this->addColumn('LEVEL', 'Level', 'INTEGER', true, null, 0); - $this->addColumn('MID', 'Mid', 'INTEGER', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - } // buildRelations() - -} // CcSmembTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcSubjsTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcSubjsTableMap.php deleted file mode 100644 index a32bb2710..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcSubjsTableMap.php +++ /dev/null @@ -1,63 +0,0 @@ -setName('cc_subjs'); - $this->setPhpName('CcSubjs'); - $this->setClassname('CcSubjs'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('LOGIN', 'Login', 'VARCHAR', true, 255, ''); - $this->addColumn('PASS', 'Pass', 'VARCHAR', true, 255, ''); - $this->addColumn('TYPE', 'Type', 'CHAR', true, 1, 'U'); - $this->addColumn('REALNAME', 'Realname', 'VARCHAR', true, 255, ''); - $this->addColumn('LASTLOGIN', 'Lastlogin', 'TIMESTAMP', false, null, null); - $this->addColumn('LASTFAIL', 'Lastfail', 'TIMESTAMP', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('CcAccess', 'CcAccess', RelationMap::ONE_TO_MANY, array('id' => 'owner', ), null, null); - $this->addRelation('CcFiles', 'CcFiles', RelationMap::ONE_TO_MANY, array('id' => 'editedby', ), null, null); - $this->addRelation('CcPerms', 'CcPerms', RelationMap::ONE_TO_MANY, array('id' => 'subj', ), 'CASCADE', null); - $this->addRelation('CcPlaylist', 'CcPlaylist', RelationMap::ONE_TO_MANY, array('id' => 'editedby', ), null, null); - $this->addRelation('CcPref', 'CcPref', RelationMap::ONE_TO_MANY, array('id' => 'subjid', ), 'CASCADE', null); - $this->addRelation('CcSess', 'CcSess', RelationMap::ONE_TO_MANY, array('id' => 'userid', ), 'CASCADE', null); - } // buildRelations() - -} // CcSubjsTableMap diff --git a/backend/propel-db/build/classes/campcaster/map/CcTransTableMap.php b/backend/propel-db/build/classes/campcaster/map/CcTransTableMap.php deleted file mode 100644 index 9ccb711db..000000000 --- a/backend/propel-db/build/classes/campcaster/map/CcTransTableMap.php +++ /dev/null @@ -1,75 +0,0 @@ -setName('cc_trans'); - $this->setPhpName('CcTrans'); - $this->setClassname('CcTrans'); - $this->setPackage('campcaster'); - $this->setUseIdGenerator(true); - $this->setPrimaryKeyMethodInfo('cc_trans_id_seq'); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('TRTOK', 'Trtok', 'CHAR', true, 16, null); - $this->addColumn('DIRECTION', 'Direction', 'VARCHAR', true, 128, null); - $this->addColumn('STATE', 'State', 'VARCHAR', true, 128, null); - $this->addColumn('TRTYPE', 'Trtype', 'VARCHAR', true, 128, null); - $this->addColumn('LOCK', 'Lock', 'CHAR', true, 1, 'N'); - $this->addColumn('TARGET', 'Target', 'VARCHAR', false, 255, null); - $this->addColumn('RTRTOK', 'Rtrtok', 'CHAR', false, 16, null); - $this->addColumn('MDTRTOK', 'Mdtrtok', 'CHAR', false, 16, null); - $this->addColumn('GUNID', 'Gunid', 'CHAR', false, 32, null); - $this->addColumn('PDTOKEN', 'Pdtoken', 'BIGINT', false, null, null); - $this->addColumn('URL', 'Url', 'VARCHAR', false, 255, null); - $this->addColumn('LOCALFILE', 'Localfile', 'VARCHAR', false, 255, null); - $this->addColumn('FNAME', 'Fname', 'VARCHAR', false, 255, null); - $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('EXPECTEDSUM', 'Expectedsum', 'CHAR', false, 32, null); - $this->addColumn('REALSUM', 'Realsum', 'CHAR', false, 32, null); - $this->addColumn('EXPECTEDSIZE', 'Expectedsize', 'INTEGER', false, null, null); - $this->addColumn('REALSIZE', 'Realsize', 'INTEGER', false, null, null); - $this->addColumn('UID', 'Uid', 'INTEGER', false, null, null); - $this->addColumn('ERRMSG', 'Errmsg', 'VARCHAR', false, 255, null); - $this->addColumn('JOBPID', 'Jobpid', 'INTEGER', false, null, null); - $this->addColumn('START', 'Start', 'TIMESTAMP', false, null, null); - $this->addColumn('TS', 'Ts', 'TIMESTAMP', false, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - } // buildRelations() - -} // CcTransTableMap diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcAccess.php b/backend/propel-db/build/classes/campcaster/om/BaseCcAccess.php deleted file mode 100644 index 974682fed..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcAccess.php +++ /dev/null @@ -1,1236 +0,0 @@ -chsum = ''; - $this->ext = ''; - $this->type = ''; - } - - /** - * Initializes internal state of BaseCcAccess object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * Get the [gunid] column value. - * - * @return string - */ - public function getGunid() - { - return $this->gunid; - } - - /** - * Get the [token] column value. - * - * @return string - */ - public function getToken() - { - return $this->token; - } - - /** - * Get the [chsum] column value. - * - * @return string - */ - public function getChsum() - { - return $this->chsum; - } - - /** - * Get the [ext] column value. - * - * @return string - */ - public function getExt() - { - return $this->ext; - } - - /** - * Get the [type] column value. - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Get the [parent] column value. - * - * @return string - */ - public function getParent() - { - return $this->parent; - } - - /** - * Get the [owner] column value. - * - * @return int - */ - public function getOwner() - { - return $this->owner; - } - - /** - * Get the [optionally formatted] temporal [ts] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getTs($format = 'Y-m-d H:i:s') - { - if ($this->ts === null) { - return null; - } - - - - try { - $dt = new DateTime($this->ts); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ts, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcAccessPeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [gunid] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setGunid($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->gunid !== $v) { - $this->gunid = $v; - $this->modifiedColumns[] = CcAccessPeer::GUNID; - } - - return $this; - } // setGunid() - - /** - * Set the value of [token] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setToken($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->token !== $v) { - $this->token = $v; - $this->modifiedColumns[] = CcAccessPeer::TOKEN; - } - - return $this; - } // setToken() - - /** - * Set the value of [chsum] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setChsum($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->chsum !== $v || $this->isNew()) { - $this->chsum = $v; - $this->modifiedColumns[] = CcAccessPeer::CHSUM; - } - - return $this; - } // setChsum() - - /** - * Set the value of [ext] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setExt($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->ext !== $v || $this->isNew()) { - $this->ext = $v; - $this->modifiedColumns[] = CcAccessPeer::EXT; - } - - return $this; - } // setExt() - - /** - * Set the value of [type] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setType($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->type !== $v || $this->isNew()) { - $this->type = $v; - $this->modifiedColumns[] = CcAccessPeer::TYPE; - } - - return $this; - } // setType() - - /** - * Set the value of [parent] column. - * - * @param string $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setParent($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->parent !== $v) { - $this->parent = $v; - $this->modifiedColumns[] = CcAccessPeer::PARENT; - } - - return $this; - } // setParent() - - /** - * Set the value of [owner] column. - * - * @param int $v new value - * @return CcAccess The current object (for fluent API support) - */ - public function setOwner($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->owner !== $v) { - $this->owner = $v; - $this->modifiedColumns[] = CcAccessPeer::OWNER; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setOwner() - - /** - * Sets the value of [ts] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcAccess The current object (for fluent API support) - */ - public function setTs($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->ts !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->ts !== null && $tmpDt = new DateTime($this->ts)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->ts = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcAccessPeer::TS; - } - } // if either are not null - - return $this; - } // setTs() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->chsum !== '') { - return false; - } - - if ($this->ext !== '') { - return false; - } - - if ($this->type !== '') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->gunid = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->token = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->chsum = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->ext = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->type = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->parent = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->owner = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null; - $this->ts = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 9; // 9 = CcAccessPeer::NUM_COLUMNS - CcAccessPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcAccess object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->owner !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcAccessPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcAccessQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcAccessPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcAccessPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcAccessPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcAccessPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows += CcAccessPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcAccessPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcAccessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getGunid(); - break; - case 2: - return $this->getToken(); - break; - case 3: - return $this->getChsum(); - break; - case 4: - return $this->getExt(); - break; - case 5: - return $this->getType(); - break; - case 6: - return $this->getParent(); - break; - case 7: - return $this->getOwner(); - break; - case 8: - return $this->getTs(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcAccessPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getGunid(), - $keys[2] => $this->getToken(), - $keys[3] => $this->getChsum(), - $keys[4] => $this->getExt(), - $keys[5] => $this->getType(), - $keys[6] => $this->getParent(), - $keys[7] => $this->getOwner(), - $keys[8] => $this->getTs(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcAccessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setGunid($value); - break; - case 2: - $this->setToken($value); - break; - case 3: - $this->setChsum($value); - break; - case 4: - $this->setExt($value); - break; - case 5: - $this->setType($value); - break; - case 6: - $this->setParent($value); - break; - case 7: - $this->setOwner($value); - break; - case 8: - $this->setTs($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcAccessPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setGunid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setToken($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setChsum($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setExt($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setType($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setParent($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setOwner($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setTs($arr[$keys[8]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcAccessPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcAccessPeer::ID)) $criteria->add(CcAccessPeer::ID, $this->id); - if ($this->isColumnModified(CcAccessPeer::GUNID)) $criteria->add(CcAccessPeer::GUNID, $this->gunid); - if ($this->isColumnModified(CcAccessPeer::TOKEN)) $criteria->add(CcAccessPeer::TOKEN, $this->token); - if ($this->isColumnModified(CcAccessPeer::CHSUM)) $criteria->add(CcAccessPeer::CHSUM, $this->chsum); - if ($this->isColumnModified(CcAccessPeer::EXT)) $criteria->add(CcAccessPeer::EXT, $this->ext); - if ($this->isColumnModified(CcAccessPeer::TYPE)) $criteria->add(CcAccessPeer::TYPE, $this->type); - if ($this->isColumnModified(CcAccessPeer::PARENT)) $criteria->add(CcAccessPeer::PARENT, $this->parent); - if ($this->isColumnModified(CcAccessPeer::OWNER)) $criteria->add(CcAccessPeer::OWNER, $this->owner); - if ($this->isColumnModified(CcAccessPeer::TS)) $criteria->add(CcAccessPeer::TS, $this->ts); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcAccessPeer::DATABASE_NAME); - $criteria->add(CcAccessPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcAccess (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setGunid($this->gunid); - $copyObj->setToken($this->token); - $copyObj->setChsum($this->chsum); - $copyObj->setExt($this->ext); - $copyObj->setType($this->type); - $copyObj->setParent($this->parent); - $copyObj->setOwner($this->owner); - $copyObj->setTs($this->ts); - - $copyObj->setNew(true); - $copyObj->setId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcAccess Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcAccessPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcAccessPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcAccess The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setOwner(NULL); - } else { - $this->setOwner($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcAccess($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->owner !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->owner, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcAccesss($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->gunid = null; - $this->token = null; - $this->chsum = null; - $this->ext = null; - $this->type = null; - $this->parent = null; - $this->owner = null; - $this->ts = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcAccess diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcAccessPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcAccessPeer.php deleted file mode 100644 index f6614d330..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcAccessPeer.php +++ /dev/null @@ -1,1008 +0,0 @@ - array ('Id', 'Gunid', 'Token', 'Chsum', 'Ext', 'Type', 'Parent', 'Owner', 'Ts', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'gunid', 'token', 'chsum', 'ext', 'type', 'parent', 'owner', 'ts', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::GUNID, self::TOKEN, self::CHSUM, self::EXT, self::TYPE, self::PARENT, self::OWNER, self::TS, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'GUNID', 'TOKEN', 'CHSUM', 'EXT', 'TYPE', 'PARENT', 'OWNER', 'TS', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'gunid', 'token', 'chsum', 'ext', 'type', 'parent', 'owner', 'ts', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Gunid' => 1, 'Token' => 2, 'Chsum' => 3, 'Ext' => 4, 'Type' => 5, 'Parent' => 6, 'Owner' => 7, 'Ts' => 8, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'gunid' => 1, 'token' => 2, 'chsum' => 3, 'ext' => 4, 'type' => 5, 'parent' => 6, 'owner' => 7, 'ts' => 8, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::GUNID => 1, self::TOKEN => 2, self::CHSUM => 3, self::EXT => 4, self::TYPE => 5, self::PARENT => 6, self::OWNER => 7, self::TS => 8, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'GUNID' => 1, 'TOKEN' => 2, 'CHSUM' => 3, 'EXT' => 4, 'TYPE' => 5, 'PARENT' => 6, 'OWNER' => 7, 'TS' => 8, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'gunid' => 1, 'token' => 2, 'chsum' => 3, 'ext' => 4, 'type' => 5, 'parent' => 6, 'owner' => 7, 'ts' => 8, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcAccessPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcAccessPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcAccessPeer::ID); - $criteria->addSelectColumn(CcAccessPeer::GUNID); - $criteria->addSelectColumn(CcAccessPeer::TOKEN); - $criteria->addSelectColumn(CcAccessPeer::CHSUM); - $criteria->addSelectColumn(CcAccessPeer::EXT); - $criteria->addSelectColumn(CcAccessPeer::TYPE); - $criteria->addSelectColumn(CcAccessPeer::PARENT); - $criteria->addSelectColumn(CcAccessPeer::OWNER); - $criteria->addSelectColumn(CcAccessPeer::TS); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.GUNID'); - $criteria->addSelectColumn($alias . '.TOKEN'); - $criteria->addSelectColumn($alias . '.CHSUM'); - $criteria->addSelectColumn($alias . '.EXT'); - $criteria->addSelectColumn($alias . '.TYPE'); - $criteria->addSelectColumn($alias . '.PARENT'); - $criteria->addSelectColumn($alias . '.OWNER'); - $criteria->addSelectColumn($alias . '.TS'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcAccessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcAccessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcAccess - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcAccessPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcAccessPeer::populateObjects(CcAccessPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcAccessPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcAccess $value A CcAccess object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcAccess $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcAccess object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcAccess) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcAccess object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcAccess Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_access - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcAccessPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcAccessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcAccessPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcAccessPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcAccess object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcAccessPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcAccessPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcAccessPeer::NUM_COLUMNS; - } else { - $cls = CcAccessPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcAccessPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcAccessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcAccessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcAccessPeer::OWNER, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcAccess objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcAccess objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcAccessPeer::addSelectColumns($criteria); - $startcol = (CcAccessPeer::NUM_COLUMNS - CcAccessPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcAccessPeer::OWNER, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcAccessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcAccessPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcAccessPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcAccessPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcAccess) to $obj2 (CcSubjs) - $obj2->addCcAccess($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcAccessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcAccessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcAccessPeer::OWNER, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcAccess objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcAccess objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcAccessPeer::addSelectColumns($criteria); - $startcol2 = (CcAccessPeer::NUM_COLUMNS - CcAccessPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcAccessPeer::OWNER, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcAccessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcAccessPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcAccessPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcAccessPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcAccess) to the collection in $obj2 (CcSubjs) - $obj2->addCcAccess($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcAccessPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcAccessPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcAccessTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcAccessPeer::CLASS_DEFAULT : CcAccessPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcAccess or Criteria object. - * - * @param mixed $values Criteria or CcAccess object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcAccess object - } - - if ($criteria->containsKey(CcAccessPeer::ID) && $criteria->keyContainsValue(CcAccessPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcAccessPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcAccess or Criteria object. - * - * @param mixed $values Criteria or CcAccess object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcAccessPeer::ID); - $value = $criteria->remove(CcAccessPeer::ID); - if ($value) { - $selectCriteria->add(CcAccessPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcAccessPeer::TABLE_NAME); - } - - } else { // $values is CcAccess object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_access table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcAccessPeer::TABLE_NAME, $con, CcAccessPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcAccessPeer::clearInstancePool(); - CcAccessPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcAccess or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcAccess object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcAccessPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcAccess) { // it's a model object - // invalidate the cache for this single object - CcAccessPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcAccessPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcAccessPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcAccessPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcAccess object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcAccess $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcAccess $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcAccessPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcAccessPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcAccessPeer::DATABASE_NAME, CcAccessPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcAccess - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcAccessPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcAccessPeer::DATABASE_NAME); - $criteria->add(CcAccessPeer::ID, $pk); - - $v = CcAccessPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcAccessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcAccessPeer::DATABASE_NAME); - $criteria->add(CcAccessPeer::ID, $pks, Criteria::IN); - $objs = CcAccessPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcAccessPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcAccessPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcAccessQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcAccessQuery.php deleted file mode 100644 index d1e6b14c9..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcAccessQuery.php +++ /dev/null @@ -1,477 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcAccess|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcAccessPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcAccessPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcAccessPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcAccessPeer::ID, $id, $comparison); - } - - /** - * Filter the query on the gunid column - * - * @param string $gunid The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByGunid($gunid = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($gunid)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $gunid)) { - $gunid = str_replace('*', '%', $gunid); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcAccessPeer::GUNID, $gunid, $comparison); - } - - /** - * Filter the query on the token column - * - * @param string|array $token The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByToken($token = null, $comparison = null) - { - if (is_array($token)) { - $useMinMax = false; - if (isset($token['min'])) { - $this->addUsingAlias(CcAccessPeer::TOKEN, $token['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($token['max'])) { - $this->addUsingAlias(CcAccessPeer::TOKEN, $token['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcAccessPeer::TOKEN, $token, $comparison); - } - - /** - * Filter the query on the chsum column - * - * @param string $chsum The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByChsum($chsum = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($chsum)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $chsum)) { - $chsum = str_replace('*', '%', $chsum); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcAccessPeer::CHSUM, $chsum, $comparison); - } - - /** - * Filter the query on the ext column - * - * @param string $ext The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByExt($ext = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($ext)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $ext)) { - $ext = str_replace('*', '%', $ext); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcAccessPeer::EXT, $ext, $comparison); - } - - /** - * Filter the query on the type column - * - * @param string $type The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByType($type = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($type)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $type)) { - $type = str_replace('*', '%', $type); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcAccessPeer::TYPE, $type, $comparison); - } - - /** - * Filter the query on the parent column - * - * @param string|array $parent The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByParent($parent = null, $comparison = null) - { - if (is_array($parent)) { - $useMinMax = false; - if (isset($parent['min'])) { - $this->addUsingAlias(CcAccessPeer::PARENT, $parent['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($parent['max'])) { - $this->addUsingAlias(CcAccessPeer::PARENT, $parent['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcAccessPeer::PARENT, $parent, $comparison); - } - - /** - * Filter the query on the owner column - * - * @param int|array $owner The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByOwner($owner = null, $comparison = null) - { - if (is_array($owner)) { - $useMinMax = false; - if (isset($owner['min'])) { - $this->addUsingAlias(CcAccessPeer::OWNER, $owner['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($owner['max'])) { - $this->addUsingAlias(CcAccessPeer::OWNER, $owner['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcAccessPeer::OWNER, $owner, $comparison); - } - - /** - * Filter the query on the ts column - * - * @param string|array $ts The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByTs($ts = null, $comparison = null) - { - if (is_array($ts)) { - $useMinMax = false; - if (isset($ts['min'])) { - $this->addUsingAlias(CcAccessPeer::TS, $ts['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($ts['max'])) { - $this->addUsingAlias(CcAccessPeer::TS, $ts['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcAccessPeer::TS, $ts, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcAccessPeer::OWNER, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Exclude object from result - * - * @param CcAccess $ccAccess Object to remove from the list of results - * - * @return CcAccessQuery The current query, for fluid interface - */ - public function prune($ccAccess = null) - { - if ($ccAccess) { - $this->addUsingAlias(CcAccessPeer::ID, $ccAccess->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcAccessQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcBackup.php b/backend/propel-db/build/classes/campcaster/om/BaseCcBackup.php deleted file mode 100644 index 37d8fb83b..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcBackup.php +++ /dev/null @@ -1,956 +0,0 @@ -token; - } - - /** - * Get the [sessionid] column value. - * - * @return string - */ - public function getSessionid() - { - return $this->sessionid; - } - - /** - * Get the [status] column value. - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Get the [optionally formatted] temporal [fromtime] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getFromtime($format = 'Y-m-d H:i:s') - { - if ($this->fromtime === null) { - return null; - } - - - - try { - $dt = new DateTime($this->fromtime); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->fromtime, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [totime] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getTotime($format = 'Y-m-d H:i:s') - { - if ($this->totime === null) { - return null; - } - - - - try { - $dt = new DateTime($this->totime); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->totime, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [token] column. - * - * @param string $v new value - * @return CcBackup The current object (for fluent API support) - */ - public function setToken($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->token !== $v) { - $this->token = $v; - $this->modifiedColumns[] = CcBackupPeer::TOKEN; - } - - return $this; - } // setToken() - - /** - * Set the value of [sessionid] column. - * - * @param string $v new value - * @return CcBackup The current object (for fluent API support) - */ - public function setSessionid($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->sessionid !== $v) { - $this->sessionid = $v; - $this->modifiedColumns[] = CcBackupPeer::SESSIONID; - } - - return $this; - } // setSessionid() - - /** - * Set the value of [status] column. - * - * @param string $v new value - * @return CcBackup The current object (for fluent API support) - */ - public function setStatus($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->status !== $v) { - $this->status = $v; - $this->modifiedColumns[] = CcBackupPeer::STATUS; - } - - return $this; - } // setStatus() - - /** - * Sets the value of [fromtime] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcBackup The current object (for fluent API support) - */ - public function setFromtime($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->fromtime !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->fromtime !== null && $tmpDt = new DateTime($this->fromtime)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->fromtime = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcBackupPeer::FROMTIME; - } - } // if either are not null - - return $this; - } // setFromtime() - - /** - * Sets the value of [totime] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcBackup The current object (for fluent API support) - */ - public function setTotime($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->totime !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->totime !== null && $tmpDt = new DateTime($this->totime)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->totime = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcBackupPeer::TOTIME; - } - } // if either are not null - - return $this; - } // setTotime() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->token = ($row[$startcol + 0] !== null) ? (string) $row[$startcol + 0] : null; - $this->sessionid = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->status = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->fromtime = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->totime = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 5; // 5 = CcBackupPeer::NUM_COLUMNS - CcBackupPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcBackup object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcBackupPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcBackupQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcBackupPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows = 1; - $this->setNew(false); - } else { - $affectedRows = CcBackupPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - if (($retval = CcBackupPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcBackupPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getToken(); - break; - case 1: - return $this->getSessionid(); - break; - case 2: - return $this->getStatus(); - break; - case 3: - return $this->getFromtime(); - break; - case 4: - return $this->getTotime(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true) - { - $keys = CcBackupPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getToken(), - $keys[1] => $this->getSessionid(), - $keys[2] => $this->getStatus(), - $keys[3] => $this->getFromtime(), - $keys[4] => $this->getTotime(), - ); - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcBackupPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setToken($value); - break; - case 1: - $this->setSessionid($value); - break; - case 2: - $this->setStatus($value); - break; - case 3: - $this->setFromtime($value); - break; - case 4: - $this->setTotime($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcBackupPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setToken($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setSessionid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setStatus($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setFromtime($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setTotime($arr[$keys[4]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcBackupPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcBackupPeer::TOKEN)) $criteria->add(CcBackupPeer::TOKEN, $this->token); - if ($this->isColumnModified(CcBackupPeer::SESSIONID)) $criteria->add(CcBackupPeer::SESSIONID, $this->sessionid); - if ($this->isColumnModified(CcBackupPeer::STATUS)) $criteria->add(CcBackupPeer::STATUS, $this->status); - if ($this->isColumnModified(CcBackupPeer::FROMTIME)) $criteria->add(CcBackupPeer::FROMTIME, $this->fromtime); - if ($this->isColumnModified(CcBackupPeer::TOTIME)) $criteria->add(CcBackupPeer::TOTIME, $this->totime); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcBackupPeer::DATABASE_NAME); - $criteria->add(CcBackupPeer::TOKEN, $this->token); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return string - */ - public function getPrimaryKey() - { - return $this->getToken(); - } - - /** - * Generic method to set the primary key (token column). - * - * @param string $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setToken($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getToken(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcBackup (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setToken($this->token); - $copyObj->setSessionid($this->sessionid); - $copyObj->setStatus($this->status); - $copyObj->setFromtime($this->fromtime); - $copyObj->setTotime($this->totime); - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcBackup Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcBackupPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcBackupPeer(); - } - return self::$peer; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->token = null; - $this->sessionid = null; - $this->status = null; - $this->fromtime = null; - $this->totime = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcBackup diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcBackupPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcBackupPeer.php deleted file mode 100644 index b8c6a3066..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcBackupPeer.php +++ /dev/null @@ -1,750 +0,0 @@ - array ('Token', 'Sessionid', 'Status', 'Fromtime', 'Totime', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('token', 'sessionid', 'status', 'fromtime', 'totime', ), - BasePeer::TYPE_COLNAME => array (self::TOKEN, self::SESSIONID, self::STATUS, self::FROMTIME, self::TOTIME, ), - BasePeer::TYPE_RAW_COLNAME => array ('TOKEN', 'SESSIONID', 'STATUS', 'FROMTIME', 'TOTIME', ), - BasePeer::TYPE_FIELDNAME => array ('token', 'sessionid', 'status', 'fromtime', 'totime', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Token' => 0, 'Sessionid' => 1, 'Status' => 2, 'Fromtime' => 3, 'Totime' => 4, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('token' => 0, 'sessionid' => 1, 'status' => 2, 'fromtime' => 3, 'totime' => 4, ), - BasePeer::TYPE_COLNAME => array (self::TOKEN => 0, self::SESSIONID => 1, self::STATUS => 2, self::FROMTIME => 3, self::TOTIME => 4, ), - BasePeer::TYPE_RAW_COLNAME => array ('TOKEN' => 0, 'SESSIONID' => 1, 'STATUS' => 2, 'FROMTIME' => 3, 'TOTIME' => 4, ), - BasePeer::TYPE_FIELDNAME => array ('token' => 0, 'sessionid' => 1, 'status' => 2, 'fromtime' => 3, 'totime' => 4, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcBackupPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcBackupPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcBackupPeer::TOKEN); - $criteria->addSelectColumn(CcBackupPeer::SESSIONID); - $criteria->addSelectColumn(CcBackupPeer::STATUS); - $criteria->addSelectColumn(CcBackupPeer::FROMTIME); - $criteria->addSelectColumn(CcBackupPeer::TOTIME); - } else { - $criteria->addSelectColumn($alias . '.TOKEN'); - $criteria->addSelectColumn($alias . '.SESSIONID'); - $criteria->addSelectColumn($alias . '.STATUS'); - $criteria->addSelectColumn($alias . '.FROMTIME'); - $criteria->addSelectColumn($alias . '.TOTIME'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcBackupPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcBackupPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcBackup - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcBackupPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcBackupPeer::populateObjects(CcBackupPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcBackupPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcBackup $value A CcBackup object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcBackup $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getToken(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcBackup object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcBackup) { - $key = (string) $value->getToken(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcBackup object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcBackup Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_backup - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (string) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcBackupPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcBackupPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcBackupPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcBackupPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcBackup object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcBackupPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcBackupPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcBackupPeer::NUM_COLUMNS; - } else { - $cls = CcBackupPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcBackupPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcBackupPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcBackupPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcBackupTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcBackupPeer::CLASS_DEFAULT : CcBackupPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcBackup or Criteria object. - * - * @param mixed $values Criteria or CcBackup object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcBackup object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcBackup or Criteria object. - * - * @param mixed $values Criteria or CcBackup object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcBackupPeer::TOKEN); - $value = $criteria->remove(CcBackupPeer::TOKEN); - if ($value) { - $selectCriteria->add(CcBackupPeer::TOKEN, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcBackupPeer::TABLE_NAME); - } - - } else { // $values is CcBackup object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_backup table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcBackupPeer::TABLE_NAME, $con, CcBackupPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcBackupPeer::clearInstancePool(); - CcBackupPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcBackup or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcBackup object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcBackupPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcBackup) { // it's a model object - // invalidate the cache for this single object - CcBackupPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcBackupPeer::TOKEN, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcBackupPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcBackupPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcBackup object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcBackup $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcBackup $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcBackupPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcBackupPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcBackupPeer::DATABASE_NAME, CcBackupPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param string $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcBackup - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcBackupPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcBackupPeer::DATABASE_NAME); - $criteria->add(CcBackupPeer::TOKEN, $pk); - - $v = CcBackupPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcBackupPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcBackupPeer::DATABASE_NAME); - $criteria->add(CcBackupPeer::TOKEN, $pks, Criteria::IN); - $objs = CcBackupPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcBackupPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcBackupPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcBackupQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcBackupQuery.php deleted file mode 100644 index f74f068bf..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcBackupQuery.php +++ /dev/null @@ -1,292 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcBackup|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcBackupPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcBackupPeer::TOKEN, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcBackupPeer::TOKEN, $keys, Criteria::IN); - } - - /** - * Filter the query on the token column - * - * @param string $token The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByToken($token = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($token)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $token)) { - $token = str_replace('*', '%', $token); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcBackupPeer::TOKEN, $token, $comparison); - } - - /** - * Filter the query on the sessionid column - * - * @param string $sessionid The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterBySessionid($sessionid = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($sessionid)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $sessionid)) { - $sessionid = str_replace('*', '%', $sessionid); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcBackupPeer::SESSIONID, $sessionid, $comparison); - } - - /** - * Filter the query on the status column - * - * @param string $status The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByStatus($status = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($status)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $status)) { - $status = str_replace('*', '%', $status); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcBackupPeer::STATUS, $status, $comparison); - } - - /** - * Filter the query on the fromtime column - * - * @param string|array $fromtime The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByFromtime($fromtime = null, $comparison = null) - { - if (is_array($fromtime)) { - $useMinMax = false; - if (isset($fromtime['min'])) { - $this->addUsingAlias(CcBackupPeer::FROMTIME, $fromtime['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($fromtime['max'])) { - $this->addUsingAlias(CcBackupPeer::FROMTIME, $fromtime['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcBackupPeer::FROMTIME, $fromtime, $comparison); - } - - /** - * Filter the query on the totime column - * - * @param string|array $totime The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function filterByTotime($totime = null, $comparison = null) - { - if (is_array($totime)) { - $useMinMax = false; - if (isset($totime['min'])) { - $this->addUsingAlias(CcBackupPeer::TOTIME, $totime['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($totime['max'])) { - $this->addUsingAlias(CcBackupPeer::TOTIME, $totime['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcBackupPeer::TOTIME, $totime, $comparison); - } - - /** - * Exclude object from result - * - * @param CcBackup $ccBackup Object to remove from the list of results - * - * @return CcBackupQuery The current query, for fluid interface - */ - public function prune($ccBackup = null) - { - if ($ccBackup) { - $this->addUsingAlias(CcBackupPeer::TOKEN, $ccBackup->getToken(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcBackupQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcFiles.php b/backend/propel-db/build/classes/campcaster/om/BaseCcFiles.php deleted file mode 100644 index 94d732f04..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcFiles.php +++ /dev/null @@ -1,3643 +0,0 @@ -name = ''; - $this->mime = ''; - $this->ftype = ''; - $this->filepath = ''; - $this->state = 'empty'; - $this->currentlyaccessing = 0; - } - - /** - * Initializes internal state of BaseCcFiles object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getDbId() - { - return $this->id; - } - - /** - * Get the [gunid] column value. - * - * @return string - */ - public function getGunid() - { - return $this->gunid; - } - - /** - * Get the [name] column value. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get the [mime] column value. - * - * @return string - */ - public function getMime() - { - return $this->mime; - } - - /** - * Get the [ftype] column value. - * - * @return string - */ - public function getFtype() - { - return $this->ftype; - } - - /** - * Get the [filepath] column value. - * - * @return string - */ - public function getfilepath() - { - return $this->filepath; - } - - /** - * Get the [state] column value. - * - * @return string - */ - public function getState() - { - return $this->state; - } - - /** - * Get the [currentlyaccessing] column value. - * - * @return int - */ - public function getCurrentlyaccessing() - { - return $this->currentlyaccessing; - } - - /** - * Get the [editedby] column value. - * - * @return int - */ - public function getEditedby() - { - return $this->editedby; - } - - /** - * Get the [optionally formatted] temporal [mtime] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getMtime($format = 'Y-m-d H:i:s') - { - if ($this->mtime === null) { - return null; - } - - - - try { - $dt = new DateTime($this->mtime); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->mtime, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [md5] column value. - * - * @return string - */ - public function getMd5() - { - return $this->md5; - } - - /** - * Get the [track_title] column value. - * - * @return string - */ - public function getTrackTitle() - { - return $this->track_title; - } - - /** - * Get the [artist_name] column value. - * - * @return string - */ - public function getArtistName() - { - return $this->artist_name; - } - - /** - * Get the [bit_rate] column value. - * - * @return string - */ - public function getBitRate() - { - return $this->bit_rate; - } - - /** - * Get the [sample_rate] column value. - * - * @return string - */ - public function getSampleRate() - { - return $this->sample_rate; - } - - /** - * Get the [format] column value. - * - * @return string - */ - public function getFormat() - { - return $this->format; - } - - /** - * Get the [optionally formatted] temporal [length] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbLength($format = '%X') - { - if ($this->length === null) { - return null; - } - - - - try { - $dt = new DateTime($this->length); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->length, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [album_title] column value. - * - * @return string - */ - public function getAlbumTitle() - { - return $this->album_title; - } - - /** - * Get the [genre] column value. - * - * @return string - */ - public function getGenre() - { - return $this->genre; - } - - /** - * Get the [comments] column value. - * - * @return string - */ - public function getComments() - { - return $this->comments; - } - - /** - * Get the [year] column value. - * - * @return string - */ - public function getYear() - { - return $this->year; - } - - /** - * Get the [track_number] column value. - * - * @return int - */ - public function getTrackNumber() - { - return $this->track_number; - } - - /** - * Get the [channels] column value. - * - * @return int - */ - public function getChannels() - { - return $this->channels; - } - - /** - * Get the [url] column value. - * - * @return string - */ - public function getUrl() - { - return $this->url; - } - - /** - * Get the [bpm] column value. - * - * @return string - */ - public function getBpm() - { - return $this->bpm; - } - - /** - * Get the [rating] column value. - * - * @return string - */ - public function getRating() - { - return $this->rating; - } - - /** - * Get the [encoded_by] column value. - * - * @return string - */ - public function getEncodedBy() - { - return $this->encoded_by; - } - - /** - * Get the [disc_number] column value. - * - * @return string - */ - public function getDiscNumber() - { - return $this->disc_number; - } - - /** - * Get the [mood] column value. - * - * @return string - */ - public function getMood() - { - return $this->mood; - } - - /** - * Get the [label] column value. - * - * @return string - */ - public function getLabel() - { - return $this->label; - } - - /** - * Get the [composer] column value. - * - * @return string - */ - public function getComposer() - { - return $this->composer; - } - - /** - * Get the [encoder] column value. - * - * @return string - */ - public function getEncoder() - { - return $this->encoder; - } - - /** - * Get the [checksum] column value. - * - * @return string - */ - public function getChecksum() - { - return $this->checksum; - } - - /** - * Get the [lyrics] column value. - * - * @return string - */ - public function getLyrics() - { - return $this->lyrics; - } - - /** - * Get the [orchestra] column value. - * - * @return string - */ - public function getOrchestra() - { - return $this->orchestra; - } - - /** - * Get the [conductor] column value. - * - * @return string - */ - public function getConductor() - { - return $this->conductor; - } - - /** - * Get the [lyricist] column value. - * - * @return string - */ - public function getLyricist() - { - return $this->lyricist; - } - - /** - * Get the [original_lyricist] column value. - * - * @return string - */ - public function getOriginalLyricist() - { - return $this->original_lyricist; - } - - /** - * Get the [radio_station_name] column value. - * - * @return string - */ - public function getRadioStationName() - { - return $this->radio_station_name; - } - - /** - * Get the [info_url] column value. - * - * @return string - */ - public function getInfoUrl() - { - return $this->info_url; - } - - /** - * Get the [artist_url] column value. - * - * @return string - */ - public function getArtistUrl() - { - return $this->artist_url; - } - - /** - * Get the [audio_source_url] column value. - * - * @return string - */ - public function getAudioSourceUrl() - { - return $this->audio_source_url; - } - - /** - * Get the [radio_station_url] column value. - * - * @return string - */ - public function getRadioStationUrl() - { - return $this->radio_station_url; - } - - /** - * Get the [buy_this_url] column value. - * - * @return string - */ - public function getBuyThisUrl() - { - return $this->buy_this_url; - } - - /** - * Get the [isrc_number] column value. - * - * @return string - */ - public function getIsrcNumber() - { - return $this->isrc_number; - } - - /** - * Get the [catalog_number] column value. - * - * @return string - */ - public function getCatalogNumber() - { - return $this->catalog_number; - } - - /** - * Get the [original_artist] column value. - * - * @return string - */ - public function getOriginalArtist() - { - return $this->original_artist; - } - - /** - * Get the [copyright] column value. - * - * @return string - */ - public function getCopyright() - { - return $this->copyright; - } - - /** - * Get the [report_datetime] column value. - * - * @return string - */ - public function getReportDatetime() - { - return $this->report_datetime; - } - - /** - * Get the [report_location] column value. - * - * @return string - */ - public function getReportLocation() - { - return $this->report_location; - } - - /** - * Get the [report_organization] column value. - * - * @return string - */ - public function getReportOrganization() - { - return $this->report_organization; - } - - /** - * Get the [subject] column value. - * - * @return string - */ - public function getSubject() - { - return $this->subject; - } - - /** - * Get the [contributor] column value. - * - * @return string - */ - public function getContributor() - { - return $this->contributor; - } - - /** - * Get the [language] column value. - * - * @return string - */ - public function getLanguage() - { - return $this->language; - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setDbId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcFilesPeer::ID; - } - - return $this; - } // setDbId() - - /** - * Set the value of [gunid] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setGunid($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->gunid !== $v) { - $this->gunid = $v; - $this->modifiedColumns[] = CcFilesPeer::GUNID; - } - - return $this; - } // setGunid() - - /** - * Set the value of [name] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setName($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->name !== $v || $this->isNew()) { - $this->name = $v; - $this->modifiedColumns[] = CcFilesPeer::NAME; - } - - return $this; - } // setName() - - /** - * Set the value of [mime] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setMime($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->mime !== $v || $this->isNew()) { - $this->mime = $v; - $this->modifiedColumns[] = CcFilesPeer::MIME; - } - - return $this; - } // setMime() - - /** - * Set the value of [ftype] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setFtype($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->ftype !== $v || $this->isNew()) { - $this->ftype = $v; - $this->modifiedColumns[] = CcFilesPeer::FTYPE; - } - - return $this; - } // setFtype() - - /** - * Set the value of [filepath] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setfilepath($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->filepath !== $v || $this->isNew()) { - $this->filepath = $v; - $this->modifiedColumns[] = CcFilesPeer::FILEPATH; - } - - return $this; - } // setfilepath() - - /** - * Set the value of [state] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setState($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->state !== $v || $this->isNew()) { - $this->state = $v; - $this->modifiedColumns[] = CcFilesPeer::STATE; - } - - return $this; - } // setState() - - /** - * Set the value of [currentlyaccessing] column. - * - * @param int $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setCurrentlyaccessing($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->currentlyaccessing !== $v || $this->isNew()) { - $this->currentlyaccessing = $v; - $this->modifiedColumns[] = CcFilesPeer::CURRENTLYACCESSING; - } - - return $this; - } // setCurrentlyaccessing() - - /** - * Set the value of [editedby] column. - * - * @param int $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setEditedby($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->editedby !== $v) { - $this->editedby = $v; - $this->modifiedColumns[] = CcFilesPeer::EDITEDBY; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setEditedby() - - /** - * Sets the value of [mtime] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcFiles The current object (for fluent API support) - */ - public function setMtime($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->mtime !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->mtime !== null && $tmpDt = new DateTime($this->mtime)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->mtime = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcFilesPeer::MTIME; - } - } // if either are not null - - return $this; - } // setMtime() - - /** - * Set the value of [md5] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setMd5($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->md5 !== $v) { - $this->md5 = $v; - $this->modifiedColumns[] = CcFilesPeer::MD5; - } - - return $this; - } // setMd5() - - /** - * Set the value of [track_title] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setTrackTitle($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->track_title !== $v) { - $this->track_title = $v; - $this->modifiedColumns[] = CcFilesPeer::TRACK_TITLE; - } - - return $this; - } // setTrackTitle() - - /** - * Set the value of [artist_name] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setArtistName($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->artist_name !== $v) { - $this->artist_name = $v; - $this->modifiedColumns[] = CcFilesPeer::ARTIST_NAME; - } - - return $this; - } // setArtistName() - - /** - * Set the value of [bit_rate] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setBitRate($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->bit_rate !== $v) { - $this->bit_rate = $v; - $this->modifiedColumns[] = CcFilesPeer::BIT_RATE; - } - - return $this; - } // setBitRate() - - /** - * Set the value of [sample_rate] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setSampleRate($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->sample_rate !== $v) { - $this->sample_rate = $v; - $this->modifiedColumns[] = CcFilesPeer::SAMPLE_RATE; - } - - return $this; - } // setSampleRate() - - /** - * Set the value of [format] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setFormat($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->format !== $v) { - $this->format = $v; - $this->modifiedColumns[] = CcFilesPeer::FORMAT; - } - - return $this; - } // setFormat() - - /** - * Sets the value of [length] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcFiles The current object (for fluent API support) - */ - public function setDbLength($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->length !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->length !== null && $tmpDt = new DateTime($this->length)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->length = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcFilesPeer::LENGTH; - } - } // if either are not null - - return $this; - } // setDbLength() - - /** - * Set the value of [album_title] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setAlbumTitle($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->album_title !== $v) { - $this->album_title = $v; - $this->modifiedColumns[] = CcFilesPeer::ALBUM_TITLE; - } - - return $this; - } // setAlbumTitle() - - /** - * Set the value of [genre] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setGenre($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->genre !== $v) { - $this->genre = $v; - $this->modifiedColumns[] = CcFilesPeer::GENRE; - } - - return $this; - } // setGenre() - - /** - * Set the value of [comments] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setComments($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->comments !== $v) { - $this->comments = $v; - $this->modifiedColumns[] = CcFilesPeer::COMMENTS; - } - - return $this; - } // setComments() - - /** - * Set the value of [year] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setYear($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->year !== $v) { - $this->year = $v; - $this->modifiedColumns[] = CcFilesPeer::YEAR; - } - - return $this; - } // setYear() - - /** - * Set the value of [track_number] column. - * - * @param int $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setTrackNumber($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->track_number !== $v) { - $this->track_number = $v; - $this->modifiedColumns[] = CcFilesPeer::TRACK_NUMBER; - } - - return $this; - } // setTrackNumber() - - /** - * Set the value of [channels] column. - * - * @param int $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setChannels($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->channels !== $v) { - $this->channels = $v; - $this->modifiedColumns[] = CcFilesPeer::CHANNELS; - } - - return $this; - } // setChannels() - - /** - * Set the value of [url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->url !== $v) { - $this->url = $v; - $this->modifiedColumns[] = CcFilesPeer::URL; - } - - return $this; - } // setUrl() - - /** - * Set the value of [bpm] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setBpm($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->bpm !== $v) { - $this->bpm = $v; - $this->modifiedColumns[] = CcFilesPeer::BPM; - } - - return $this; - } // setBpm() - - /** - * Set the value of [rating] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setRating($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->rating !== $v) { - $this->rating = $v; - $this->modifiedColumns[] = CcFilesPeer::RATING; - } - - return $this; - } // setRating() - - /** - * Set the value of [encoded_by] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setEncodedBy($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->encoded_by !== $v) { - $this->encoded_by = $v; - $this->modifiedColumns[] = CcFilesPeer::ENCODED_BY; - } - - return $this; - } // setEncodedBy() - - /** - * Set the value of [disc_number] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setDiscNumber($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->disc_number !== $v) { - $this->disc_number = $v; - $this->modifiedColumns[] = CcFilesPeer::DISC_NUMBER; - } - - return $this; - } // setDiscNumber() - - /** - * Set the value of [mood] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setMood($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->mood !== $v) { - $this->mood = $v; - $this->modifiedColumns[] = CcFilesPeer::MOOD; - } - - return $this; - } // setMood() - - /** - * Set the value of [label] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setLabel($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->label !== $v) { - $this->label = $v; - $this->modifiedColumns[] = CcFilesPeer::LABEL; - } - - return $this; - } // setLabel() - - /** - * Set the value of [composer] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setComposer($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->composer !== $v) { - $this->composer = $v; - $this->modifiedColumns[] = CcFilesPeer::COMPOSER; - } - - return $this; - } // setComposer() - - /** - * Set the value of [encoder] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setEncoder($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->encoder !== $v) { - $this->encoder = $v; - $this->modifiedColumns[] = CcFilesPeer::ENCODER; - } - - return $this; - } // setEncoder() - - /** - * Set the value of [checksum] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setChecksum($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->checksum !== $v) { - $this->checksum = $v; - $this->modifiedColumns[] = CcFilesPeer::CHECKSUM; - } - - return $this; - } // setChecksum() - - /** - * Set the value of [lyrics] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setLyrics($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->lyrics !== $v) { - $this->lyrics = $v; - $this->modifiedColumns[] = CcFilesPeer::LYRICS; - } - - return $this; - } // setLyrics() - - /** - * Set the value of [orchestra] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setOrchestra($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->orchestra !== $v) { - $this->orchestra = $v; - $this->modifiedColumns[] = CcFilesPeer::ORCHESTRA; - } - - return $this; - } // setOrchestra() - - /** - * Set the value of [conductor] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setConductor($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->conductor !== $v) { - $this->conductor = $v; - $this->modifiedColumns[] = CcFilesPeer::CONDUCTOR; - } - - return $this; - } // setConductor() - - /** - * Set the value of [lyricist] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setLyricist($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->lyricist !== $v) { - $this->lyricist = $v; - $this->modifiedColumns[] = CcFilesPeer::LYRICIST; - } - - return $this; - } // setLyricist() - - /** - * Set the value of [original_lyricist] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setOriginalLyricist($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->original_lyricist !== $v) { - $this->original_lyricist = $v; - $this->modifiedColumns[] = CcFilesPeer::ORIGINAL_LYRICIST; - } - - return $this; - } // setOriginalLyricist() - - /** - * Set the value of [radio_station_name] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setRadioStationName($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->radio_station_name !== $v) { - $this->radio_station_name = $v; - $this->modifiedColumns[] = CcFilesPeer::RADIO_STATION_NAME; - } - - return $this; - } // setRadioStationName() - - /** - * Set the value of [info_url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setInfoUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->info_url !== $v) { - $this->info_url = $v; - $this->modifiedColumns[] = CcFilesPeer::INFO_URL; - } - - return $this; - } // setInfoUrl() - - /** - * Set the value of [artist_url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setArtistUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->artist_url !== $v) { - $this->artist_url = $v; - $this->modifiedColumns[] = CcFilesPeer::ARTIST_URL; - } - - return $this; - } // setArtistUrl() - - /** - * Set the value of [audio_source_url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setAudioSourceUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->audio_source_url !== $v) { - $this->audio_source_url = $v; - $this->modifiedColumns[] = CcFilesPeer::AUDIO_SOURCE_URL; - } - - return $this; - } // setAudioSourceUrl() - - /** - * Set the value of [radio_station_url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setRadioStationUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->radio_station_url !== $v) { - $this->radio_station_url = $v; - $this->modifiedColumns[] = CcFilesPeer::RADIO_STATION_URL; - } - - return $this; - } // setRadioStationUrl() - - /** - * Set the value of [buy_this_url] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setBuyThisUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->buy_this_url !== $v) { - $this->buy_this_url = $v; - $this->modifiedColumns[] = CcFilesPeer::BUY_THIS_URL; - } - - return $this; - } // setBuyThisUrl() - - /** - * Set the value of [isrc_number] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setIsrcNumber($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->isrc_number !== $v) { - $this->isrc_number = $v; - $this->modifiedColumns[] = CcFilesPeer::ISRC_NUMBER; - } - - return $this; - } // setIsrcNumber() - - /** - * Set the value of [catalog_number] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setCatalogNumber($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->catalog_number !== $v) { - $this->catalog_number = $v; - $this->modifiedColumns[] = CcFilesPeer::CATALOG_NUMBER; - } - - return $this; - } // setCatalogNumber() - - /** - * Set the value of [original_artist] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setOriginalArtist($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->original_artist !== $v) { - $this->original_artist = $v; - $this->modifiedColumns[] = CcFilesPeer::ORIGINAL_ARTIST; - } - - return $this; - } // setOriginalArtist() - - /** - * Set the value of [copyright] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setCopyright($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->copyright !== $v) { - $this->copyright = $v; - $this->modifiedColumns[] = CcFilesPeer::COPYRIGHT; - } - - return $this; - } // setCopyright() - - /** - * Set the value of [report_datetime] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setReportDatetime($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->report_datetime !== $v) { - $this->report_datetime = $v; - $this->modifiedColumns[] = CcFilesPeer::REPORT_DATETIME; - } - - return $this; - } // setReportDatetime() - - /** - * Set the value of [report_location] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setReportLocation($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->report_location !== $v) { - $this->report_location = $v; - $this->modifiedColumns[] = CcFilesPeer::REPORT_LOCATION; - } - - return $this; - } // setReportLocation() - - /** - * Set the value of [report_organization] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setReportOrganization($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->report_organization !== $v) { - $this->report_organization = $v; - $this->modifiedColumns[] = CcFilesPeer::REPORT_ORGANIZATION; - } - - return $this; - } // setReportOrganization() - - /** - * Set the value of [subject] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setSubject($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->subject !== $v) { - $this->subject = $v; - $this->modifiedColumns[] = CcFilesPeer::SUBJECT; - } - - return $this; - } // setSubject() - - /** - * Set the value of [contributor] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setContributor($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->contributor !== $v) { - $this->contributor = $v; - $this->modifiedColumns[] = CcFilesPeer::CONTRIBUTOR; - } - - return $this; - } // setContributor() - - /** - * Set the value of [language] column. - * - * @param string $v new value - * @return CcFiles The current object (for fluent API support) - */ - public function setLanguage($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->language !== $v) { - $this->language = $v; - $this->modifiedColumns[] = CcFilesPeer::LANGUAGE; - } - - return $this; - } // setLanguage() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->name !== '') { - return false; - } - - if ($this->mime !== '') { - return false; - } - - if ($this->ftype !== '') { - return false; - } - - if ($this->filepath !== '') { - return false; - } - - if ($this->state !== 'empty') { - return false; - } - - if ($this->currentlyaccessing !== 0) { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->gunid = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->name = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->mime = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->ftype = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->filepath = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->state = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->currentlyaccessing = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null; - $this->editedby = ($row[$startcol + 8] !== null) ? (int) $row[$startcol + 8] : null; - $this->mtime = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null; - $this->md5 = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null; - $this->track_title = ($row[$startcol + 11] !== null) ? (string) $row[$startcol + 11] : null; - $this->artist_name = ($row[$startcol + 12] !== null) ? (string) $row[$startcol + 12] : null; - $this->bit_rate = ($row[$startcol + 13] !== null) ? (string) $row[$startcol + 13] : null; - $this->sample_rate = ($row[$startcol + 14] !== null) ? (string) $row[$startcol + 14] : null; - $this->format = ($row[$startcol + 15] !== null) ? (string) $row[$startcol + 15] : null; - $this->length = ($row[$startcol + 16] !== null) ? (string) $row[$startcol + 16] : null; - $this->album_title = ($row[$startcol + 17] !== null) ? (string) $row[$startcol + 17] : null; - $this->genre = ($row[$startcol + 18] !== null) ? (string) $row[$startcol + 18] : null; - $this->comments = ($row[$startcol + 19] !== null) ? (string) $row[$startcol + 19] : null; - $this->year = ($row[$startcol + 20] !== null) ? (string) $row[$startcol + 20] : null; - $this->track_number = ($row[$startcol + 21] !== null) ? (int) $row[$startcol + 21] : null; - $this->channels = ($row[$startcol + 22] !== null) ? (int) $row[$startcol + 22] : null; - $this->url = ($row[$startcol + 23] !== null) ? (string) $row[$startcol + 23] : null; - $this->bpm = ($row[$startcol + 24] !== null) ? (string) $row[$startcol + 24] : null; - $this->rating = ($row[$startcol + 25] !== null) ? (string) $row[$startcol + 25] : null; - $this->encoded_by = ($row[$startcol + 26] !== null) ? (string) $row[$startcol + 26] : null; - $this->disc_number = ($row[$startcol + 27] !== null) ? (string) $row[$startcol + 27] : null; - $this->mood = ($row[$startcol + 28] !== null) ? (string) $row[$startcol + 28] : null; - $this->label = ($row[$startcol + 29] !== null) ? (string) $row[$startcol + 29] : null; - $this->composer = ($row[$startcol + 30] !== null) ? (string) $row[$startcol + 30] : null; - $this->encoder = ($row[$startcol + 31] !== null) ? (string) $row[$startcol + 31] : null; - $this->checksum = ($row[$startcol + 32] !== null) ? (string) $row[$startcol + 32] : null; - $this->lyrics = ($row[$startcol + 33] !== null) ? (string) $row[$startcol + 33] : null; - $this->orchestra = ($row[$startcol + 34] !== null) ? (string) $row[$startcol + 34] : null; - $this->conductor = ($row[$startcol + 35] !== null) ? (string) $row[$startcol + 35] : null; - $this->lyricist = ($row[$startcol + 36] !== null) ? (string) $row[$startcol + 36] : null; - $this->original_lyricist = ($row[$startcol + 37] !== null) ? (string) $row[$startcol + 37] : null; - $this->radio_station_name = ($row[$startcol + 38] !== null) ? (string) $row[$startcol + 38] : null; - $this->info_url = ($row[$startcol + 39] !== null) ? (string) $row[$startcol + 39] : null; - $this->artist_url = ($row[$startcol + 40] !== null) ? (string) $row[$startcol + 40] : null; - $this->audio_source_url = ($row[$startcol + 41] !== null) ? (string) $row[$startcol + 41] : null; - $this->radio_station_url = ($row[$startcol + 42] !== null) ? (string) $row[$startcol + 42] : null; - $this->buy_this_url = ($row[$startcol + 43] !== null) ? (string) $row[$startcol + 43] : null; - $this->isrc_number = ($row[$startcol + 44] !== null) ? (string) $row[$startcol + 44] : null; - $this->catalog_number = ($row[$startcol + 45] !== null) ? (string) $row[$startcol + 45] : null; - $this->original_artist = ($row[$startcol + 46] !== null) ? (string) $row[$startcol + 46] : null; - $this->copyright = ($row[$startcol + 47] !== null) ? (string) $row[$startcol + 47] : null; - $this->report_datetime = ($row[$startcol + 48] !== null) ? (string) $row[$startcol + 48] : null; - $this->report_location = ($row[$startcol + 49] !== null) ? (string) $row[$startcol + 49] : null; - $this->report_organization = ($row[$startcol + 50] !== null) ? (string) $row[$startcol + 50] : null; - $this->subject = ($row[$startcol + 51] !== null) ? (string) $row[$startcol + 51] : null; - $this->contributor = ($row[$startcol + 52] !== null) ? (string) $row[$startcol + 52] : null; - $this->language = ($row[$startcol + 53] !== null) ? (string) $row[$startcol + 53] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 54; // 54 = CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcFiles object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->editedby !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcFilesPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - $this->collCcPlaylistcontentss = null; - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcFilesQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcFilesPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcFilesPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcFilesPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcFilesPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setDbId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows += CcFilesPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - if ($this->collCcPlaylistcontentss !== null) { - foreach ($this->collCcPlaylistcontentss as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcFilesPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - if ($this->collCcPlaylistcontentss !== null) { - foreach ($this->collCcPlaylistcontentss as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcFilesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getDbId(); - break; - case 1: - return $this->getGunid(); - break; - case 2: - return $this->getName(); - break; - case 3: - return $this->getMime(); - break; - case 4: - return $this->getFtype(); - break; - case 5: - return $this->getfilepath(); - break; - case 6: - return $this->getState(); - break; - case 7: - return $this->getCurrentlyaccessing(); - break; - case 8: - return $this->getEditedby(); - break; - case 9: - return $this->getMtime(); - break; - case 10: - return $this->getMd5(); - break; - case 11: - return $this->getTrackTitle(); - break; - case 12: - return $this->getArtistName(); - break; - case 13: - return $this->getBitRate(); - break; - case 14: - return $this->getSampleRate(); - break; - case 15: - return $this->getFormat(); - break; - case 16: - return $this->getDbLength(); - break; - case 17: - return $this->getAlbumTitle(); - break; - case 18: - return $this->getGenre(); - break; - case 19: - return $this->getComments(); - break; - case 20: - return $this->getYear(); - break; - case 21: - return $this->getTrackNumber(); - break; - case 22: - return $this->getChannels(); - break; - case 23: - return $this->getUrl(); - break; - case 24: - return $this->getBpm(); - break; - case 25: - return $this->getRating(); - break; - case 26: - return $this->getEncodedBy(); - break; - case 27: - return $this->getDiscNumber(); - break; - case 28: - return $this->getMood(); - break; - case 29: - return $this->getLabel(); - break; - case 30: - return $this->getComposer(); - break; - case 31: - return $this->getEncoder(); - break; - case 32: - return $this->getChecksum(); - break; - case 33: - return $this->getLyrics(); - break; - case 34: - return $this->getOrchestra(); - break; - case 35: - return $this->getConductor(); - break; - case 36: - return $this->getLyricist(); - break; - case 37: - return $this->getOriginalLyricist(); - break; - case 38: - return $this->getRadioStationName(); - break; - case 39: - return $this->getInfoUrl(); - break; - case 40: - return $this->getArtistUrl(); - break; - case 41: - return $this->getAudioSourceUrl(); - break; - case 42: - return $this->getRadioStationUrl(); - break; - case 43: - return $this->getBuyThisUrl(); - break; - case 44: - return $this->getIsrcNumber(); - break; - case 45: - return $this->getCatalogNumber(); - break; - case 46: - return $this->getOriginalArtist(); - break; - case 47: - return $this->getCopyright(); - break; - case 48: - return $this->getReportDatetime(); - break; - case 49: - return $this->getReportLocation(); - break; - case 50: - return $this->getReportOrganization(); - break; - case 51: - return $this->getSubject(); - break; - case 52: - return $this->getContributor(); - break; - case 53: - return $this->getLanguage(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcFilesPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getDbId(), - $keys[1] => $this->getGunid(), - $keys[2] => $this->getName(), - $keys[3] => $this->getMime(), - $keys[4] => $this->getFtype(), - $keys[5] => $this->getfilepath(), - $keys[6] => $this->getState(), - $keys[7] => $this->getCurrentlyaccessing(), - $keys[8] => $this->getEditedby(), - $keys[9] => $this->getMtime(), - $keys[10] => $this->getMd5(), - $keys[11] => $this->getTrackTitle(), - $keys[12] => $this->getArtistName(), - $keys[13] => $this->getBitRate(), - $keys[14] => $this->getSampleRate(), - $keys[15] => $this->getFormat(), - $keys[16] => $this->getDbLength(), - $keys[17] => $this->getAlbumTitle(), - $keys[18] => $this->getGenre(), - $keys[19] => $this->getComments(), - $keys[20] => $this->getYear(), - $keys[21] => $this->getTrackNumber(), - $keys[22] => $this->getChannels(), - $keys[23] => $this->getUrl(), - $keys[24] => $this->getBpm(), - $keys[25] => $this->getRating(), - $keys[26] => $this->getEncodedBy(), - $keys[27] => $this->getDiscNumber(), - $keys[28] => $this->getMood(), - $keys[29] => $this->getLabel(), - $keys[30] => $this->getComposer(), - $keys[31] => $this->getEncoder(), - $keys[32] => $this->getChecksum(), - $keys[33] => $this->getLyrics(), - $keys[34] => $this->getOrchestra(), - $keys[35] => $this->getConductor(), - $keys[36] => $this->getLyricist(), - $keys[37] => $this->getOriginalLyricist(), - $keys[38] => $this->getRadioStationName(), - $keys[39] => $this->getInfoUrl(), - $keys[40] => $this->getArtistUrl(), - $keys[41] => $this->getAudioSourceUrl(), - $keys[42] => $this->getRadioStationUrl(), - $keys[43] => $this->getBuyThisUrl(), - $keys[44] => $this->getIsrcNumber(), - $keys[45] => $this->getCatalogNumber(), - $keys[46] => $this->getOriginalArtist(), - $keys[47] => $this->getCopyright(), - $keys[48] => $this->getReportDatetime(), - $keys[49] => $this->getReportLocation(), - $keys[50] => $this->getReportOrganization(), - $keys[51] => $this->getSubject(), - $keys[52] => $this->getContributor(), - $keys[53] => $this->getLanguage(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcFilesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setDbId($value); - break; - case 1: - $this->setGunid($value); - break; - case 2: - $this->setName($value); - break; - case 3: - $this->setMime($value); - break; - case 4: - $this->setFtype($value); - break; - case 5: - $this->setfilepath($value); - break; - case 6: - $this->setState($value); - break; - case 7: - $this->setCurrentlyaccessing($value); - break; - case 8: - $this->setEditedby($value); - break; - case 9: - $this->setMtime($value); - break; - case 10: - $this->setMd5($value); - break; - case 11: - $this->setTrackTitle($value); - break; - case 12: - $this->setArtistName($value); - break; - case 13: - $this->setBitRate($value); - break; - case 14: - $this->setSampleRate($value); - break; - case 15: - $this->setFormat($value); - break; - case 16: - $this->setDbLength($value); - break; - case 17: - $this->setAlbumTitle($value); - break; - case 18: - $this->setGenre($value); - break; - case 19: - $this->setComments($value); - break; - case 20: - $this->setYear($value); - break; - case 21: - $this->setTrackNumber($value); - break; - case 22: - $this->setChannels($value); - break; - case 23: - $this->setUrl($value); - break; - case 24: - $this->setBpm($value); - break; - case 25: - $this->setRating($value); - break; - case 26: - $this->setEncodedBy($value); - break; - case 27: - $this->setDiscNumber($value); - break; - case 28: - $this->setMood($value); - break; - case 29: - $this->setLabel($value); - break; - case 30: - $this->setComposer($value); - break; - case 31: - $this->setEncoder($value); - break; - case 32: - $this->setChecksum($value); - break; - case 33: - $this->setLyrics($value); - break; - case 34: - $this->setOrchestra($value); - break; - case 35: - $this->setConductor($value); - break; - case 36: - $this->setLyricist($value); - break; - case 37: - $this->setOriginalLyricist($value); - break; - case 38: - $this->setRadioStationName($value); - break; - case 39: - $this->setInfoUrl($value); - break; - case 40: - $this->setArtistUrl($value); - break; - case 41: - $this->setAudioSourceUrl($value); - break; - case 42: - $this->setRadioStationUrl($value); - break; - case 43: - $this->setBuyThisUrl($value); - break; - case 44: - $this->setIsrcNumber($value); - break; - case 45: - $this->setCatalogNumber($value); - break; - case 46: - $this->setOriginalArtist($value); - break; - case 47: - $this->setCopyright($value); - break; - case 48: - $this->setReportDatetime($value); - break; - case 49: - $this->setReportLocation($value); - break; - case 50: - $this->setReportOrganization($value); - break; - case 51: - $this->setSubject($value); - break; - case 52: - $this->setContributor($value); - break; - case 53: - $this->setLanguage($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcFilesPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setDbId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setGunid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setName($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setMime($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setFtype($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setfilepath($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setState($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setCurrentlyaccessing($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setEditedby($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setMtime($arr[$keys[9]]); - if (array_key_exists($keys[10], $arr)) $this->setMd5($arr[$keys[10]]); - if (array_key_exists($keys[11], $arr)) $this->setTrackTitle($arr[$keys[11]]); - if (array_key_exists($keys[12], $arr)) $this->setArtistName($arr[$keys[12]]); - if (array_key_exists($keys[13], $arr)) $this->setBitRate($arr[$keys[13]]); - if (array_key_exists($keys[14], $arr)) $this->setSampleRate($arr[$keys[14]]); - if (array_key_exists($keys[15], $arr)) $this->setFormat($arr[$keys[15]]); - if (array_key_exists($keys[16], $arr)) $this->setDbLength($arr[$keys[16]]); - if (array_key_exists($keys[17], $arr)) $this->setAlbumTitle($arr[$keys[17]]); - if (array_key_exists($keys[18], $arr)) $this->setGenre($arr[$keys[18]]); - if (array_key_exists($keys[19], $arr)) $this->setComments($arr[$keys[19]]); - if (array_key_exists($keys[20], $arr)) $this->setYear($arr[$keys[20]]); - if (array_key_exists($keys[21], $arr)) $this->setTrackNumber($arr[$keys[21]]); - if (array_key_exists($keys[22], $arr)) $this->setChannels($arr[$keys[22]]); - if (array_key_exists($keys[23], $arr)) $this->setUrl($arr[$keys[23]]); - if (array_key_exists($keys[24], $arr)) $this->setBpm($arr[$keys[24]]); - if (array_key_exists($keys[25], $arr)) $this->setRating($arr[$keys[25]]); - if (array_key_exists($keys[26], $arr)) $this->setEncodedBy($arr[$keys[26]]); - if (array_key_exists($keys[27], $arr)) $this->setDiscNumber($arr[$keys[27]]); - if (array_key_exists($keys[28], $arr)) $this->setMood($arr[$keys[28]]); - if (array_key_exists($keys[29], $arr)) $this->setLabel($arr[$keys[29]]); - if (array_key_exists($keys[30], $arr)) $this->setComposer($arr[$keys[30]]); - if (array_key_exists($keys[31], $arr)) $this->setEncoder($arr[$keys[31]]); - if (array_key_exists($keys[32], $arr)) $this->setChecksum($arr[$keys[32]]); - if (array_key_exists($keys[33], $arr)) $this->setLyrics($arr[$keys[33]]); - if (array_key_exists($keys[34], $arr)) $this->setOrchestra($arr[$keys[34]]); - if (array_key_exists($keys[35], $arr)) $this->setConductor($arr[$keys[35]]); - if (array_key_exists($keys[36], $arr)) $this->setLyricist($arr[$keys[36]]); - if (array_key_exists($keys[37], $arr)) $this->setOriginalLyricist($arr[$keys[37]]); - if (array_key_exists($keys[38], $arr)) $this->setRadioStationName($arr[$keys[38]]); - if (array_key_exists($keys[39], $arr)) $this->setInfoUrl($arr[$keys[39]]); - if (array_key_exists($keys[40], $arr)) $this->setArtistUrl($arr[$keys[40]]); - if (array_key_exists($keys[41], $arr)) $this->setAudioSourceUrl($arr[$keys[41]]); - if (array_key_exists($keys[42], $arr)) $this->setRadioStationUrl($arr[$keys[42]]); - if (array_key_exists($keys[43], $arr)) $this->setBuyThisUrl($arr[$keys[43]]); - if (array_key_exists($keys[44], $arr)) $this->setIsrcNumber($arr[$keys[44]]); - if (array_key_exists($keys[45], $arr)) $this->setCatalogNumber($arr[$keys[45]]); - if (array_key_exists($keys[46], $arr)) $this->setOriginalArtist($arr[$keys[46]]); - if (array_key_exists($keys[47], $arr)) $this->setCopyright($arr[$keys[47]]); - if (array_key_exists($keys[48], $arr)) $this->setReportDatetime($arr[$keys[48]]); - if (array_key_exists($keys[49], $arr)) $this->setReportLocation($arr[$keys[49]]); - if (array_key_exists($keys[50], $arr)) $this->setReportOrganization($arr[$keys[50]]); - if (array_key_exists($keys[51], $arr)) $this->setSubject($arr[$keys[51]]); - if (array_key_exists($keys[52], $arr)) $this->setContributor($arr[$keys[52]]); - if (array_key_exists($keys[53], $arr)) $this->setLanguage($arr[$keys[53]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcFilesPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcFilesPeer::ID)) $criteria->add(CcFilesPeer::ID, $this->id); - if ($this->isColumnModified(CcFilesPeer::GUNID)) $criteria->add(CcFilesPeer::GUNID, $this->gunid); - if ($this->isColumnModified(CcFilesPeer::NAME)) $criteria->add(CcFilesPeer::NAME, $this->name); - if ($this->isColumnModified(CcFilesPeer::MIME)) $criteria->add(CcFilesPeer::MIME, $this->mime); - if ($this->isColumnModified(CcFilesPeer::FTYPE)) $criteria->add(CcFilesPeer::FTYPE, $this->ftype); - if ($this->isColumnModified(CcFilesPeer::FILEPATH)) $criteria->add(CcFilesPeer::FILEPATH, $this->filepath); - if ($this->isColumnModified(CcFilesPeer::STATE)) $criteria->add(CcFilesPeer::STATE, $this->state); - if ($this->isColumnModified(CcFilesPeer::CURRENTLYACCESSING)) $criteria->add(CcFilesPeer::CURRENTLYACCESSING, $this->currentlyaccessing); - if ($this->isColumnModified(CcFilesPeer::EDITEDBY)) $criteria->add(CcFilesPeer::EDITEDBY, $this->editedby); - if ($this->isColumnModified(CcFilesPeer::MTIME)) $criteria->add(CcFilesPeer::MTIME, $this->mtime); - if ($this->isColumnModified(CcFilesPeer::MD5)) $criteria->add(CcFilesPeer::MD5, $this->md5); - if ($this->isColumnModified(CcFilesPeer::TRACK_TITLE)) $criteria->add(CcFilesPeer::TRACK_TITLE, $this->track_title); - if ($this->isColumnModified(CcFilesPeer::ARTIST_NAME)) $criteria->add(CcFilesPeer::ARTIST_NAME, $this->artist_name); - if ($this->isColumnModified(CcFilesPeer::BIT_RATE)) $criteria->add(CcFilesPeer::BIT_RATE, $this->bit_rate); - if ($this->isColumnModified(CcFilesPeer::SAMPLE_RATE)) $criteria->add(CcFilesPeer::SAMPLE_RATE, $this->sample_rate); - if ($this->isColumnModified(CcFilesPeer::FORMAT)) $criteria->add(CcFilesPeer::FORMAT, $this->format); - if ($this->isColumnModified(CcFilesPeer::LENGTH)) $criteria->add(CcFilesPeer::LENGTH, $this->length); - if ($this->isColumnModified(CcFilesPeer::ALBUM_TITLE)) $criteria->add(CcFilesPeer::ALBUM_TITLE, $this->album_title); - if ($this->isColumnModified(CcFilesPeer::GENRE)) $criteria->add(CcFilesPeer::GENRE, $this->genre); - if ($this->isColumnModified(CcFilesPeer::COMMENTS)) $criteria->add(CcFilesPeer::COMMENTS, $this->comments); - if ($this->isColumnModified(CcFilesPeer::YEAR)) $criteria->add(CcFilesPeer::YEAR, $this->year); - if ($this->isColumnModified(CcFilesPeer::TRACK_NUMBER)) $criteria->add(CcFilesPeer::TRACK_NUMBER, $this->track_number); - if ($this->isColumnModified(CcFilesPeer::CHANNELS)) $criteria->add(CcFilesPeer::CHANNELS, $this->channels); - if ($this->isColumnModified(CcFilesPeer::URL)) $criteria->add(CcFilesPeer::URL, $this->url); - if ($this->isColumnModified(CcFilesPeer::BPM)) $criteria->add(CcFilesPeer::BPM, $this->bpm); - if ($this->isColumnModified(CcFilesPeer::RATING)) $criteria->add(CcFilesPeer::RATING, $this->rating); - if ($this->isColumnModified(CcFilesPeer::ENCODED_BY)) $criteria->add(CcFilesPeer::ENCODED_BY, $this->encoded_by); - if ($this->isColumnModified(CcFilesPeer::DISC_NUMBER)) $criteria->add(CcFilesPeer::DISC_NUMBER, $this->disc_number); - if ($this->isColumnModified(CcFilesPeer::MOOD)) $criteria->add(CcFilesPeer::MOOD, $this->mood); - if ($this->isColumnModified(CcFilesPeer::LABEL)) $criteria->add(CcFilesPeer::LABEL, $this->label); - if ($this->isColumnModified(CcFilesPeer::COMPOSER)) $criteria->add(CcFilesPeer::COMPOSER, $this->composer); - if ($this->isColumnModified(CcFilesPeer::ENCODER)) $criteria->add(CcFilesPeer::ENCODER, $this->encoder); - if ($this->isColumnModified(CcFilesPeer::CHECKSUM)) $criteria->add(CcFilesPeer::CHECKSUM, $this->checksum); - if ($this->isColumnModified(CcFilesPeer::LYRICS)) $criteria->add(CcFilesPeer::LYRICS, $this->lyrics); - if ($this->isColumnModified(CcFilesPeer::ORCHESTRA)) $criteria->add(CcFilesPeer::ORCHESTRA, $this->orchestra); - if ($this->isColumnModified(CcFilesPeer::CONDUCTOR)) $criteria->add(CcFilesPeer::CONDUCTOR, $this->conductor); - if ($this->isColumnModified(CcFilesPeer::LYRICIST)) $criteria->add(CcFilesPeer::LYRICIST, $this->lyricist); - if ($this->isColumnModified(CcFilesPeer::ORIGINAL_LYRICIST)) $criteria->add(CcFilesPeer::ORIGINAL_LYRICIST, $this->original_lyricist); - if ($this->isColumnModified(CcFilesPeer::RADIO_STATION_NAME)) $criteria->add(CcFilesPeer::RADIO_STATION_NAME, $this->radio_station_name); - if ($this->isColumnModified(CcFilesPeer::INFO_URL)) $criteria->add(CcFilesPeer::INFO_URL, $this->info_url); - if ($this->isColumnModified(CcFilesPeer::ARTIST_URL)) $criteria->add(CcFilesPeer::ARTIST_URL, $this->artist_url); - if ($this->isColumnModified(CcFilesPeer::AUDIO_SOURCE_URL)) $criteria->add(CcFilesPeer::AUDIO_SOURCE_URL, $this->audio_source_url); - if ($this->isColumnModified(CcFilesPeer::RADIO_STATION_URL)) $criteria->add(CcFilesPeer::RADIO_STATION_URL, $this->radio_station_url); - if ($this->isColumnModified(CcFilesPeer::BUY_THIS_URL)) $criteria->add(CcFilesPeer::BUY_THIS_URL, $this->buy_this_url); - if ($this->isColumnModified(CcFilesPeer::ISRC_NUMBER)) $criteria->add(CcFilesPeer::ISRC_NUMBER, $this->isrc_number); - if ($this->isColumnModified(CcFilesPeer::CATALOG_NUMBER)) $criteria->add(CcFilesPeer::CATALOG_NUMBER, $this->catalog_number); - if ($this->isColumnModified(CcFilesPeer::ORIGINAL_ARTIST)) $criteria->add(CcFilesPeer::ORIGINAL_ARTIST, $this->original_artist); - if ($this->isColumnModified(CcFilesPeer::COPYRIGHT)) $criteria->add(CcFilesPeer::COPYRIGHT, $this->copyright); - if ($this->isColumnModified(CcFilesPeer::REPORT_DATETIME)) $criteria->add(CcFilesPeer::REPORT_DATETIME, $this->report_datetime); - if ($this->isColumnModified(CcFilesPeer::REPORT_LOCATION)) $criteria->add(CcFilesPeer::REPORT_LOCATION, $this->report_location); - if ($this->isColumnModified(CcFilesPeer::REPORT_ORGANIZATION)) $criteria->add(CcFilesPeer::REPORT_ORGANIZATION, $this->report_organization); - if ($this->isColumnModified(CcFilesPeer::SUBJECT)) $criteria->add(CcFilesPeer::SUBJECT, $this->subject); - if ($this->isColumnModified(CcFilesPeer::CONTRIBUTOR)) $criteria->add(CcFilesPeer::CONTRIBUTOR, $this->contributor); - if ($this->isColumnModified(CcFilesPeer::LANGUAGE)) $criteria->add(CcFilesPeer::LANGUAGE, $this->language); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcFilesPeer::DATABASE_NAME); - $criteria->add(CcFilesPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getDbId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setDbId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getDbId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcFiles (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setGunid($this->gunid); - $copyObj->setName($this->name); - $copyObj->setMime($this->mime); - $copyObj->setFtype($this->ftype); - $copyObj->setfilepath($this->filepath); - $copyObj->setState($this->state); - $copyObj->setCurrentlyaccessing($this->currentlyaccessing); - $copyObj->setEditedby($this->editedby); - $copyObj->setMtime($this->mtime); - $copyObj->setMd5($this->md5); - $copyObj->setTrackTitle($this->track_title); - $copyObj->setArtistName($this->artist_name); - $copyObj->setBitRate($this->bit_rate); - $copyObj->setSampleRate($this->sample_rate); - $copyObj->setFormat($this->format); - $copyObj->setDbLength($this->length); - $copyObj->setAlbumTitle($this->album_title); - $copyObj->setGenre($this->genre); - $copyObj->setComments($this->comments); - $copyObj->setYear($this->year); - $copyObj->setTrackNumber($this->track_number); - $copyObj->setChannels($this->channels); - $copyObj->setUrl($this->url); - $copyObj->setBpm($this->bpm); - $copyObj->setRating($this->rating); - $copyObj->setEncodedBy($this->encoded_by); - $copyObj->setDiscNumber($this->disc_number); - $copyObj->setMood($this->mood); - $copyObj->setLabel($this->label); - $copyObj->setComposer($this->composer); - $copyObj->setEncoder($this->encoder); - $copyObj->setChecksum($this->checksum); - $copyObj->setLyrics($this->lyrics); - $copyObj->setOrchestra($this->orchestra); - $copyObj->setConductor($this->conductor); - $copyObj->setLyricist($this->lyricist); - $copyObj->setOriginalLyricist($this->original_lyricist); - $copyObj->setRadioStationName($this->radio_station_name); - $copyObj->setInfoUrl($this->info_url); - $copyObj->setArtistUrl($this->artist_url); - $copyObj->setAudioSourceUrl($this->audio_source_url); - $copyObj->setRadioStationUrl($this->radio_station_url); - $copyObj->setBuyThisUrl($this->buy_this_url); - $copyObj->setIsrcNumber($this->isrc_number); - $copyObj->setCatalogNumber($this->catalog_number); - $copyObj->setOriginalArtist($this->original_artist); - $copyObj->setCopyright($this->copyright); - $copyObj->setReportDatetime($this->report_datetime); - $copyObj->setReportLocation($this->report_location); - $copyObj->setReportOrganization($this->report_organization); - $copyObj->setSubject($this->subject); - $copyObj->setContributor($this->contributor); - $copyObj->setLanguage($this->language); - - if ($deepCopy) { - // important: temporarily setNew(false) because this affects the behavior of - // the getter/setter methods for fkey referrer objects. - $copyObj->setNew(false); - - foreach ($this->getCcPlaylistcontentss() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcPlaylistcontents($relObj->copy($deepCopy)); - } - } - - } // if ($deepCopy) - - - $copyObj->setNew(true); - $copyObj->setDbId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcFiles Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcFilesPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcFilesPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcFiles The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setEditedby(NULL); - } else { - $this->setEditedby($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcFiles($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->editedby !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->editedby, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcFiless($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears out the collCcPlaylistcontentss collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcPlaylistcontentss() - */ - public function clearCcPlaylistcontentss() - { - $this->collCcPlaylistcontentss = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcPlaylistcontentss collection. - * - * By default this just sets the collCcPlaylistcontentss collection to an empty array (like clearcollCcPlaylistcontentss()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcPlaylistcontentss() - { - $this->collCcPlaylistcontentss = new PropelObjectCollection(); - $this->collCcPlaylistcontentss->setModel('CcPlaylistcontents'); - } - - /** - * Gets an array of CcPlaylistcontents objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcFiles is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcPlaylistcontents[] List of CcPlaylistcontents objects - * @throws PropelException - */ - public function getCcPlaylistcontentss($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcPlaylistcontentss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylistcontentss) { - // return empty collection - $this->initCcPlaylistcontentss(); - } else { - $collCcPlaylistcontentss = CcPlaylistcontentsQuery::create(null, $criteria) - ->filterByCcFiles($this) - ->find($con); - if (null !== $criteria) { - return $collCcPlaylistcontentss; - } - $this->collCcPlaylistcontentss = $collCcPlaylistcontentss; - } - } - return $this->collCcPlaylistcontentss; - } - - /** - * Returns the number of related CcPlaylistcontents objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcPlaylistcontents objects. - * @throws PropelException - */ - public function countCcPlaylistcontentss(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcPlaylistcontentss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylistcontentss) { - return 0; - } else { - $query = CcPlaylistcontentsQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcFiles($this) - ->count($con); - } - } else { - return count($this->collCcPlaylistcontentss); - } - } - - /** - * Method called to associate a CcPlaylistcontents object to this object - * through the CcPlaylistcontents foreign key attribute. - * - * @param CcPlaylistcontents $l CcPlaylistcontents - * @return void - * @throws PropelException - */ - public function addCcPlaylistcontents(CcPlaylistcontents $l) - { - if ($this->collCcPlaylistcontentss === null) { - $this->initCcPlaylistcontentss(); - } - if (!$this->collCcPlaylistcontentss->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcPlaylistcontentss[]= $l; - $l->setCcFiles($this); - } - } - - - /** - * If this collection has already been initialized with - * an identical criteria, it returns the collection. - * Otherwise if this CcFiles is new, it will return - * an empty collection; or if this CcFiles has previously - * been saved, it will retrieve related CcPlaylistcontentss from storage. - * - * This method is protected by default in order to keep the public - * api reasonable. You can provide public methods for those you - * actually need in CcFiles. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return PropelCollection|array CcPlaylistcontents[] List of CcPlaylistcontents objects - */ - public function getCcPlaylistcontentssJoinCcPlaylist($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $query = CcPlaylistcontentsQuery::create(null, $criteria); - $query->joinWith('CcPlaylist', $join_behavior); - - return $this->getCcPlaylistcontentss($query, $con); - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->gunid = null; - $this->name = null; - $this->mime = null; - $this->ftype = null; - $this->filepath = null; - $this->state = null; - $this->currentlyaccessing = null; - $this->editedby = null; - $this->mtime = null; - $this->md5 = null; - $this->track_title = null; - $this->artist_name = null; - $this->bit_rate = null; - $this->sample_rate = null; - $this->format = null; - $this->length = null; - $this->album_title = null; - $this->genre = null; - $this->comments = null; - $this->year = null; - $this->track_number = null; - $this->channels = null; - $this->url = null; - $this->bpm = null; - $this->rating = null; - $this->encoded_by = null; - $this->disc_number = null; - $this->mood = null; - $this->label = null; - $this->composer = null; - $this->encoder = null; - $this->checksum = null; - $this->lyrics = null; - $this->orchestra = null; - $this->conductor = null; - $this->lyricist = null; - $this->original_lyricist = null; - $this->radio_station_name = null; - $this->info_url = null; - $this->artist_url = null; - $this->audio_source_url = null; - $this->radio_station_url = null; - $this->buy_this_url = null; - $this->isrc_number = null; - $this->catalog_number = null; - $this->original_artist = null; - $this->copyright = null; - $this->report_datetime = null; - $this->report_location = null; - $this->report_organization = null; - $this->subject = null; - $this->contributor = null; - $this->language = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - if ($this->collCcPlaylistcontentss) { - foreach ((array) $this->collCcPlaylistcontentss as $o) { - $o->clearAllReferences($deep); - } - } - } // if ($deep) - - $this->collCcPlaylistcontentss = null; - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcFiles diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcFilesPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcFilesPeer.php deleted file mode 100644 index 8f48b5fc9..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcFilesPeer.php +++ /dev/null @@ -1,1236 +0,0 @@ - array ('DbId', 'Gunid', 'Name', 'Mime', 'Ftype', 'filepath', 'State', 'Currentlyaccessing', 'Editedby', 'Mtime', 'Md5', 'TrackTitle', 'ArtistName', 'BitRate', 'SampleRate', 'Format', 'DbLength', 'AlbumTitle', 'Genre', 'Comments', 'Year', 'TrackNumber', 'Channels', 'Url', 'Bpm', 'Rating', 'EncodedBy', 'DiscNumber', 'Mood', 'Label', 'Composer', 'Encoder', 'Checksum', 'Lyrics', 'Orchestra', 'Conductor', 'Lyricist', 'OriginalLyricist', 'RadioStationName', 'InfoUrl', 'ArtistUrl', 'AudioSourceUrl', 'RadioStationUrl', 'BuyThisUrl', 'IsrcNumber', 'CatalogNumber', 'OriginalArtist', 'Copyright', 'ReportDatetime', 'ReportLocation', 'ReportOrganization', 'Subject', 'Contributor', 'Language', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'gunid', 'name', 'mime', 'ftype', 'filepath', 'state', 'currentlyaccessing', 'editedby', 'mtime', 'md5', 'trackTitle', 'artistName', 'bitRate', 'sampleRate', 'format', 'dbLength', 'albumTitle', 'genre', 'comments', 'year', 'trackNumber', 'channels', 'url', 'bpm', 'rating', 'encodedBy', 'discNumber', 'mood', 'label', 'composer', 'encoder', 'checksum', 'lyrics', 'orchestra', 'conductor', 'lyricist', 'originalLyricist', 'radioStationName', 'infoUrl', 'artistUrl', 'audioSourceUrl', 'radioStationUrl', 'buyThisUrl', 'isrcNumber', 'catalogNumber', 'originalArtist', 'copyright', 'reportDatetime', 'reportLocation', 'reportOrganization', 'subject', 'contributor', 'language', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::GUNID, self::NAME, self::MIME, self::FTYPE, self::FILEPATH, self::STATE, self::CURRENTLYACCESSING, self::EDITEDBY, self::MTIME, self::MD5, self::TRACK_TITLE, self::ARTIST_NAME, self::BIT_RATE, self::SAMPLE_RATE, self::FORMAT, self::LENGTH, self::ALBUM_TITLE, self::GENRE, self::COMMENTS, self::YEAR, self::TRACK_NUMBER, self::CHANNELS, self::URL, self::BPM, self::RATING, self::ENCODED_BY, self::DISC_NUMBER, self::MOOD, self::LABEL, self::COMPOSER, self::ENCODER, self::CHECKSUM, self::LYRICS, self::ORCHESTRA, self::CONDUCTOR, self::LYRICIST, self::ORIGINAL_LYRICIST, self::RADIO_STATION_NAME, self::INFO_URL, self::ARTIST_URL, self::AUDIO_SOURCE_URL, self::RADIO_STATION_URL, self::BUY_THIS_URL, self::ISRC_NUMBER, self::CATALOG_NUMBER, self::ORIGINAL_ARTIST, self::COPYRIGHT, self::REPORT_DATETIME, self::REPORT_LOCATION, self::REPORT_ORGANIZATION, self::SUBJECT, self::CONTRIBUTOR, self::LANGUAGE, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'GUNID', 'NAME', 'MIME', 'FTYPE', 'FILEPATH', 'STATE', 'CURRENTLYACCESSING', 'EDITEDBY', 'MTIME', 'MD5', 'TRACK_TITLE', 'ARTIST_NAME', 'BIT_RATE', 'SAMPLE_RATE', 'FORMAT', 'LENGTH', 'ALBUM_TITLE', 'GENRE', 'COMMENTS', 'YEAR', 'TRACK_NUMBER', 'CHANNELS', 'URL', 'BPM', 'RATING', 'ENCODED_BY', 'DISC_NUMBER', 'MOOD', 'LABEL', 'COMPOSER', 'ENCODER', 'CHECKSUM', 'LYRICS', 'ORCHESTRA', 'CONDUCTOR', 'LYRICIST', 'ORIGINAL_LYRICIST', 'RADIO_STATION_NAME', 'INFO_URL', 'ARTIST_URL', 'AUDIO_SOURCE_URL', 'RADIO_STATION_URL', 'BUY_THIS_URL', 'ISRC_NUMBER', 'CATALOG_NUMBER', 'ORIGINAL_ARTIST', 'COPYRIGHT', 'REPORT_DATETIME', 'REPORT_LOCATION', 'REPORT_ORGANIZATION', 'SUBJECT', 'CONTRIBUTOR', 'LANGUAGE', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'gunid', 'name', 'mime', 'ftype', 'filepath', 'state', 'currentlyaccessing', 'editedby', 'mtime', 'md5', 'track_title', 'artist_name', 'bit_rate', 'sample_rate', 'format', 'length', 'album_title', 'genre', 'comments', 'year', 'track_number', 'channels', 'url', 'bpm', 'rating', 'encoded_by', 'disc_number', 'mood', 'label', 'composer', 'encoder', 'checksum', 'lyrics', 'orchestra', 'conductor', 'lyricist', 'original_lyricist', 'radio_station_name', 'info_url', 'artist_url', 'audio_source_url', 'radio_station_url', 'buy_this_url', 'isrc_number', 'catalog_number', 'original_artist', 'copyright', 'report_datetime', 'report_location', 'report_organization', 'subject', 'contributor', 'language', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'Gunid' => 1, 'Name' => 2, 'Mime' => 3, 'Ftype' => 4, 'filepath' => 5, 'State' => 6, 'Currentlyaccessing' => 7, 'Editedby' => 8, 'Mtime' => 9, 'Md5' => 10, 'TrackTitle' => 11, 'ArtistName' => 12, 'BitRate' => 13, 'SampleRate' => 14, 'Format' => 15, 'DbLength' => 16, 'AlbumTitle' => 17, 'Genre' => 18, 'Comments' => 19, 'Year' => 20, 'TrackNumber' => 21, 'Channels' => 22, 'Url' => 23, 'Bpm' => 24, 'Rating' => 25, 'EncodedBy' => 26, 'DiscNumber' => 27, 'Mood' => 28, 'Label' => 29, 'Composer' => 30, 'Encoder' => 31, 'Checksum' => 32, 'Lyrics' => 33, 'Orchestra' => 34, 'Conductor' => 35, 'Lyricist' => 36, 'OriginalLyricist' => 37, 'RadioStationName' => 38, 'InfoUrl' => 39, 'ArtistUrl' => 40, 'AudioSourceUrl' => 41, 'RadioStationUrl' => 42, 'BuyThisUrl' => 43, 'IsrcNumber' => 44, 'CatalogNumber' => 45, 'OriginalArtist' => 46, 'Copyright' => 47, 'ReportDatetime' => 48, 'ReportLocation' => 49, 'ReportOrganization' => 50, 'Subject' => 51, 'Contributor' => 52, 'Language' => 53, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'gunid' => 1, 'name' => 2, 'mime' => 3, 'ftype' => 4, 'filepath' => 5, 'state' => 6, 'currentlyaccessing' => 7, 'editedby' => 8, 'mtime' => 9, 'md5' => 10, 'trackTitle' => 11, 'artistName' => 12, 'bitRate' => 13, 'sampleRate' => 14, 'format' => 15, 'dbLength' => 16, 'albumTitle' => 17, 'genre' => 18, 'comments' => 19, 'year' => 20, 'trackNumber' => 21, 'channels' => 22, 'url' => 23, 'bpm' => 24, 'rating' => 25, 'encodedBy' => 26, 'discNumber' => 27, 'mood' => 28, 'label' => 29, 'composer' => 30, 'encoder' => 31, 'checksum' => 32, 'lyrics' => 33, 'orchestra' => 34, 'conductor' => 35, 'lyricist' => 36, 'originalLyricist' => 37, 'radioStationName' => 38, 'infoUrl' => 39, 'artistUrl' => 40, 'audioSourceUrl' => 41, 'radioStationUrl' => 42, 'buyThisUrl' => 43, 'isrcNumber' => 44, 'catalogNumber' => 45, 'originalArtist' => 46, 'copyright' => 47, 'reportDatetime' => 48, 'reportLocation' => 49, 'reportOrganization' => 50, 'subject' => 51, 'contributor' => 52, 'language' => 53, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::GUNID => 1, self::NAME => 2, self::MIME => 3, self::FTYPE => 4, self::FILEPATH => 5, self::STATE => 6, self::CURRENTLYACCESSING => 7, self::EDITEDBY => 8, self::MTIME => 9, self::MD5 => 10, self::TRACK_TITLE => 11, self::ARTIST_NAME => 12, self::BIT_RATE => 13, self::SAMPLE_RATE => 14, self::FORMAT => 15, self::LENGTH => 16, self::ALBUM_TITLE => 17, self::GENRE => 18, self::COMMENTS => 19, self::YEAR => 20, self::TRACK_NUMBER => 21, self::CHANNELS => 22, self::URL => 23, self::BPM => 24, self::RATING => 25, self::ENCODED_BY => 26, self::DISC_NUMBER => 27, self::MOOD => 28, self::LABEL => 29, self::COMPOSER => 30, self::ENCODER => 31, self::CHECKSUM => 32, self::LYRICS => 33, self::ORCHESTRA => 34, self::CONDUCTOR => 35, self::LYRICIST => 36, self::ORIGINAL_LYRICIST => 37, self::RADIO_STATION_NAME => 38, self::INFO_URL => 39, self::ARTIST_URL => 40, self::AUDIO_SOURCE_URL => 41, self::RADIO_STATION_URL => 42, self::BUY_THIS_URL => 43, self::ISRC_NUMBER => 44, self::CATALOG_NUMBER => 45, self::ORIGINAL_ARTIST => 46, self::COPYRIGHT => 47, self::REPORT_DATETIME => 48, self::REPORT_LOCATION => 49, self::REPORT_ORGANIZATION => 50, self::SUBJECT => 51, self::CONTRIBUTOR => 52, self::LANGUAGE => 53, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'GUNID' => 1, 'NAME' => 2, 'MIME' => 3, 'FTYPE' => 4, 'FILEPATH' => 5, 'STATE' => 6, 'CURRENTLYACCESSING' => 7, 'EDITEDBY' => 8, 'MTIME' => 9, 'MD5' => 10, 'TRACK_TITLE' => 11, 'ARTIST_NAME' => 12, 'BIT_RATE' => 13, 'SAMPLE_RATE' => 14, 'FORMAT' => 15, 'LENGTH' => 16, 'ALBUM_TITLE' => 17, 'GENRE' => 18, 'COMMENTS' => 19, 'YEAR' => 20, 'TRACK_NUMBER' => 21, 'CHANNELS' => 22, 'URL' => 23, 'BPM' => 24, 'RATING' => 25, 'ENCODED_BY' => 26, 'DISC_NUMBER' => 27, 'MOOD' => 28, 'LABEL' => 29, 'COMPOSER' => 30, 'ENCODER' => 31, 'CHECKSUM' => 32, 'LYRICS' => 33, 'ORCHESTRA' => 34, 'CONDUCTOR' => 35, 'LYRICIST' => 36, 'ORIGINAL_LYRICIST' => 37, 'RADIO_STATION_NAME' => 38, 'INFO_URL' => 39, 'ARTIST_URL' => 40, 'AUDIO_SOURCE_URL' => 41, 'RADIO_STATION_URL' => 42, 'BUY_THIS_URL' => 43, 'ISRC_NUMBER' => 44, 'CATALOG_NUMBER' => 45, 'ORIGINAL_ARTIST' => 46, 'COPYRIGHT' => 47, 'REPORT_DATETIME' => 48, 'REPORT_LOCATION' => 49, 'REPORT_ORGANIZATION' => 50, 'SUBJECT' => 51, 'CONTRIBUTOR' => 52, 'LANGUAGE' => 53, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'gunid' => 1, 'name' => 2, 'mime' => 3, 'ftype' => 4, 'filepath' => 5, 'state' => 6, 'currentlyaccessing' => 7, 'editedby' => 8, 'mtime' => 9, 'md5' => 10, 'track_title' => 11, 'artist_name' => 12, 'bit_rate' => 13, 'sample_rate' => 14, 'format' => 15, 'length' => 16, 'album_title' => 17, 'genre' => 18, 'comments' => 19, 'year' => 20, 'track_number' => 21, 'channels' => 22, 'url' => 23, 'bpm' => 24, 'rating' => 25, 'encoded_by' => 26, 'disc_number' => 27, 'mood' => 28, 'label' => 29, 'composer' => 30, 'encoder' => 31, 'checksum' => 32, 'lyrics' => 33, 'orchestra' => 34, 'conductor' => 35, 'lyricist' => 36, 'original_lyricist' => 37, 'radio_station_name' => 38, 'info_url' => 39, 'artist_url' => 40, 'audio_source_url' => 41, 'radio_station_url' => 42, 'buy_this_url' => 43, 'isrc_number' => 44, 'catalog_number' => 45, 'original_artist' => 46, 'copyright' => 47, 'report_datetime' => 48, 'report_location' => 49, 'report_organization' => 50, 'subject' => 51, 'contributor' => 52, 'language' => 53, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcFilesPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcFilesPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcFilesPeer::ID); - $criteria->addSelectColumn(CcFilesPeer::GUNID); - $criteria->addSelectColumn(CcFilesPeer::NAME); - $criteria->addSelectColumn(CcFilesPeer::MIME); - $criteria->addSelectColumn(CcFilesPeer::FTYPE); - $criteria->addSelectColumn(CcFilesPeer::FILEPATH); - $criteria->addSelectColumn(CcFilesPeer::STATE); - $criteria->addSelectColumn(CcFilesPeer::CURRENTLYACCESSING); - $criteria->addSelectColumn(CcFilesPeer::EDITEDBY); - $criteria->addSelectColumn(CcFilesPeer::MTIME); - $criteria->addSelectColumn(CcFilesPeer::MD5); - $criteria->addSelectColumn(CcFilesPeer::TRACK_TITLE); - $criteria->addSelectColumn(CcFilesPeer::ARTIST_NAME); - $criteria->addSelectColumn(CcFilesPeer::BIT_RATE); - $criteria->addSelectColumn(CcFilesPeer::SAMPLE_RATE); - $criteria->addSelectColumn(CcFilesPeer::FORMAT); - $criteria->addSelectColumn(CcFilesPeer::LENGTH); - $criteria->addSelectColumn(CcFilesPeer::ALBUM_TITLE); - $criteria->addSelectColumn(CcFilesPeer::GENRE); - $criteria->addSelectColumn(CcFilesPeer::COMMENTS); - $criteria->addSelectColumn(CcFilesPeer::YEAR); - $criteria->addSelectColumn(CcFilesPeer::TRACK_NUMBER); - $criteria->addSelectColumn(CcFilesPeer::CHANNELS); - $criteria->addSelectColumn(CcFilesPeer::URL); - $criteria->addSelectColumn(CcFilesPeer::BPM); - $criteria->addSelectColumn(CcFilesPeer::RATING); - $criteria->addSelectColumn(CcFilesPeer::ENCODED_BY); - $criteria->addSelectColumn(CcFilesPeer::DISC_NUMBER); - $criteria->addSelectColumn(CcFilesPeer::MOOD); - $criteria->addSelectColumn(CcFilesPeer::LABEL); - $criteria->addSelectColumn(CcFilesPeer::COMPOSER); - $criteria->addSelectColumn(CcFilesPeer::ENCODER); - $criteria->addSelectColumn(CcFilesPeer::CHECKSUM); - $criteria->addSelectColumn(CcFilesPeer::LYRICS); - $criteria->addSelectColumn(CcFilesPeer::ORCHESTRA); - $criteria->addSelectColumn(CcFilesPeer::CONDUCTOR); - $criteria->addSelectColumn(CcFilesPeer::LYRICIST); - $criteria->addSelectColumn(CcFilesPeer::ORIGINAL_LYRICIST); - $criteria->addSelectColumn(CcFilesPeer::RADIO_STATION_NAME); - $criteria->addSelectColumn(CcFilesPeer::INFO_URL); - $criteria->addSelectColumn(CcFilesPeer::ARTIST_URL); - $criteria->addSelectColumn(CcFilesPeer::AUDIO_SOURCE_URL); - $criteria->addSelectColumn(CcFilesPeer::RADIO_STATION_URL); - $criteria->addSelectColumn(CcFilesPeer::BUY_THIS_URL); - $criteria->addSelectColumn(CcFilesPeer::ISRC_NUMBER); - $criteria->addSelectColumn(CcFilesPeer::CATALOG_NUMBER); - $criteria->addSelectColumn(CcFilesPeer::ORIGINAL_ARTIST); - $criteria->addSelectColumn(CcFilesPeer::COPYRIGHT); - $criteria->addSelectColumn(CcFilesPeer::REPORT_DATETIME); - $criteria->addSelectColumn(CcFilesPeer::REPORT_LOCATION); - $criteria->addSelectColumn(CcFilesPeer::REPORT_ORGANIZATION); - $criteria->addSelectColumn(CcFilesPeer::SUBJECT); - $criteria->addSelectColumn(CcFilesPeer::CONTRIBUTOR); - $criteria->addSelectColumn(CcFilesPeer::LANGUAGE); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.GUNID'); - $criteria->addSelectColumn($alias . '.NAME'); - $criteria->addSelectColumn($alias . '.MIME'); - $criteria->addSelectColumn($alias . '.FTYPE'); - $criteria->addSelectColumn($alias . '.FILEPATH'); - $criteria->addSelectColumn($alias . '.STATE'); - $criteria->addSelectColumn($alias . '.CURRENTLYACCESSING'); - $criteria->addSelectColumn($alias . '.EDITEDBY'); - $criteria->addSelectColumn($alias . '.MTIME'); - $criteria->addSelectColumn($alias . '.MD5'); - $criteria->addSelectColumn($alias . '.TRACK_TITLE'); - $criteria->addSelectColumn($alias . '.ARTIST_NAME'); - $criteria->addSelectColumn($alias . '.BIT_RATE'); - $criteria->addSelectColumn($alias . '.SAMPLE_RATE'); - $criteria->addSelectColumn($alias . '.FORMAT'); - $criteria->addSelectColumn($alias . '.LENGTH'); - $criteria->addSelectColumn($alias . '.ALBUM_TITLE'); - $criteria->addSelectColumn($alias . '.GENRE'); - $criteria->addSelectColumn($alias . '.COMMENTS'); - $criteria->addSelectColumn($alias . '.YEAR'); - $criteria->addSelectColumn($alias . '.TRACK_NUMBER'); - $criteria->addSelectColumn($alias . '.CHANNELS'); - $criteria->addSelectColumn($alias . '.URL'); - $criteria->addSelectColumn($alias . '.BPM'); - $criteria->addSelectColumn($alias . '.RATING'); - $criteria->addSelectColumn($alias . '.ENCODED_BY'); - $criteria->addSelectColumn($alias . '.DISC_NUMBER'); - $criteria->addSelectColumn($alias . '.MOOD'); - $criteria->addSelectColumn($alias . '.LABEL'); - $criteria->addSelectColumn($alias . '.COMPOSER'); - $criteria->addSelectColumn($alias . '.ENCODER'); - $criteria->addSelectColumn($alias . '.CHECKSUM'); - $criteria->addSelectColumn($alias . '.LYRICS'); - $criteria->addSelectColumn($alias . '.ORCHESTRA'); - $criteria->addSelectColumn($alias . '.CONDUCTOR'); - $criteria->addSelectColumn($alias . '.LYRICIST'); - $criteria->addSelectColumn($alias . '.ORIGINAL_LYRICIST'); - $criteria->addSelectColumn($alias . '.RADIO_STATION_NAME'); - $criteria->addSelectColumn($alias . '.INFO_URL'); - $criteria->addSelectColumn($alias . '.ARTIST_URL'); - $criteria->addSelectColumn($alias . '.AUDIO_SOURCE_URL'); - $criteria->addSelectColumn($alias . '.RADIO_STATION_URL'); - $criteria->addSelectColumn($alias . '.BUY_THIS_URL'); - $criteria->addSelectColumn($alias . '.ISRC_NUMBER'); - $criteria->addSelectColumn($alias . '.CATALOG_NUMBER'); - $criteria->addSelectColumn($alias . '.ORIGINAL_ARTIST'); - $criteria->addSelectColumn($alias . '.COPYRIGHT'); - $criteria->addSelectColumn($alias . '.REPORT_DATETIME'); - $criteria->addSelectColumn($alias . '.REPORT_LOCATION'); - $criteria->addSelectColumn($alias . '.REPORT_ORGANIZATION'); - $criteria->addSelectColumn($alias . '.SUBJECT'); - $criteria->addSelectColumn($alias . '.CONTRIBUTOR'); - $criteria->addSelectColumn($alias . '.LANGUAGE'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcFilesPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcFilesPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcFiles - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcFilesPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcFilesPeer::populateObjects(CcFilesPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcFilesPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcFiles $value A CcFiles object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcFiles $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getDbId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcFiles object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcFiles) { - $key = (string) $value->getDbId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcFiles object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcFiles Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_files - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - // Invalidate objects in CcPlaylistcontentsPeer instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - CcPlaylistcontentsPeer::clearInstancePool(); - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcFilesPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcFilesPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcFilesPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcFilesPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcFiles object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcFilesPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcFilesPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcFilesPeer::NUM_COLUMNS; - } else { - $cls = CcFilesPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcFilesPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcFilesPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcFilesPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcFilesPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcFiles objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcFiles objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcFilesPeer::addSelectColumns($criteria); - $startcol = (CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcFilesPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcFilesPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcFilesPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcFilesPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcFilesPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcFiles) to $obj2 (CcSubjs) - $obj2->addCcFiles($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcFilesPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcFilesPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcFilesPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcFiles objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcFiles objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcFilesPeer::addSelectColumns($criteria); - $startcol2 = (CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcFilesPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcFilesPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcFilesPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcFilesPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcFilesPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcFiles) to the collection in $obj2 (CcSubjs) - $obj2->addCcFiles($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcFilesPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcFilesPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcFilesTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcFilesPeer::CLASS_DEFAULT : CcFilesPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcFiles or Criteria object. - * - * @param mixed $values Criteria or CcFiles object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcFiles object - } - - if ($criteria->containsKey(CcFilesPeer::ID) && $criteria->keyContainsValue(CcFilesPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcFilesPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcFiles or Criteria object. - * - * @param mixed $values Criteria or CcFiles object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcFilesPeer::ID); - $value = $criteria->remove(CcFilesPeer::ID); - if ($value) { - $selectCriteria->add(CcFilesPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcFilesPeer::TABLE_NAME); - } - - } else { // $values is CcFiles object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_files table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcFilesPeer::TABLE_NAME, $con, CcFilesPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcFilesPeer::clearInstancePool(); - CcFilesPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcFiles or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcFiles object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcFilesPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcFiles) { // it's a model object - // invalidate the cache for this single object - CcFilesPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcFilesPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcFilesPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcFilesPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcFiles object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcFiles $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcFiles $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcFilesPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcFilesPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcFilesPeer::DATABASE_NAME, CcFilesPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcFiles - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcFilesPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcFilesPeer::DATABASE_NAME); - $criteria->add(CcFilesPeer::ID, $pk); - - $v = CcFilesPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcFilesPeer::DATABASE_NAME); - $criteria->add(CcFilesPeer::ID, $pks, Criteria::IN); - $objs = CcFilesPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcFilesPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcFilesPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcFilesQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcFilesQuery.php deleted file mode 100644 index 03136febe..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcFilesQuery.php +++ /dev/null @@ -1,1733 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcFiles|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcFilesPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcFilesPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcFilesPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $dbId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByDbId($dbId = null, $comparison = null) - { - if (is_array($dbId) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcFilesPeer::ID, $dbId, $comparison); - } - - /** - * Filter the query on the gunid column - * - * @param string $gunid The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByGunid($gunid = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($gunid)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $gunid)) { - $gunid = str_replace('*', '%', $gunid); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::GUNID, $gunid, $comparison); - } - - /** - * Filter the query on the name column - * - * @param string $name The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByName($name = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($name)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $name)) { - $name = str_replace('*', '%', $name); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::NAME, $name, $comparison); - } - - /** - * Filter the query on the mime column - * - * @param string $mime The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByMime($mime = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($mime)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $mime)) { - $mime = str_replace('*', '%', $mime); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::MIME, $mime, $comparison); - } - - /** - * Filter the query on the ftype column - * - * @param string $ftype The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByFtype($ftype = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($ftype)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $ftype)) { - $ftype = str_replace('*', '%', $ftype); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::FTYPE, $ftype, $comparison); - } - - /** - * Filter the query on the filepath column - * - * @param string $filepath The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByfilepath($filepath = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($filepath)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $filepath)) { - $filepath = str_replace('*', '%', $filepath); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::FILEPATH, $filepath, $comparison); - } - - /** - * Filter the query on the state column - * - * @param string $state The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByState($state = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($state)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $state)) { - $state = str_replace('*', '%', $state); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::STATE, $state, $comparison); - } - - /** - * Filter the query on the currentlyaccessing column - * - * @param int|array $currentlyaccessing The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByCurrentlyaccessing($currentlyaccessing = null, $comparison = null) - { - if (is_array($currentlyaccessing)) { - $useMinMax = false; - if (isset($currentlyaccessing['min'])) { - $this->addUsingAlias(CcFilesPeer::CURRENTLYACCESSING, $currentlyaccessing['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($currentlyaccessing['max'])) { - $this->addUsingAlias(CcFilesPeer::CURRENTLYACCESSING, $currentlyaccessing['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::CURRENTLYACCESSING, $currentlyaccessing, $comparison); - } - - /** - * Filter the query on the editedby column - * - * @param int|array $editedby The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByEditedby($editedby = null, $comparison = null) - { - if (is_array($editedby)) { - $useMinMax = false; - if (isset($editedby['min'])) { - $this->addUsingAlias(CcFilesPeer::EDITEDBY, $editedby['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($editedby['max'])) { - $this->addUsingAlias(CcFilesPeer::EDITEDBY, $editedby['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::EDITEDBY, $editedby, $comparison); - } - - /** - * Filter the query on the mtime column - * - * @param string|array $mtime The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByMtime($mtime = null, $comparison = null) - { - if (is_array($mtime)) { - $useMinMax = false; - if (isset($mtime['min'])) { - $this->addUsingAlias(CcFilesPeer::MTIME, $mtime['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($mtime['max'])) { - $this->addUsingAlias(CcFilesPeer::MTIME, $mtime['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::MTIME, $mtime, $comparison); - } - - /** - * Filter the query on the md5 column - * - * @param string $md5 The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByMd5($md5 = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($md5)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $md5)) { - $md5 = str_replace('*', '%', $md5); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::MD5, $md5, $comparison); - } - - /** - * Filter the query on the track_title column - * - * @param string $trackTitle The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByTrackTitle($trackTitle = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($trackTitle)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $trackTitle)) { - $trackTitle = str_replace('*', '%', $trackTitle); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::TRACK_TITLE, $trackTitle, $comparison); - } - - /** - * Filter the query on the artist_name column - * - * @param string $artistName The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByArtistName($artistName = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($artistName)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $artistName)) { - $artistName = str_replace('*', '%', $artistName); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ARTIST_NAME, $artistName, $comparison); - } - - /** - * Filter the query on the bit_rate column - * - * @param string $bitRate The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByBitRate($bitRate = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($bitRate)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $bitRate)) { - $bitRate = str_replace('*', '%', $bitRate); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::BIT_RATE, $bitRate, $comparison); - } - - /** - * Filter the query on the sample_rate column - * - * @param string $sampleRate The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterBySampleRate($sampleRate = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($sampleRate)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $sampleRate)) { - $sampleRate = str_replace('*', '%', $sampleRate); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::SAMPLE_RATE, $sampleRate, $comparison); - } - - /** - * Filter the query on the format column - * - * @param string $format The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByFormat($format = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($format)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $format)) { - $format = str_replace('*', '%', $format); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::FORMAT, $format, $comparison); - } - - /** - * Filter the query on the length column - * - * @param string|array $dbLength The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByDbLength($dbLength = null, $comparison = null) - { - if (is_array($dbLength)) { - $useMinMax = false; - if (isset($dbLength['min'])) { - $this->addUsingAlias(CcFilesPeer::LENGTH, $dbLength['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbLength['max'])) { - $this->addUsingAlias(CcFilesPeer::LENGTH, $dbLength['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::LENGTH, $dbLength, $comparison); - } - - /** - * Filter the query on the album_title column - * - * @param string $albumTitle The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByAlbumTitle($albumTitle = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($albumTitle)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $albumTitle)) { - $albumTitle = str_replace('*', '%', $albumTitle); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ALBUM_TITLE, $albumTitle, $comparison); - } - - /** - * Filter the query on the genre column - * - * @param string $genre The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByGenre($genre = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($genre)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $genre)) { - $genre = str_replace('*', '%', $genre); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::GENRE, $genre, $comparison); - } - - /** - * Filter the query on the comments column - * - * @param string $comments The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByComments($comments = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($comments)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $comments)) { - $comments = str_replace('*', '%', $comments); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::COMMENTS, $comments, $comparison); - } - - /** - * Filter the query on the year column - * - * @param string $year The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByYear($year = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($year)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $year)) { - $year = str_replace('*', '%', $year); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::YEAR, $year, $comparison); - } - - /** - * Filter the query on the track_number column - * - * @param int|array $trackNumber The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByTrackNumber($trackNumber = null, $comparison = null) - { - if (is_array($trackNumber)) { - $useMinMax = false; - if (isset($trackNumber['min'])) { - $this->addUsingAlias(CcFilesPeer::TRACK_NUMBER, $trackNumber['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($trackNumber['max'])) { - $this->addUsingAlias(CcFilesPeer::TRACK_NUMBER, $trackNumber['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::TRACK_NUMBER, $trackNumber, $comparison); - } - - /** - * Filter the query on the channels column - * - * @param int|array $channels The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByChannels($channels = null, $comparison = null) - { - if (is_array($channels)) { - $useMinMax = false; - if (isset($channels['min'])) { - $this->addUsingAlias(CcFilesPeer::CHANNELS, $channels['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($channels['max'])) { - $this->addUsingAlias(CcFilesPeer::CHANNELS, $channels['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcFilesPeer::CHANNELS, $channels, $comparison); - } - - /** - * Filter the query on the url column - * - * @param string $url The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByUrl($url = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($url)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $url)) { - $url = str_replace('*', '%', $url); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::URL, $url, $comparison); - } - - /** - * Filter the query on the bpm column - * - * @param string $bpm The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByBpm($bpm = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($bpm)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $bpm)) { - $bpm = str_replace('*', '%', $bpm); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::BPM, $bpm, $comparison); - } - - /** - * Filter the query on the rating column - * - * @param string $rating The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByRating($rating = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($rating)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $rating)) { - $rating = str_replace('*', '%', $rating); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::RATING, $rating, $comparison); - } - - /** - * Filter the query on the encoded_by column - * - * @param string $encodedBy The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByEncodedBy($encodedBy = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($encodedBy)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $encodedBy)) { - $encodedBy = str_replace('*', '%', $encodedBy); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ENCODED_BY, $encodedBy, $comparison); - } - - /** - * Filter the query on the disc_number column - * - * @param string $discNumber The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByDiscNumber($discNumber = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($discNumber)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $discNumber)) { - $discNumber = str_replace('*', '%', $discNumber); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::DISC_NUMBER, $discNumber, $comparison); - } - - /** - * Filter the query on the mood column - * - * @param string $mood The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByMood($mood = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($mood)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $mood)) { - $mood = str_replace('*', '%', $mood); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::MOOD, $mood, $comparison); - } - - /** - * Filter the query on the label column - * - * @param string $label The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByLabel($label = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($label)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $label)) { - $label = str_replace('*', '%', $label); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::LABEL, $label, $comparison); - } - - /** - * Filter the query on the composer column - * - * @param string $composer The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByComposer($composer = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($composer)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $composer)) { - $composer = str_replace('*', '%', $composer); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::COMPOSER, $composer, $comparison); - } - - /** - * Filter the query on the encoder column - * - * @param string $encoder The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByEncoder($encoder = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($encoder)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $encoder)) { - $encoder = str_replace('*', '%', $encoder); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ENCODER, $encoder, $comparison); - } - - /** - * Filter the query on the checksum column - * - * @param string $checksum The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByChecksum($checksum = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($checksum)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $checksum)) { - $checksum = str_replace('*', '%', $checksum); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::CHECKSUM, $checksum, $comparison); - } - - /** - * Filter the query on the lyrics column - * - * @param string $lyrics The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByLyrics($lyrics = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($lyrics)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $lyrics)) { - $lyrics = str_replace('*', '%', $lyrics); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::LYRICS, $lyrics, $comparison); - } - - /** - * Filter the query on the orchestra column - * - * @param string $orchestra The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByOrchestra($orchestra = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($orchestra)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $orchestra)) { - $orchestra = str_replace('*', '%', $orchestra); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ORCHESTRA, $orchestra, $comparison); - } - - /** - * Filter the query on the conductor column - * - * @param string $conductor The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByConductor($conductor = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($conductor)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $conductor)) { - $conductor = str_replace('*', '%', $conductor); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::CONDUCTOR, $conductor, $comparison); - } - - /** - * Filter the query on the lyricist column - * - * @param string $lyricist The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByLyricist($lyricist = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($lyricist)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $lyricist)) { - $lyricist = str_replace('*', '%', $lyricist); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::LYRICIST, $lyricist, $comparison); - } - - /** - * Filter the query on the original_lyricist column - * - * @param string $originalLyricist The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByOriginalLyricist($originalLyricist = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($originalLyricist)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $originalLyricist)) { - $originalLyricist = str_replace('*', '%', $originalLyricist); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ORIGINAL_LYRICIST, $originalLyricist, $comparison); - } - - /** - * Filter the query on the radio_station_name column - * - * @param string $radioStationName The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByRadioStationName($radioStationName = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($radioStationName)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $radioStationName)) { - $radioStationName = str_replace('*', '%', $radioStationName); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::RADIO_STATION_NAME, $radioStationName, $comparison); - } - - /** - * Filter the query on the info_url column - * - * @param string $infoUrl The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByInfoUrl($infoUrl = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($infoUrl)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $infoUrl)) { - $infoUrl = str_replace('*', '%', $infoUrl); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::INFO_URL, $infoUrl, $comparison); - } - - /** - * Filter the query on the artist_url column - * - * @param string $artistUrl The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByArtistUrl($artistUrl = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($artistUrl)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $artistUrl)) { - $artistUrl = str_replace('*', '%', $artistUrl); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ARTIST_URL, $artistUrl, $comparison); - } - - /** - * Filter the query on the audio_source_url column - * - * @param string $audioSourceUrl The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByAudioSourceUrl($audioSourceUrl = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($audioSourceUrl)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $audioSourceUrl)) { - $audioSourceUrl = str_replace('*', '%', $audioSourceUrl); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::AUDIO_SOURCE_URL, $audioSourceUrl, $comparison); - } - - /** - * Filter the query on the radio_station_url column - * - * @param string $radioStationUrl The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByRadioStationUrl($radioStationUrl = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($radioStationUrl)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $radioStationUrl)) { - $radioStationUrl = str_replace('*', '%', $radioStationUrl); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::RADIO_STATION_URL, $radioStationUrl, $comparison); - } - - /** - * Filter the query on the buy_this_url column - * - * @param string $buyThisUrl The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByBuyThisUrl($buyThisUrl = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($buyThisUrl)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $buyThisUrl)) { - $buyThisUrl = str_replace('*', '%', $buyThisUrl); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::BUY_THIS_URL, $buyThisUrl, $comparison); - } - - /** - * Filter the query on the isrc_number column - * - * @param string $isrcNumber The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByIsrcNumber($isrcNumber = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($isrcNumber)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $isrcNumber)) { - $isrcNumber = str_replace('*', '%', $isrcNumber); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ISRC_NUMBER, $isrcNumber, $comparison); - } - - /** - * Filter the query on the catalog_number column - * - * @param string $catalogNumber The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByCatalogNumber($catalogNumber = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($catalogNumber)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $catalogNumber)) { - $catalogNumber = str_replace('*', '%', $catalogNumber); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::CATALOG_NUMBER, $catalogNumber, $comparison); - } - - /** - * Filter the query on the original_artist column - * - * @param string $originalArtist The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByOriginalArtist($originalArtist = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($originalArtist)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $originalArtist)) { - $originalArtist = str_replace('*', '%', $originalArtist); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::ORIGINAL_ARTIST, $originalArtist, $comparison); - } - - /** - * Filter the query on the copyright column - * - * @param string $copyright The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByCopyright($copyright = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($copyright)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $copyright)) { - $copyright = str_replace('*', '%', $copyright); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::COPYRIGHT, $copyright, $comparison); - } - - /** - * Filter the query on the report_datetime column - * - * @param string $reportDatetime The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByReportDatetime($reportDatetime = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($reportDatetime)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $reportDatetime)) { - $reportDatetime = str_replace('*', '%', $reportDatetime); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::REPORT_DATETIME, $reportDatetime, $comparison); - } - - /** - * Filter the query on the report_location column - * - * @param string $reportLocation The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByReportLocation($reportLocation = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($reportLocation)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $reportLocation)) { - $reportLocation = str_replace('*', '%', $reportLocation); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::REPORT_LOCATION, $reportLocation, $comparison); - } - - /** - * Filter the query on the report_organization column - * - * @param string $reportOrganization The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByReportOrganization($reportOrganization = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($reportOrganization)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $reportOrganization)) { - $reportOrganization = str_replace('*', '%', $reportOrganization); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::REPORT_ORGANIZATION, $reportOrganization, $comparison); - } - - /** - * Filter the query on the subject column - * - * @param string $subject The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterBySubject($subject = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($subject)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $subject)) { - $subject = str_replace('*', '%', $subject); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::SUBJECT, $subject, $comparison); - } - - /** - * Filter the query on the contributor column - * - * @param string $contributor The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByContributor($contributor = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($contributor)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $contributor)) { - $contributor = str_replace('*', '%', $contributor); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::CONTRIBUTOR, $contributor, $comparison); - } - - /** - * Filter the query on the language column - * - * @param string $language The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByLanguage($language = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($language)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $language)) { - $language = str_replace('*', '%', $language); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcFilesPeer::LANGUAGE, $language, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcFilesPeer::EDITEDBY, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Filter the query by a related CcPlaylistcontents object - * - * @param CcPlaylistcontents $ccPlaylistcontents the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function filterByCcPlaylistcontents($ccPlaylistcontents, $comparison = null) - { - return $this - ->addUsingAlias(CcFilesPeer::ID, $ccPlaylistcontents->getDbFileId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPlaylistcontents relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function joinCcPlaylistcontents($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPlaylistcontents'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPlaylistcontents'); - } - - return $this; - } - - /** - * Use the CcPlaylistcontents relation CcPlaylistcontents object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistcontentsQuery A secondary query class using the current class as primary query - */ - public function useCcPlaylistcontentsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPlaylistcontents($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPlaylistcontents', 'CcPlaylistcontentsQuery'); - } - - /** - * Exclude object from result - * - * @param CcFiles $ccFiles Object to remove from the list of results - * - * @return CcFilesQuery The current query, for fluid interface - */ - public function prune($ccFiles = null) - { - if ($ccFiles) { - $this->addUsingAlias(CcFilesPeer::ID, $ccFiles->getDbId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcFilesQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPerms.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPerms.php deleted file mode 100644 index a7398920f..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPerms.php +++ /dev/null @@ -1,945 +0,0 @@ -permid; - } - - /** - * Get the [subj] column value. - * - * @return int - */ - public function getSubj() - { - return $this->subj; - } - - /** - * Get the [action] column value. - * - * @return string - */ - public function getAction() - { - return $this->action; - } - - /** - * Get the [obj] column value. - * - * @return int - */ - public function getObj() - { - return $this->obj; - } - - /** - * Get the [type] column value. - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Set the value of [permid] column. - * - * @param int $v new value - * @return CcPerms The current object (for fluent API support) - */ - public function setPermid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->permid !== $v) { - $this->permid = $v; - $this->modifiedColumns[] = CcPermsPeer::PERMID; - } - - return $this; - } // setPermid() - - /** - * Set the value of [subj] column. - * - * @param int $v new value - * @return CcPerms The current object (for fluent API support) - */ - public function setSubj($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->subj !== $v) { - $this->subj = $v; - $this->modifiedColumns[] = CcPermsPeer::SUBJ; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setSubj() - - /** - * Set the value of [action] column. - * - * @param string $v new value - * @return CcPerms The current object (for fluent API support) - */ - public function setAction($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->action !== $v) { - $this->action = $v; - $this->modifiedColumns[] = CcPermsPeer::ACTION; - } - - return $this; - } // setAction() - - /** - * Set the value of [obj] column. - * - * @param int $v new value - * @return CcPerms The current object (for fluent API support) - */ - public function setObj($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->obj !== $v) { - $this->obj = $v; - $this->modifiedColumns[] = CcPermsPeer::OBJ; - } - - return $this; - } // setObj() - - /** - * Set the value of [type] column. - * - * @param string $v new value - * @return CcPerms The current object (for fluent API support) - */ - public function setType($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->type !== $v) { - $this->type = $v; - $this->modifiedColumns[] = CcPermsPeer::TYPE; - } - - return $this; - } // setType() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->permid = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->subj = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->action = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->obj = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null; - $this->type = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 5; // 5 = CcPermsPeer::NUM_COLUMNS - CcPermsPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcPerms object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->subj !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcPermsPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcPermsQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcPermsPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setNew(false); - } else { - $affectedRows += CcPermsPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcPermsPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPermsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getPermid(); - break; - case 1: - return $this->getSubj(); - break; - case 2: - return $this->getAction(); - break; - case 3: - return $this->getObj(); - break; - case 4: - return $this->getType(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcPermsPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getPermid(), - $keys[1] => $this->getSubj(), - $keys[2] => $this->getAction(), - $keys[3] => $this->getObj(), - $keys[4] => $this->getType(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPermsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setPermid($value); - break; - case 1: - $this->setSubj($value); - break; - case 2: - $this->setAction($value); - break; - case 3: - $this->setObj($value); - break; - case 4: - $this->setType($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcPermsPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setPermid($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setSubj($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setAction($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setObj($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setType($arr[$keys[4]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcPermsPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcPermsPeer::PERMID)) $criteria->add(CcPermsPeer::PERMID, $this->permid); - if ($this->isColumnModified(CcPermsPeer::SUBJ)) $criteria->add(CcPermsPeer::SUBJ, $this->subj); - if ($this->isColumnModified(CcPermsPeer::ACTION)) $criteria->add(CcPermsPeer::ACTION, $this->action); - if ($this->isColumnModified(CcPermsPeer::OBJ)) $criteria->add(CcPermsPeer::OBJ, $this->obj); - if ($this->isColumnModified(CcPermsPeer::TYPE)) $criteria->add(CcPermsPeer::TYPE, $this->type); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcPermsPeer::DATABASE_NAME); - $criteria->add(CcPermsPeer::PERMID, $this->permid); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getPermid(); - } - - /** - * Generic method to set the primary key (permid column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setPermid($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getPermid(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcPerms (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setPermid($this->permid); - $copyObj->setSubj($this->subj); - $copyObj->setAction($this->action); - $copyObj->setObj($this->obj); - $copyObj->setType($this->type); - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcPerms Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcPermsPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcPermsPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcPerms The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setSubj(NULL); - } else { - $this->setSubj($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcPerms($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->subj !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->subj, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcPermss($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->permid = null; - $this->subj = null; - $this->action = null; - $this->obj = null; - $this->type = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcPerms diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPermsPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPermsPeer.php deleted file mode 100644 index 2bfdaeb0e..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPermsPeer.php +++ /dev/null @@ -1,984 +0,0 @@ - array ('Permid', 'Subj', 'Action', 'Obj', 'Type', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('permid', 'subj', 'action', 'obj', 'type', ), - BasePeer::TYPE_COLNAME => array (self::PERMID, self::SUBJ, self::ACTION, self::OBJ, self::TYPE, ), - BasePeer::TYPE_RAW_COLNAME => array ('PERMID', 'SUBJ', 'ACTION', 'OBJ', 'TYPE', ), - BasePeer::TYPE_FIELDNAME => array ('permid', 'subj', 'action', 'obj', 'type', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Permid' => 0, 'Subj' => 1, 'Action' => 2, 'Obj' => 3, 'Type' => 4, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('permid' => 0, 'subj' => 1, 'action' => 2, 'obj' => 3, 'type' => 4, ), - BasePeer::TYPE_COLNAME => array (self::PERMID => 0, self::SUBJ => 1, self::ACTION => 2, self::OBJ => 3, self::TYPE => 4, ), - BasePeer::TYPE_RAW_COLNAME => array ('PERMID' => 0, 'SUBJ' => 1, 'ACTION' => 2, 'OBJ' => 3, 'TYPE' => 4, ), - BasePeer::TYPE_FIELDNAME => array ('permid' => 0, 'subj' => 1, 'action' => 2, 'obj' => 3, 'type' => 4, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcPermsPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcPermsPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcPermsPeer::PERMID); - $criteria->addSelectColumn(CcPermsPeer::SUBJ); - $criteria->addSelectColumn(CcPermsPeer::ACTION); - $criteria->addSelectColumn(CcPermsPeer::OBJ); - $criteria->addSelectColumn(CcPermsPeer::TYPE); - } else { - $criteria->addSelectColumn($alias . '.PERMID'); - $criteria->addSelectColumn($alias . '.SUBJ'); - $criteria->addSelectColumn($alias . '.ACTION'); - $criteria->addSelectColumn($alias . '.OBJ'); - $criteria->addSelectColumn($alias . '.TYPE'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPermsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPermsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcPerms - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcPermsPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcPermsPeer::populateObjects(CcPermsPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcPermsPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcPerms $value A CcPerms object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcPerms $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getPermid(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcPerms object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcPerms) { - $key = (string) $value->getPermid(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcPerms object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcPerms Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_perms - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcPermsPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcPermsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcPermsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcPermsPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcPerms object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcPermsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcPermsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcPermsPeer::NUM_COLUMNS; - } else { - $cls = CcPermsPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcPermsPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPermsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPermsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPermsPeer::SUBJ, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcPerms objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPerms objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPermsPeer::addSelectColumns($criteria); - $startcol = (CcPermsPeer::NUM_COLUMNS - CcPermsPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcPermsPeer::SUBJ, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPermsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPermsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcPermsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPermsPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcPerms) to $obj2 (CcSubjs) - $obj2->addCcPerms($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPermsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPermsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPermsPeer::SUBJ, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcPerms objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPerms objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPermsPeer::addSelectColumns($criteria); - $startcol2 = (CcPermsPeer::NUM_COLUMNS - CcPermsPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPermsPeer::SUBJ, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPermsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPermsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPermsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPermsPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcPerms) to the collection in $obj2 (CcSubjs) - $obj2->addCcPerms($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcPermsPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcPermsPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcPermsTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcPermsPeer::CLASS_DEFAULT : CcPermsPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcPerms or Criteria object. - * - * @param mixed $values Criteria or CcPerms object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcPerms object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcPerms or Criteria object. - * - * @param mixed $values Criteria or CcPerms object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcPermsPeer::PERMID); - $value = $criteria->remove(CcPermsPeer::PERMID); - if ($value) { - $selectCriteria->add(CcPermsPeer::PERMID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcPermsPeer::TABLE_NAME); - } - - } else { // $values is CcPerms object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_perms table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcPermsPeer::TABLE_NAME, $con, CcPermsPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcPermsPeer::clearInstancePool(); - CcPermsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcPerms or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcPerms object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcPermsPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcPerms) { // it's a model object - // invalidate the cache for this single object - CcPermsPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcPermsPeer::PERMID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcPermsPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcPermsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcPerms object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcPerms $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcPerms $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcPermsPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcPermsPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcPermsPeer::DATABASE_NAME, CcPermsPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcPerms - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcPermsPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcPermsPeer::DATABASE_NAME); - $criteria->add(CcPermsPeer::PERMID, $pk); - - $v = CcPermsPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPermsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcPermsPeer::DATABASE_NAME); - $criteria->add(CcPermsPeer::PERMID, $pks, Criteria::IN); - $objs = CcPermsPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcPermsPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcPermsPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPermsQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPermsQuery.php deleted file mode 100644 index f78dfb99e..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPermsQuery.php +++ /dev/null @@ -1,355 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcPerms|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcPermsPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcPermsPeer::PERMID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcPermsPeer::PERMID, $keys, Criteria::IN); - } - - /** - * Filter the query on the permid column - * - * @param int|array $permid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByPermid($permid = null, $comparison = null) - { - if (is_array($permid) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcPermsPeer::PERMID, $permid, $comparison); - } - - /** - * Filter the query on the subj column - * - * @param int|array $subj The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterBySubj($subj = null, $comparison = null) - { - if (is_array($subj)) { - $useMinMax = false; - if (isset($subj['min'])) { - $this->addUsingAlias(CcPermsPeer::SUBJ, $subj['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($subj['max'])) { - $this->addUsingAlias(CcPermsPeer::SUBJ, $subj['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPermsPeer::SUBJ, $subj, $comparison); - } - - /** - * Filter the query on the action column - * - * @param string $action The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByAction($action = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($action)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $action)) { - $action = str_replace('*', '%', $action); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPermsPeer::ACTION, $action, $comparison); - } - - /** - * Filter the query on the obj column - * - * @param int|array $obj The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByObj($obj = null, $comparison = null) - { - if (is_array($obj)) { - $useMinMax = false; - if (isset($obj['min'])) { - $this->addUsingAlias(CcPermsPeer::OBJ, $obj['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($obj['max'])) { - $this->addUsingAlias(CcPermsPeer::OBJ, $obj['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPermsPeer::OBJ, $obj, $comparison); - } - - /** - * Filter the query on the type column - * - * @param string $type The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByType($type = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($type)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $type)) { - $type = str_replace('*', '%', $type); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPermsPeer::TYPE, $type, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcPermsPeer::SUBJ, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Exclude object from result - * - * @param CcPerms $ccPerms Object to remove from the list of results - * - * @return CcPermsQuery The current query, for fluid interface - */ - public function prune($ccPerms = null) - { - if ($ccPerms) { - $this->addUsingAlias(CcPermsPeer::PERMID, $ccPerms->getPermid(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcPermsQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylist.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylist.php deleted file mode 100644 index 295060730..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylist.php +++ /dev/null @@ -1,1365 +0,0 @@ -name = ''; - $this->state = 'empty'; - $this->currentlyaccessing = 0; - } - - /** - * Initializes internal state of BaseCcPlaylist object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getDbId() - { - return $this->id; - } - - /** - * Get the [name] column value. - * - * @return string - */ - public function getDbName() - { - return $this->name; - } - - /** - * Get the [state] column value. - * - * @return string - */ - public function getDbState() - { - return $this->state; - } - - /** - * Get the [currentlyaccessing] column value. - * - * @return int - */ - public function getDbCurrentlyaccessing() - { - return $this->currentlyaccessing; - } - - /** - * Get the [editedby] column value. - * - * @return int - */ - public function getDbEditedby() - { - return $this->editedby; - } - - /** - * Get the [optionally formatted] temporal [mtime] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbMtime($format = 'Y-m-d H:i:s') - { - if ($this->mtime === null) { - return null; - } - - - - try { - $dt = new DateTime($this->mtime); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->mtime, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [creator] column value. - * - * @return string - */ - public function getDbCreator() - { - return $this->creator; - } - - /** - * Get the [description] column value. - * - * @return string - */ - public function getDbDescription() - { - return $this->description; - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcPlaylistPeer::ID; - } - - return $this; - } // setDbId() - - /** - * Set the value of [name] column. - * - * @param string $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbName($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->name !== $v || $this->isNew()) { - $this->name = $v; - $this->modifiedColumns[] = CcPlaylistPeer::NAME; - } - - return $this; - } // setDbName() - - /** - * Set the value of [state] column. - * - * @param string $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbState($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->state !== $v || $this->isNew()) { - $this->state = $v; - $this->modifiedColumns[] = CcPlaylistPeer::STATE; - } - - return $this; - } // setDbState() - - /** - * Set the value of [currentlyaccessing] column. - * - * @param int $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbCurrentlyaccessing($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->currentlyaccessing !== $v || $this->isNew()) { - $this->currentlyaccessing = $v; - $this->modifiedColumns[] = CcPlaylistPeer::CURRENTLYACCESSING; - } - - return $this; - } // setDbCurrentlyaccessing() - - /** - * Set the value of [editedby] column. - * - * @param int $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbEditedby($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->editedby !== $v) { - $this->editedby = $v; - $this->modifiedColumns[] = CcPlaylistPeer::EDITEDBY; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setDbEditedby() - - /** - * Sets the value of [mtime] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbMtime($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->mtime !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->mtime !== null && $tmpDt = new DateTime($this->mtime)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->mtime = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcPlaylistPeer::MTIME; - } - } // if either are not null - - return $this; - } // setDbMtime() - - /** - * Set the value of [creator] column. - * - * @param string $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbCreator($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->creator !== $v) { - $this->creator = $v; - $this->modifiedColumns[] = CcPlaylistPeer::CREATOR; - } - - return $this; - } // setDbCreator() - - /** - * Set the value of [description] column. - * - * @param string $v new value - * @return CcPlaylist The current object (for fluent API support) - */ - public function setDbDescription($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->description !== $v) { - $this->description = $v; - $this->modifiedColumns[] = CcPlaylistPeer::DESCRIPTION; - } - - return $this; - } // setDbDescription() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->name !== '') { - return false; - } - - if ($this->state !== 'empty') { - return false; - } - - if ($this->currentlyaccessing !== 0) { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->name = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->state = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->currentlyaccessing = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null; - $this->editedby = ($row[$startcol + 4] !== null) ? (int) $row[$startcol + 4] : null; - $this->mtime = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->creator = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->description = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 8; // 8 = CcPlaylistPeer::NUM_COLUMNS - CcPlaylistPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcPlaylist object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->editedby !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcPlaylistPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - $this->collCcPlaylistcontentss = null; - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcPlaylistQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcPlaylistPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcPlaylistPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcPlaylistPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPlaylistPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setDbId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows += CcPlaylistPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - if ($this->collCcPlaylistcontentss !== null) { - foreach ($this->collCcPlaylistcontentss as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcPlaylistPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - if ($this->collCcPlaylistcontentss !== null) { - foreach ($this->collCcPlaylistcontentss as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPlaylistPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getDbId(); - break; - case 1: - return $this->getDbName(); - break; - case 2: - return $this->getDbState(); - break; - case 3: - return $this->getDbCurrentlyaccessing(); - break; - case 4: - return $this->getDbEditedby(); - break; - case 5: - return $this->getDbMtime(); - break; - case 6: - return $this->getDbCreator(); - break; - case 7: - return $this->getDbDescription(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcPlaylistPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getDbId(), - $keys[1] => $this->getDbName(), - $keys[2] => $this->getDbState(), - $keys[3] => $this->getDbCurrentlyaccessing(), - $keys[4] => $this->getDbEditedby(), - $keys[5] => $this->getDbMtime(), - $keys[6] => $this->getDbCreator(), - $keys[7] => $this->getDbDescription(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPlaylistPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setDbId($value); - break; - case 1: - $this->setDbName($value); - break; - case 2: - $this->setDbState($value); - break; - case 3: - $this->setDbCurrentlyaccessing($value); - break; - case 4: - $this->setDbEditedby($value); - break; - case 5: - $this->setDbMtime($value); - break; - case 6: - $this->setDbCreator($value); - break; - case 7: - $this->setDbDescription($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcPlaylistPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setDbId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setDbName($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setDbState($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setDbCurrentlyaccessing($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setDbEditedby($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setDbMtime($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setDbCreator($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setDbDescription($arr[$keys[7]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcPlaylistPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcPlaylistPeer::ID)) $criteria->add(CcPlaylistPeer::ID, $this->id); - if ($this->isColumnModified(CcPlaylistPeer::NAME)) $criteria->add(CcPlaylistPeer::NAME, $this->name); - if ($this->isColumnModified(CcPlaylistPeer::STATE)) $criteria->add(CcPlaylistPeer::STATE, $this->state); - if ($this->isColumnModified(CcPlaylistPeer::CURRENTLYACCESSING)) $criteria->add(CcPlaylistPeer::CURRENTLYACCESSING, $this->currentlyaccessing); - if ($this->isColumnModified(CcPlaylistPeer::EDITEDBY)) $criteria->add(CcPlaylistPeer::EDITEDBY, $this->editedby); - if ($this->isColumnModified(CcPlaylistPeer::MTIME)) $criteria->add(CcPlaylistPeer::MTIME, $this->mtime); - if ($this->isColumnModified(CcPlaylistPeer::CREATOR)) $criteria->add(CcPlaylistPeer::CREATOR, $this->creator); - if ($this->isColumnModified(CcPlaylistPeer::DESCRIPTION)) $criteria->add(CcPlaylistPeer::DESCRIPTION, $this->description); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcPlaylistPeer::DATABASE_NAME); - $criteria->add(CcPlaylistPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getDbId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setDbId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getDbId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcPlaylist (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setDbName($this->name); - $copyObj->setDbState($this->state); - $copyObj->setDbCurrentlyaccessing($this->currentlyaccessing); - $copyObj->setDbEditedby($this->editedby); - $copyObj->setDbMtime($this->mtime); - $copyObj->setDbCreator($this->creator); - $copyObj->setDbDescription($this->description); - - if ($deepCopy) { - // important: temporarily setNew(false) because this affects the behavior of - // the getter/setter methods for fkey referrer objects. - $copyObj->setNew(false); - - foreach ($this->getCcPlaylistcontentss() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcPlaylistcontents($relObj->copy($deepCopy)); - } - } - - } // if ($deepCopy) - - - $copyObj->setNew(true); - $copyObj->setDbId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcPlaylist Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcPlaylistPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcPlaylistPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcPlaylist The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setDbEditedby(NULL); - } else { - $this->setDbEditedby($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcPlaylist($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->editedby !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->editedby, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcPlaylists($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears out the collCcPlaylistcontentss collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcPlaylistcontentss() - */ - public function clearCcPlaylistcontentss() - { - $this->collCcPlaylistcontentss = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcPlaylistcontentss collection. - * - * By default this just sets the collCcPlaylistcontentss collection to an empty array (like clearcollCcPlaylistcontentss()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcPlaylistcontentss() - { - $this->collCcPlaylistcontentss = new PropelObjectCollection(); - $this->collCcPlaylistcontentss->setModel('CcPlaylistcontents'); - } - - /** - * Gets an array of CcPlaylistcontents objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcPlaylist is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcPlaylistcontents[] List of CcPlaylistcontents objects - * @throws PropelException - */ - public function getCcPlaylistcontentss($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcPlaylistcontentss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylistcontentss) { - // return empty collection - $this->initCcPlaylistcontentss(); - } else { - $collCcPlaylistcontentss = CcPlaylistcontentsQuery::create(null, $criteria) - ->filterByCcPlaylist($this) - ->find($con); - if (null !== $criteria) { - return $collCcPlaylistcontentss; - } - $this->collCcPlaylistcontentss = $collCcPlaylistcontentss; - } - } - return $this->collCcPlaylistcontentss; - } - - /** - * Returns the number of related CcPlaylistcontents objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcPlaylistcontents objects. - * @throws PropelException - */ - public function countCcPlaylistcontentss(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcPlaylistcontentss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylistcontentss) { - return 0; - } else { - $query = CcPlaylistcontentsQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcPlaylist($this) - ->count($con); - } - } else { - return count($this->collCcPlaylistcontentss); - } - } - - /** - * Method called to associate a CcPlaylistcontents object to this object - * through the CcPlaylistcontents foreign key attribute. - * - * @param CcPlaylistcontents $l CcPlaylistcontents - * @return void - * @throws PropelException - */ - public function addCcPlaylistcontents(CcPlaylistcontents $l) - { - if ($this->collCcPlaylistcontentss === null) { - $this->initCcPlaylistcontentss(); - } - if (!$this->collCcPlaylistcontentss->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcPlaylistcontentss[]= $l; - $l->setCcPlaylist($this); - } - } - - - /** - * If this collection has already been initialized with - * an identical criteria, it returns the collection. - * Otherwise if this CcPlaylist is new, it will return - * an empty collection; or if this CcPlaylist has previously - * been saved, it will retrieve related CcPlaylistcontentss from storage. - * - * This method is protected by default in order to keep the public - * api reasonable. You can provide public methods for those you - * actually need in CcPlaylist. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return PropelCollection|array CcPlaylistcontents[] List of CcPlaylistcontents objects - */ - public function getCcPlaylistcontentssJoinCcFiles($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $query = CcPlaylistcontentsQuery::create(null, $criteria); - $query->joinWith('CcFiles', $join_behavior); - - return $this->getCcPlaylistcontentss($query, $con); - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->name = null; - $this->state = null; - $this->currentlyaccessing = null; - $this->editedby = null; - $this->mtime = null; - $this->creator = null; - $this->description = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - if ($this->collCcPlaylistcontentss) { - foreach ((array) $this->collCcPlaylistcontentss as $o) { - $o->clearAllReferences($deep); - } - } - } // if ($deep) - - $this->collCcPlaylistcontentss = null; - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcPlaylist diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistPeer.php deleted file mode 100644 index 04ff4a612..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistPeer.php +++ /dev/null @@ -1,1006 +0,0 @@ - array ('DbId', 'DbName', 'DbState', 'DbCurrentlyaccessing', 'DbEditedby', 'DbMtime', 'DbCreator', 'DbDescription', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbState', 'dbCurrentlyaccessing', 'dbEditedby', 'dbMtime', 'dbCreator', 'dbDescription', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::NAME, self::STATE, self::CURRENTLYACCESSING, self::EDITEDBY, self::MTIME, self::CREATOR, self::DESCRIPTION, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'STATE', 'CURRENTLYACCESSING', 'EDITEDBY', 'MTIME', 'CREATOR', 'DESCRIPTION', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'state', 'currentlyaccessing', 'editedby', 'mtime', 'creator', 'description', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbState' => 2, 'DbCurrentlyaccessing' => 3, 'DbEditedby' => 4, 'DbMtime' => 5, 'DbCreator' => 6, 'DbDescription' => 7, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbState' => 2, 'dbCurrentlyaccessing' => 3, 'dbEditedby' => 4, 'dbMtime' => 5, 'dbCreator' => 6, 'dbDescription' => 7, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::NAME => 1, self::STATE => 2, self::CURRENTLYACCESSING => 3, self::EDITEDBY => 4, self::MTIME => 5, self::CREATOR => 6, self::DESCRIPTION => 7, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'STATE' => 2, 'CURRENTLYACCESSING' => 3, 'EDITEDBY' => 4, 'MTIME' => 5, 'CREATOR' => 6, 'DESCRIPTION' => 7, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'state' => 2, 'currentlyaccessing' => 3, 'editedby' => 4, 'mtime' => 5, 'creator' => 6, 'description' => 7, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcPlaylistPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcPlaylistPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcPlaylistPeer::ID); - $criteria->addSelectColumn(CcPlaylistPeer::NAME); - $criteria->addSelectColumn(CcPlaylistPeer::STATE); - $criteria->addSelectColumn(CcPlaylistPeer::CURRENTLYACCESSING); - $criteria->addSelectColumn(CcPlaylistPeer::EDITEDBY); - $criteria->addSelectColumn(CcPlaylistPeer::MTIME); - $criteria->addSelectColumn(CcPlaylistPeer::CREATOR); - $criteria->addSelectColumn(CcPlaylistPeer::DESCRIPTION); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.NAME'); - $criteria->addSelectColumn($alias . '.STATE'); - $criteria->addSelectColumn($alias . '.CURRENTLYACCESSING'); - $criteria->addSelectColumn($alias . '.EDITEDBY'); - $criteria->addSelectColumn($alias . '.MTIME'); - $criteria->addSelectColumn($alias . '.CREATOR'); - $criteria->addSelectColumn($alias . '.DESCRIPTION'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcPlaylist - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcPlaylistPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcPlaylistPeer::populateObjects(CcPlaylistPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcPlaylistPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcPlaylist $value A CcPlaylist object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcPlaylist $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getDbId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcPlaylist object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcPlaylist) { - $key = (string) $value->getDbId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcPlaylist object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcPlaylist Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_playlist - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - // Invalidate objects in CcPlaylistcontentsPeer instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - CcPlaylistcontentsPeer::clearInstancePool(); - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcPlaylistPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcPlaylistPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcPlaylistPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcPlaylist object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcPlaylistPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcPlaylistPeer::NUM_COLUMNS; - } else { - $cls = CcPlaylistPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcPlaylistPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcPlaylist objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylist objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistPeer::addSelectColumns($criteria); - $startcol = (CcPlaylistPeer::NUM_COLUMNS - CcPlaylistPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcPlaylistPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcPlaylistPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcPlaylist) to $obj2 (CcSubjs) - $obj2->addCcPlaylist($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcPlaylist objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylist objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistPeer::addSelectColumns($criteria); - $startcol2 = (CcPlaylistPeer::NUM_COLUMNS - CcPlaylistPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPlaylistPeer::EDITEDBY, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPlaylistPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcPlaylist) to the collection in $obj2 (CcSubjs) - $obj2->addCcPlaylist($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcPlaylistPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcPlaylistPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcPlaylistTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcPlaylistPeer::CLASS_DEFAULT : CcPlaylistPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcPlaylist or Criteria object. - * - * @param mixed $values Criteria or CcPlaylist object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcPlaylist object - } - - if ($criteria->containsKey(CcPlaylistPeer::ID) && $criteria->keyContainsValue(CcPlaylistPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPlaylistPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcPlaylist or Criteria object. - * - * @param mixed $values Criteria or CcPlaylist object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcPlaylistPeer::ID); - $value = $criteria->remove(CcPlaylistPeer::ID); - if ($value) { - $selectCriteria->add(CcPlaylistPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcPlaylistPeer::TABLE_NAME); - } - - } else { // $values is CcPlaylist object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_playlist table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcPlaylistPeer::TABLE_NAME, $con, CcPlaylistPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcPlaylistPeer::clearInstancePool(); - CcPlaylistPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcPlaylist or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcPlaylist object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcPlaylistPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcPlaylist) { // it's a model object - // invalidate the cache for this single object - CcPlaylistPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcPlaylistPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcPlaylistPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcPlaylistPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcPlaylist object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcPlaylist $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcPlaylist $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcPlaylistPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcPlaylistPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcPlaylistPeer::DATABASE_NAME, CcPlaylistPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcPlaylist - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcPlaylistPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcPlaylistPeer::DATABASE_NAME); - $criteria->add(CcPlaylistPeer::ID, $pk); - - $v = CcPlaylistPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcPlaylistPeer::DATABASE_NAME); - $criteria->add(CcPlaylistPeer::ID, $pks, Criteria::IN); - $objs = CcPlaylistPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcPlaylistPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcPlaylistPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistQuery.php deleted file mode 100644 index 237be4312..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistQuery.php +++ /dev/null @@ -1,510 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcPlaylist|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcPlaylistPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcPlaylistPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcPlaylistPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $dbId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbId($dbId = null, $comparison = null) - { - if (is_array($dbId) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcPlaylistPeer::ID, $dbId, $comparison); - } - - /** - * Filter the query on the name column - * - * @param string $dbName The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbName($dbName = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($dbName)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $dbName)) { - $dbName = str_replace('*', '%', $dbName); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPlaylistPeer::NAME, $dbName, $comparison); - } - - /** - * Filter the query on the state column - * - * @param string $dbState The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbState($dbState = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($dbState)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $dbState)) { - $dbState = str_replace('*', '%', $dbState); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPlaylistPeer::STATE, $dbState, $comparison); - } - - /** - * Filter the query on the currentlyaccessing column - * - * @param int|array $dbCurrentlyaccessing The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbCurrentlyaccessing($dbCurrentlyaccessing = null, $comparison = null) - { - if (is_array($dbCurrentlyaccessing)) { - $useMinMax = false; - if (isset($dbCurrentlyaccessing['min'])) { - $this->addUsingAlias(CcPlaylistPeer::CURRENTLYACCESSING, $dbCurrentlyaccessing['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbCurrentlyaccessing['max'])) { - $this->addUsingAlias(CcPlaylistPeer::CURRENTLYACCESSING, $dbCurrentlyaccessing['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistPeer::CURRENTLYACCESSING, $dbCurrentlyaccessing, $comparison); - } - - /** - * Filter the query on the editedby column - * - * @param int|array $dbEditedby The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbEditedby($dbEditedby = null, $comparison = null) - { - if (is_array($dbEditedby)) { - $useMinMax = false; - if (isset($dbEditedby['min'])) { - $this->addUsingAlias(CcPlaylistPeer::EDITEDBY, $dbEditedby['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbEditedby['max'])) { - $this->addUsingAlias(CcPlaylistPeer::EDITEDBY, $dbEditedby['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistPeer::EDITEDBY, $dbEditedby, $comparison); - } - - /** - * Filter the query on the mtime column - * - * @param string|array $dbMtime The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbMtime($dbMtime = null, $comparison = null) - { - if (is_array($dbMtime)) { - $useMinMax = false; - if (isset($dbMtime['min'])) { - $this->addUsingAlias(CcPlaylistPeer::MTIME, $dbMtime['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbMtime['max'])) { - $this->addUsingAlias(CcPlaylistPeer::MTIME, $dbMtime['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistPeer::MTIME, $dbMtime, $comparison); - } - - /** - * Filter the query on the creator column - * - * @param string $dbCreator The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbCreator($dbCreator = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($dbCreator)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $dbCreator)) { - $dbCreator = str_replace('*', '%', $dbCreator); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPlaylistPeer::CREATOR, $dbCreator, $comparison); - } - - /** - * Filter the query on the description column - * - * @param string $dbDescription The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByDbDescription($dbDescription = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($dbDescription)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $dbDescription)) { - $dbDescription = str_replace('*', '%', $dbDescription); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPlaylistPeer::DESCRIPTION, $dbDescription, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcPlaylistPeer::EDITEDBY, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Filter the query by a related CcPlaylistcontents object - * - * @param CcPlaylistcontents $ccPlaylistcontents the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function filterByCcPlaylistcontents($ccPlaylistcontents, $comparison = null) - { - return $this - ->addUsingAlias(CcPlaylistPeer::ID, $ccPlaylistcontents->getDbPlaylistId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPlaylistcontents relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function joinCcPlaylistcontents($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPlaylistcontents'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPlaylistcontents'); - } - - return $this; - } - - /** - * Use the CcPlaylistcontents relation CcPlaylistcontents object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistcontentsQuery A secondary query class using the current class as primary query - */ - public function useCcPlaylistcontentsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPlaylistcontents($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPlaylistcontents', 'CcPlaylistcontentsQuery'); - } - - /** - * Exclude object from result - * - * @param CcPlaylist $ccPlaylist Object to remove from the list of results - * - * @return CcPlaylistQuery The current query, for fluid interface - */ - public function prune($ccPlaylist = null) - { - if ($ccPlaylist) { - $this->addUsingAlias(CcPlaylistPeer::ID, $ccPlaylist->getDbId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcPlaylistQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontents.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontents.php deleted file mode 100644 index 53ff5fe8d..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontents.php +++ /dev/null @@ -1,1540 +0,0 @@ -cliplength = '00:00:00'; - $this->cuein = '00:00:00'; - $this->cueout = '00:00:00'; - $this->fadein = '00:00:00'; - $this->fadeout = '00:00:00'; - } - - /** - * Initializes internal state of BaseCcPlaylistcontents object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getDbId() - { - return $this->id; - } - - /** - * Get the [playlist_id] column value. - * - * @return int - */ - public function getDbPlaylistId() - { - return $this->playlist_id; - } - - /** - * Get the [file_id] column value. - * - * @return int - */ - public function getDbFileId() - { - return $this->file_id; - } - - /** - * Get the [position] column value. - * - * @return int - */ - public function getDbPosition() - { - return $this->position; - } - - /** - * Get the [optionally formatted] temporal [cliplength] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbCliplength($format = '%X') - { - if ($this->cliplength === null) { - return null; - } - - - - try { - $dt = new DateTime($this->cliplength); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cliplength, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [cuein] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbCuein($format = '%X') - { - if ($this->cuein === null) { - return null; - } - - - - try { - $dt = new DateTime($this->cuein); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cuein, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [cueout] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbCueout($format = '%X') - { - if ($this->cueout === null) { - return null; - } - - - - try { - $dt = new DateTime($this->cueout); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cueout, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [fadein] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbFadein($format = '%X') - { - if ($this->fadein === null) { - return null; - } - - - - try { - $dt = new DateTime($this->fadein); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->fadein, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [fadeout] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getDbFadeout($format = '%X') - { - if ($this->fadeout === null) { - return null; - } - - - - try { - $dt = new DateTime($this->fadeout); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->fadeout, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcPlaylistcontentsPeer::ID; - } - - return $this; - } // setDbId() - - /** - * Set the value of [playlist_id] column. - * - * @param int $v new value - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbPlaylistId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->playlist_id !== $v) { - $this->playlist_id = $v; - $this->modifiedColumns[] = CcPlaylistcontentsPeer::PLAYLIST_ID; - } - - if ($this->aCcPlaylist !== null && $this->aCcPlaylist->getDbId() !== $v) { - $this->aCcPlaylist = null; - } - - return $this; - } // setDbPlaylistId() - - /** - * Set the value of [file_id] column. - * - * @param int $v new value - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbFileId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->file_id !== $v) { - $this->file_id = $v; - $this->modifiedColumns[] = CcPlaylistcontentsPeer::FILE_ID; - } - - if ($this->aCcFiles !== null && $this->aCcFiles->getDbId() !== $v) { - $this->aCcFiles = null; - } - - return $this; - } // setDbFileId() - - /** - * Set the value of [position] column. - * - * @param int $v new value - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbPosition($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->position !== $v) { - $this->position = $v; - $this->modifiedColumns[] = CcPlaylistcontentsPeer::POSITION; - } - - return $this; - } // setDbPosition() - - /** - * Sets the value of [cliplength] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbCliplength($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->cliplength !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->cliplength !== null && $tmpDt = new DateTime($this->cliplength)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->cliplength = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcPlaylistcontentsPeer::CLIPLENGTH; - } - } // if either are not null - - return $this; - } // setDbCliplength() - - /** - * Sets the value of [cuein] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbCuein($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->cuein !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->cuein !== null && $tmpDt = new DateTime($this->cuein)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->cuein = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEIN; - } - } // if either are not null - - return $this; - } // setDbCuein() - - /** - * Sets the value of [cueout] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbCueout($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->cueout !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->cueout !== null && $tmpDt = new DateTime($this->cueout)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->cueout = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEOUT; - } - } // if either are not null - - return $this; - } // setDbCueout() - - /** - * Sets the value of [fadein] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbFadein($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->fadein !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->fadein !== null && $tmpDt = new DateTime($this->fadein)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->fadein = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEIN; - } - } // if either are not null - - return $this; - } // setDbFadein() - - /** - * Sets the value of [fadeout] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcPlaylistcontents The current object (for fluent API support) - */ - public function setDbFadeout($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->fadeout !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->fadeout !== null && $tmpDt = new DateTime($this->fadeout)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->fadeout = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEOUT; - } - } // if either are not null - - return $this; - } // setDbFadeout() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->cliplength !== '00:00:00') { - return false; - } - - if ($this->cuein !== '00:00:00') { - return false; - } - - if ($this->cueout !== '00:00:00') { - return false; - } - - if ($this->fadein !== '00:00:00') { - return false; - } - - if ($this->fadeout !== '00:00:00') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->playlist_id = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->file_id = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null; - $this->position = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null; - $this->cliplength = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->cuein = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->cueout = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->fadein = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null; - $this->fadeout = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 9; // 9 = CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcPlaylistcontents object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcPlaylist !== null && $this->playlist_id !== $this->aCcPlaylist->getDbId()) { - $this->aCcPlaylist = null; - } - if ($this->aCcFiles !== null && $this->file_id !== $this->aCcFiles->getDbId()) { - $this->aCcFiles = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcPlaylistcontentsPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcFiles = null; - $this->aCcPlaylist = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcPlaylistcontentsQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcPlaylistcontentsPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcFiles !== null) { - if ($this->aCcFiles->isModified() || $this->aCcFiles->isNew()) { - $affectedRows += $this->aCcFiles->save($con); - } - $this->setCcFiles($this->aCcFiles); - } - - if ($this->aCcPlaylist !== null) { - if ($this->aCcPlaylist->isModified() || $this->aCcPlaylist->isNew()) { - $affectedRows += $this->aCcPlaylist->save($con); - } - $this->setCcPlaylist($this->aCcPlaylist); - } - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcPlaylistcontentsPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcPlaylistcontentsPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPlaylistcontentsPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setDbId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows += CcPlaylistcontentsPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcFiles !== null) { - if (!$this->aCcFiles->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcFiles->getValidationFailures()); - } - } - - if ($this->aCcPlaylist !== null) { - if (!$this->aCcPlaylist->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcPlaylist->getValidationFailures()); - } - } - - - if (($retval = CcPlaylistcontentsPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPlaylistcontentsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getDbId(); - break; - case 1: - return $this->getDbPlaylistId(); - break; - case 2: - return $this->getDbFileId(); - break; - case 3: - return $this->getDbPosition(); - break; - case 4: - return $this->getDbCliplength(); - break; - case 5: - return $this->getDbCuein(); - break; - case 6: - return $this->getDbCueout(); - break; - case 7: - return $this->getDbFadein(); - break; - case 8: - return $this->getDbFadeout(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcPlaylistcontentsPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getDbId(), - $keys[1] => $this->getDbPlaylistId(), - $keys[2] => $this->getDbFileId(), - $keys[3] => $this->getDbPosition(), - $keys[4] => $this->getDbCliplength(), - $keys[5] => $this->getDbCuein(), - $keys[6] => $this->getDbCueout(), - $keys[7] => $this->getDbFadein(), - $keys[8] => $this->getDbFadeout(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcFiles) { - $result['CcFiles'] = $this->aCcFiles->toArray($keyType, $includeLazyLoadColumns, true); - } - if (null !== $this->aCcPlaylist) { - $result['CcPlaylist'] = $this->aCcPlaylist->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPlaylistcontentsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setDbId($value); - break; - case 1: - $this->setDbPlaylistId($value); - break; - case 2: - $this->setDbFileId($value); - break; - case 3: - $this->setDbPosition($value); - break; - case 4: - $this->setDbCliplength($value); - break; - case 5: - $this->setDbCuein($value); - break; - case 6: - $this->setDbCueout($value); - break; - case 7: - $this->setDbFadein($value); - break; - case 8: - $this->setDbFadeout($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcPlaylistcontentsPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setDbId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setDbPlaylistId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setDbFileId($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setDbPosition($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setDbCliplength($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setDbCuein($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setDbCueout($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setDbFadein($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setDbFadeout($arr[$keys[8]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcPlaylistcontentsPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcPlaylistcontentsPeer::ID)) $criteria->add(CcPlaylistcontentsPeer::ID, $this->id); - if ($this->isColumnModified(CcPlaylistcontentsPeer::PLAYLIST_ID)) $criteria->add(CcPlaylistcontentsPeer::PLAYLIST_ID, $this->playlist_id); - if ($this->isColumnModified(CcPlaylistcontentsPeer::FILE_ID)) $criteria->add(CcPlaylistcontentsPeer::FILE_ID, $this->file_id); - if ($this->isColumnModified(CcPlaylistcontentsPeer::POSITION)) $criteria->add(CcPlaylistcontentsPeer::POSITION, $this->position); - if ($this->isColumnModified(CcPlaylistcontentsPeer::CLIPLENGTH)) $criteria->add(CcPlaylistcontentsPeer::CLIPLENGTH, $this->cliplength); - if ($this->isColumnModified(CcPlaylistcontentsPeer::CUEIN)) $criteria->add(CcPlaylistcontentsPeer::CUEIN, $this->cuein); - if ($this->isColumnModified(CcPlaylistcontentsPeer::CUEOUT)) $criteria->add(CcPlaylistcontentsPeer::CUEOUT, $this->cueout); - if ($this->isColumnModified(CcPlaylistcontentsPeer::FADEIN)) $criteria->add(CcPlaylistcontentsPeer::FADEIN, $this->fadein); - if ($this->isColumnModified(CcPlaylistcontentsPeer::FADEOUT)) $criteria->add(CcPlaylistcontentsPeer::FADEOUT, $this->fadeout); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcPlaylistcontentsPeer::DATABASE_NAME); - $criteria->add(CcPlaylistcontentsPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getDbId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setDbId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getDbId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcPlaylistcontents (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setDbPlaylistId($this->playlist_id); - $copyObj->setDbFileId($this->file_id); - $copyObj->setDbPosition($this->position); - $copyObj->setDbCliplength($this->cliplength); - $copyObj->setDbCuein($this->cuein); - $copyObj->setDbCueout($this->cueout); - $copyObj->setDbFadein($this->fadein); - $copyObj->setDbFadeout($this->fadeout); - - $copyObj->setNew(true); - $copyObj->setDbId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcPlaylistcontents Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcPlaylistcontentsPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcPlaylistcontentsPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcFiles object. - * - * @param CcFiles $v - * @return CcPlaylistcontents The current object (for fluent API support) - * @throws PropelException - */ - public function setCcFiles(CcFiles $v = null) - { - if ($v === null) { - $this->setDbFileId(NULL); - } else { - $this->setDbFileId($v->getDbId()); - } - - $this->aCcFiles = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcFiles object, it will not be re-added. - if ($v !== null) { - $v->addCcPlaylistcontents($this); - } - - return $this; - } - - - /** - * Get the associated CcFiles object - * - * @param PropelPDO Optional Connection object. - * @return CcFiles The associated CcFiles object. - * @throws PropelException - */ - public function getCcFiles(PropelPDO $con = null) - { - if ($this->aCcFiles === null && ($this->file_id !== null)) { - $this->aCcFiles = CcFilesQuery::create()->findPk($this->file_id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcFiles->addCcPlaylistcontentss($this); - */ - } - return $this->aCcFiles; - } - - /** - * Declares an association between this object and a CcPlaylist object. - * - * @param CcPlaylist $v - * @return CcPlaylistcontents The current object (for fluent API support) - * @throws PropelException - */ - public function setCcPlaylist(CcPlaylist $v = null) - { - if ($v === null) { - $this->setDbPlaylistId(NULL); - } else { - $this->setDbPlaylistId($v->getDbId()); - } - - $this->aCcPlaylist = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcPlaylist object, it will not be re-added. - if ($v !== null) { - $v->addCcPlaylistcontents($this); - } - - return $this; - } - - - /** - * Get the associated CcPlaylist object - * - * @param PropelPDO Optional Connection object. - * @return CcPlaylist The associated CcPlaylist object. - * @throws PropelException - */ - public function getCcPlaylist(PropelPDO $con = null) - { - if ($this->aCcPlaylist === null && ($this->playlist_id !== null)) { - $this->aCcPlaylist = CcPlaylistQuery::create()->findPk($this->playlist_id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcPlaylist->addCcPlaylistcontentss($this); - */ - } - return $this->aCcPlaylist; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->playlist_id = null; - $this->file_id = null; - $this->position = null; - $this->cliplength = null; - $this->cuein = null; - $this->cueout = null; - $this->fadein = null; - $this->fadeout = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aCcFiles = null; - $this->aCcPlaylist = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcPlaylistcontents diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsPeer.php deleted file mode 100644 index 1d448bd34..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsPeer.php +++ /dev/null @@ -1,1395 +0,0 @@ - array ('DbId', 'DbPlaylistId', 'DbFileId', 'DbPosition', 'DbCliplength', 'DbCuein', 'DbCueout', 'DbFadein', 'DbFadeout', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbPlaylistId', 'dbFileId', 'dbPosition', 'dbCliplength', 'dbCuein', 'dbCueout', 'dbFadein', 'dbFadeout', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::PLAYLIST_ID, self::FILE_ID, self::POSITION, self::CLIPLENGTH, self::CUEIN, self::CUEOUT, self::FADEIN, self::FADEOUT, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'PLAYLIST_ID', 'FILE_ID', 'POSITION', 'CLIPLENGTH', 'CUEIN', 'CUEOUT', 'FADEIN', 'FADEOUT', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'playlist_id', 'file_id', 'position', 'cliplength', 'cuein', 'cueout', 'fadein', 'fadeout', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbPlaylistId' => 1, 'DbFileId' => 2, 'DbPosition' => 3, 'DbCliplength' => 4, 'DbCuein' => 5, 'DbCueout' => 6, 'DbFadein' => 7, 'DbFadeout' => 8, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbPlaylistId' => 1, 'dbFileId' => 2, 'dbPosition' => 3, 'dbCliplength' => 4, 'dbCuein' => 5, 'dbCueout' => 6, 'dbFadein' => 7, 'dbFadeout' => 8, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::PLAYLIST_ID => 1, self::FILE_ID => 2, self::POSITION => 3, self::CLIPLENGTH => 4, self::CUEIN => 5, self::CUEOUT => 6, self::FADEIN => 7, self::FADEOUT => 8, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'PLAYLIST_ID' => 1, 'FILE_ID' => 2, 'POSITION' => 3, 'CLIPLENGTH' => 4, 'CUEIN' => 5, 'CUEOUT' => 6, 'FADEIN' => 7, 'FADEOUT' => 8, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'playlist_id' => 1, 'file_id' => 2, 'position' => 3, 'cliplength' => 4, 'cuein' => 5, 'cueout' => 6, 'fadein' => 7, 'fadeout' => 8, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcPlaylistcontentsPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcPlaylistcontentsPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcPlaylistcontentsPeer::ID); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::PLAYLIST_ID); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::FILE_ID); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::POSITION); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::CLIPLENGTH); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::CUEIN); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::CUEOUT); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::FADEIN); - $criteria->addSelectColumn(CcPlaylistcontentsPeer::FADEOUT); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.PLAYLIST_ID'); - $criteria->addSelectColumn($alias . '.FILE_ID'); - $criteria->addSelectColumn($alias . '.POSITION'); - $criteria->addSelectColumn($alias . '.CLIPLENGTH'); - $criteria->addSelectColumn($alias . '.CUEIN'); - $criteria->addSelectColumn($alias . '.CUEOUT'); - $criteria->addSelectColumn($alias . '.FADEIN'); - $criteria->addSelectColumn($alias . '.FADEOUT'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcPlaylistcontents - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcPlaylistcontentsPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcPlaylistcontentsPeer::populateObjects(CcPlaylistcontentsPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcPlaylistcontents $value A CcPlaylistcontents object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcPlaylistcontents $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getDbId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcPlaylistcontents object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcPlaylistcontents) { - $key = (string) $value->getDbId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcPlaylistcontents object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcPlaylistcontents Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_playlistcontents - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcPlaylistcontentsPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcPlaylistcontentsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcPlaylistcontentsPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcPlaylistcontents object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcPlaylistcontentsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcPlaylistcontentsPeer::NUM_COLUMNS; - } else { - $cls = CcPlaylistcontentsPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcPlaylistcontentsPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcFiles table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcFiles(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Returns the number of rows matching criteria, joining the related CcPlaylist table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcPlaylist(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcPlaylistcontents objects pre-filled with their CcFiles objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylistcontents objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcFiles(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistcontentsPeer::addSelectColumns($criteria); - $startcol = (CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS); - CcFilesPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistcontentsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcPlaylistcontentsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistcontentsPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcFilesPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcFilesPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcFilesPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcFilesPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcPlaylistcontents) to $obj2 (CcFiles) - $obj2->addCcPlaylistcontents($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Selects a collection of CcPlaylistcontents objects pre-filled with their CcPlaylist objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylistcontents objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcPlaylist(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistcontentsPeer::addSelectColumns($criteria); - $startcol = (CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS); - CcPlaylistPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistcontentsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcPlaylistcontentsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistcontentsPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcPlaylistPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcPlaylistPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcPlaylistPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcPlaylistcontents) to $obj2 (CcPlaylist) - $obj2->addCcPlaylistcontents($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcPlaylistcontents objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylistcontents objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistcontentsPeer::addSelectColumns($criteria); - $startcol2 = (CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS); - - CcFilesPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS); - - CcPlaylistPeer::addSelectColumns($criteria); - $startcol4 = $startcol3 + (CcPlaylistPeer::NUM_COLUMNS - CcPlaylistPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistcontentsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPlaylistcontentsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistcontentsPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcFiles rows - - $key2 = CcFilesPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcFilesPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcFilesPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcFilesPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcPlaylistcontents) to the collection in $obj2 (CcFiles) - $obj2->addCcPlaylistcontents($obj1); - } // if joined row not null - - // Add objects for joined CcPlaylist rows - - $key3 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol3); - if ($key3 !== null) { - $obj3 = CcPlaylistPeer::getInstanceFromPool($key3); - if (!$obj3) { - - $cls = CcPlaylistPeer::getOMClass(false); - - $obj3 = new $cls(); - $obj3->hydrate($row, $startcol3); - CcPlaylistPeer::addInstanceToPool($obj3, $key3); - } // if obj3 loaded - - // Add the $obj1 (CcPlaylistcontents) to the collection in $obj3 (CcPlaylist) - $obj3->addCcPlaylistcontents($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining the related CcFiles table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAllExceptCcFiles(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY should not affect count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Returns the number of rows matching criteria, joining the related CcPlaylist table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAllExceptCcPlaylist(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPlaylistcontentsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY should not affect count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcPlaylistcontents objects pre-filled with all related objects except CcFiles. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylistcontents objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAllExceptCcFiles(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - // $criteria->getDbName() will return the same object if not set to another value - // so == check is okay and faster - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistcontentsPeer::addSelectColumns($criteria); - $startcol2 = (CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS); - - CcPlaylistPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcPlaylistPeer::NUM_COLUMNS - CcPlaylistPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPlaylistcontentsPeer::PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior); - - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistcontentsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPlaylistcontentsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistcontentsPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcPlaylist rows - - $key2 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcPlaylistPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcPlaylistPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcPlaylistPeer::addInstanceToPool($obj2, $key2); - } // if $obj2 already loaded - - // Add the $obj1 (CcPlaylistcontents) to the collection in $obj2 (CcPlaylist) - $obj2->addCcPlaylistcontents($obj1); - - } // if joined row is not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Selects a collection of CcPlaylistcontents objects pre-filled with all related objects except CcPlaylist. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPlaylistcontents objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAllExceptCcPlaylist(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - // $criteria->getDbName() will return the same object if not set to another value - // so == check is okay and faster - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPlaylistcontentsPeer::addSelectColumns($criteria); - $startcol2 = (CcPlaylistcontentsPeer::NUM_COLUMNS - CcPlaylistcontentsPeer::NUM_LAZY_LOAD_COLUMNS); - - CcFilesPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPlaylistcontentsPeer::FILE_ID, CcFilesPeer::ID, $join_behavior); - - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPlaylistcontentsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPlaylistcontentsPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPlaylistcontentsPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPlaylistcontentsPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcFiles rows - - $key2 = CcFilesPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcFilesPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcFilesPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcFilesPeer::addInstanceToPool($obj2, $key2); - } // if $obj2 already loaded - - // Add the $obj1 (CcPlaylistcontents) to the collection in $obj2 (CcFiles) - $obj2->addCcPlaylistcontents($obj1); - - } // if joined row is not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcPlaylistcontentsPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcPlaylistcontentsPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcPlaylistcontentsTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcPlaylistcontentsPeer::CLASS_DEFAULT : CcPlaylistcontentsPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcPlaylistcontents or Criteria object. - * - * @param mixed $values Criteria or CcPlaylistcontents object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcPlaylistcontents object - } - - if ($criteria->containsKey(CcPlaylistcontentsPeer::ID) && $criteria->keyContainsValue(CcPlaylistcontentsPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPlaylistcontentsPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcPlaylistcontents or Criteria object. - * - * @param mixed $values Criteria or CcPlaylistcontents object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcPlaylistcontentsPeer::ID); - $value = $criteria->remove(CcPlaylistcontentsPeer::ID); - if ($value) { - $selectCriteria->add(CcPlaylistcontentsPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcPlaylistcontentsPeer::TABLE_NAME); - } - - } else { // $values is CcPlaylistcontents object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_playlistcontents table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcPlaylistcontentsPeer::TABLE_NAME, $con, CcPlaylistcontentsPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcPlaylistcontentsPeer::clearInstancePool(); - CcPlaylistcontentsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcPlaylistcontents or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcPlaylistcontents object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcPlaylistcontentsPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcPlaylistcontents) { // it's a model object - // invalidate the cache for this single object - CcPlaylistcontentsPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcPlaylistcontentsPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcPlaylistcontentsPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcPlaylistcontentsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcPlaylistcontents object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcPlaylistcontents $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcPlaylistcontents $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcPlaylistcontentsPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcPlaylistcontentsPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcPlaylistcontentsPeer::DATABASE_NAME, CcPlaylistcontentsPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcPlaylistcontents - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcPlaylistcontentsPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcPlaylistcontentsPeer::DATABASE_NAME); - $criteria->add(CcPlaylistcontentsPeer::ID, $pk); - - $v = CcPlaylistcontentsPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcPlaylistcontentsPeer::DATABASE_NAME); - $criteria->add(CcPlaylistcontentsPeer::ID, $pks, Criteria::IN); - $objs = CcPlaylistcontentsPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcPlaylistcontentsPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcPlaylistcontentsPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsQuery.php deleted file mode 100644 index 183fa9a4f..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPlaylistcontentsQuery.php +++ /dev/null @@ -1,581 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcPlaylistcontents|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcPlaylistcontentsPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcPlaylistcontentsPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcPlaylistcontentsPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $dbId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbId($dbId = null, $comparison = null) - { - if (is_array($dbId) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::ID, $dbId, $comparison); - } - - /** - * Filter the query on the playlist_id column - * - * @param int|array $dbPlaylistId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbPlaylistId($dbPlaylistId = null, $comparison = null) - { - if (is_array($dbPlaylistId)) { - $useMinMax = false; - if (isset($dbPlaylistId['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::PLAYLIST_ID, $dbPlaylistId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbPlaylistId['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::PLAYLIST_ID, $dbPlaylistId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::PLAYLIST_ID, $dbPlaylistId, $comparison); - } - - /** - * Filter the query on the file_id column - * - * @param int|array $dbFileId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbFileId($dbFileId = null, $comparison = null) - { - if (is_array($dbFileId)) { - $useMinMax = false; - if (isset($dbFileId['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FILE_ID, $dbFileId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbFileId['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FILE_ID, $dbFileId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::FILE_ID, $dbFileId, $comparison); - } - - /** - * Filter the query on the position column - * - * @param int|array $dbPosition The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbPosition($dbPosition = null, $comparison = null) - { - if (is_array($dbPosition)) { - $useMinMax = false; - if (isset($dbPosition['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::POSITION, $dbPosition['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbPosition['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::POSITION, $dbPosition['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::POSITION, $dbPosition, $comparison); - } - - /** - * Filter the query on the cliplength column - * - * @param string|array $dbCliplength The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbCliplength($dbCliplength = null, $comparison = null) - { - if (is_array($dbCliplength)) { - $useMinMax = false; - if (isset($dbCliplength['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CLIPLENGTH, $dbCliplength['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbCliplength['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CLIPLENGTH, $dbCliplength['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::CLIPLENGTH, $dbCliplength, $comparison); - } - - /** - * Filter the query on the cuein column - * - * @param string|array $dbCuein The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbCuein($dbCuein = null, $comparison = null) - { - if (is_array($dbCuein)) { - $useMinMax = false; - if (isset($dbCuein['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CUEIN, $dbCuein['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbCuein['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CUEIN, $dbCuein['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::CUEIN, $dbCuein, $comparison); - } - - /** - * Filter the query on the cueout column - * - * @param string|array $dbCueout The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbCueout($dbCueout = null, $comparison = null) - { - if (is_array($dbCueout)) { - $useMinMax = false; - if (isset($dbCueout['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CUEOUT, $dbCueout['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbCueout['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::CUEOUT, $dbCueout['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::CUEOUT, $dbCueout, $comparison); - } - - /** - * Filter the query on the fadein column - * - * @param string|array $dbFadein The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbFadein($dbFadein = null, $comparison = null) - { - if (is_array($dbFadein)) { - $useMinMax = false; - if (isset($dbFadein['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FADEIN, $dbFadein['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbFadein['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FADEIN, $dbFadein['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::FADEIN, $dbFadein, $comparison); - } - - /** - * Filter the query on the fadeout column - * - * @param string|array $dbFadeout The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByDbFadeout($dbFadeout = null, $comparison = null) - { - if (is_array($dbFadeout)) { - $useMinMax = false; - if (isset($dbFadeout['min'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FADEOUT, $dbFadeout['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($dbFadeout['max'])) { - $this->addUsingAlias(CcPlaylistcontentsPeer::FADEOUT, $dbFadeout['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPlaylistcontentsPeer::FADEOUT, $dbFadeout, $comparison); - } - - /** - * Filter the query by a related CcFiles object - * - * @param CcFiles $ccFiles the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByCcFiles($ccFiles, $comparison = null) - { - return $this - ->addUsingAlias(CcPlaylistcontentsPeer::FILE_ID, $ccFiles->getDbId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcFiles relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function joinCcFiles($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcFiles'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcFiles'); - } - - return $this; - } - - /** - * Use the CcFiles relation CcFiles object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcFilesQuery A secondary query class using the current class as primary query - */ - public function useCcFilesQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcFiles($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcFiles', 'CcFilesQuery'); - } - - /** - * Filter the query by a related CcPlaylist object - * - * @param CcPlaylist $ccPlaylist the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function filterByCcPlaylist($ccPlaylist, $comparison = null) - { - return $this - ->addUsingAlias(CcPlaylistcontentsPeer::PLAYLIST_ID, $ccPlaylist->getDbId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPlaylist relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function joinCcPlaylist($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPlaylist'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPlaylist'); - } - - return $this; - } - - /** - * Use the CcPlaylist relation CcPlaylist object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistQuery A secondary query class using the current class as primary query - */ - public function useCcPlaylistQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPlaylist($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPlaylist', 'CcPlaylistQuery'); - } - - /** - * Exclude object from result - * - * @param CcPlaylistcontents $ccPlaylistcontents Object to remove from the list of results - * - * @return CcPlaylistcontentsQuery The current query, for fluid interface - */ - public function prune($ccPlaylistcontents = null) - { - if ($ccPlaylistcontents) { - $this->addUsingAlias(CcPlaylistcontentsPeer::ID, $ccPlaylistcontents->getDbId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcPlaylistcontentsQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPref.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPref.php deleted file mode 100644 index d1f07c596..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPref.php +++ /dev/null @@ -1,905 +0,0 @@ -id; - } - - /** - * Get the [subjid] column value. - * - * @return int - */ - public function getSubjid() - { - return $this->subjid; - } - - /** - * Get the [keystr] column value. - * - * @return string - */ - public function getKeystr() - { - return $this->keystr; - } - - /** - * Get the [valstr] column value. - * - * @return string - */ - public function getValstr() - { - return $this->valstr; - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcPref The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcPrefPeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [subjid] column. - * - * @param int $v new value - * @return CcPref The current object (for fluent API support) - */ - public function setSubjid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->subjid !== $v) { - $this->subjid = $v; - $this->modifiedColumns[] = CcPrefPeer::SUBJID; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setSubjid() - - /** - * Set the value of [keystr] column. - * - * @param string $v new value - * @return CcPref The current object (for fluent API support) - */ - public function setKeystr($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->keystr !== $v) { - $this->keystr = $v; - $this->modifiedColumns[] = CcPrefPeer::KEYSTR; - } - - return $this; - } // setKeystr() - - /** - * Set the value of [valstr] column. - * - * @param string $v new value - * @return CcPref The current object (for fluent API support) - */ - public function setValstr($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->valstr !== $v) { - $this->valstr = $v; - $this->modifiedColumns[] = CcPrefPeer::VALSTR; - } - - return $this; - } // setValstr() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->subjid = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->keystr = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->valstr = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 4; // 4 = CcPrefPeer::NUM_COLUMNS - CcPrefPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcPref object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->subjid !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcPrefPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcPrefQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcPrefPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcPrefPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcPrefPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPrefPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows += CcPrefPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcPrefPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPrefPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getSubjid(); - break; - case 2: - return $this->getKeystr(); - break; - case 3: - return $this->getValstr(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcPrefPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getSubjid(), - $keys[2] => $this->getKeystr(), - $keys[3] => $this->getValstr(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcPrefPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setSubjid($value); - break; - case 2: - $this->setKeystr($value); - break; - case 3: - $this->setValstr($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcPrefPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setSubjid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setKeystr($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setValstr($arr[$keys[3]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcPrefPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcPrefPeer::ID)) $criteria->add(CcPrefPeer::ID, $this->id); - if ($this->isColumnModified(CcPrefPeer::SUBJID)) $criteria->add(CcPrefPeer::SUBJID, $this->subjid); - if ($this->isColumnModified(CcPrefPeer::KEYSTR)) $criteria->add(CcPrefPeer::KEYSTR, $this->keystr); - if ($this->isColumnModified(CcPrefPeer::VALSTR)) $criteria->add(CcPrefPeer::VALSTR, $this->valstr); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcPrefPeer::DATABASE_NAME); - $criteria->add(CcPrefPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcPref (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setSubjid($this->subjid); - $copyObj->setKeystr($this->keystr); - $copyObj->setValstr($this->valstr); - - $copyObj->setNew(true); - $copyObj->setId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcPref Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcPrefPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcPrefPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcPref The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setSubjid(NULL); - } else { - $this->setSubjid($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcPref($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->subjid !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->subjid, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcPrefs($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->subjid = null; - $this->keystr = null; - $this->valstr = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcPref diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPrefPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPrefPeer.php deleted file mode 100644 index 8356fed9a..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPrefPeer.php +++ /dev/null @@ -1,983 +0,0 @@ - array ('Id', 'Subjid', 'Keystr', 'Valstr', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'subjid', 'keystr', 'valstr', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::SUBJID, self::KEYSTR, self::VALSTR, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'SUBJID', 'KEYSTR', 'VALSTR', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'subjid', 'keystr', 'valstr', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Subjid' => 1, 'Keystr' => 2, 'Valstr' => 3, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'subjid' => 1, 'keystr' => 2, 'valstr' => 3, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::SUBJID => 1, self::KEYSTR => 2, self::VALSTR => 3, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'SUBJID' => 1, 'KEYSTR' => 2, 'VALSTR' => 3, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'subjid' => 1, 'keystr' => 2, 'valstr' => 3, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcPrefPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcPrefPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcPrefPeer::ID); - $criteria->addSelectColumn(CcPrefPeer::SUBJID); - $criteria->addSelectColumn(CcPrefPeer::KEYSTR); - $criteria->addSelectColumn(CcPrefPeer::VALSTR); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.SUBJID'); - $criteria->addSelectColumn($alias . '.KEYSTR'); - $criteria->addSelectColumn($alias . '.VALSTR'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPrefPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPrefPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcPref - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcPrefPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcPrefPeer::populateObjects(CcPrefPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcPrefPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcPref $value A CcPref object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcPref $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcPref object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcPref) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcPref object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcPref Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_pref - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcPrefPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcPrefPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcPrefPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcPrefPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcPref object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcPrefPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcPrefPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcPrefPeer::NUM_COLUMNS; - } else { - $cls = CcPrefPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcPrefPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPrefPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPrefPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPrefPeer::SUBJID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcPref objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPref objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPrefPeer::addSelectColumns($criteria); - $startcol = (CcPrefPeer::NUM_COLUMNS - CcPrefPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcPrefPeer::SUBJID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPrefPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPrefPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcPrefPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPrefPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcPref) to $obj2 (CcSubjs) - $obj2->addCcPref($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcPrefPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcPrefPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcPrefPeer::SUBJID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcPref objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcPref objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcPrefPeer::addSelectColumns($criteria); - $startcol2 = (CcPrefPeer::NUM_COLUMNS - CcPrefPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcPrefPeer::SUBJID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcPrefPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcPrefPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcPrefPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcPrefPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcPref) to the collection in $obj2 (CcSubjs) - $obj2->addCcPref($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcPrefPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcPrefPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcPrefTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcPrefPeer::CLASS_DEFAULT : CcPrefPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcPref or Criteria object. - * - * @param mixed $values Criteria or CcPref object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcPref object - } - - if ($criteria->containsKey(CcPrefPeer::ID) && $criteria->keyContainsValue(CcPrefPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcPrefPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcPref or Criteria object. - * - * @param mixed $values Criteria or CcPref object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcPrefPeer::ID); - $value = $criteria->remove(CcPrefPeer::ID); - if ($value) { - $selectCriteria->add(CcPrefPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcPrefPeer::TABLE_NAME); - } - - } else { // $values is CcPref object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_pref table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcPrefPeer::TABLE_NAME, $con, CcPrefPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcPrefPeer::clearInstancePool(); - CcPrefPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcPref or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcPref object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcPrefPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcPref) { // it's a model object - // invalidate the cache for this single object - CcPrefPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcPrefPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcPrefPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcPrefPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcPref object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcPref $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcPref $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcPrefPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcPrefPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcPrefPeer::DATABASE_NAME, CcPrefPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcPref - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcPrefPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcPrefPeer::DATABASE_NAME); - $criteria->add(CcPrefPeer::ID, $pk); - - $v = CcPrefPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcPrefPeer::DATABASE_NAME); - $criteria->add(CcPrefPeer::ID, $pks, Criteria::IN); - $objs = CcPrefPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcPrefPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcPrefPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcPrefQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcPrefQuery.php deleted file mode 100644 index e85c52a36..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcPrefQuery.php +++ /dev/null @@ -1,320 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcPref|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcPrefPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcPrefPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcPrefPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcPrefPeer::ID, $id, $comparison); - } - - /** - * Filter the query on the subjid column - * - * @param int|array $subjid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterBySubjid($subjid = null, $comparison = null) - { - if (is_array($subjid)) { - $useMinMax = false; - if (isset($subjid['min'])) { - $this->addUsingAlias(CcPrefPeer::SUBJID, $subjid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($subjid['max'])) { - $this->addUsingAlias(CcPrefPeer::SUBJID, $subjid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcPrefPeer::SUBJID, $subjid, $comparison); - } - - /** - * Filter the query on the keystr column - * - * @param string $keystr The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterByKeystr($keystr = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($keystr)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $keystr)) { - $keystr = str_replace('*', '%', $keystr); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPrefPeer::KEYSTR, $keystr, $comparison); - } - - /** - * Filter the query on the valstr column - * - * @param string $valstr The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterByValstr($valstr = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($valstr)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $valstr)) { - $valstr = str_replace('*', '%', $valstr); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcPrefPeer::VALSTR, $valstr, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcPrefPeer::SUBJID, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Exclude object from result - * - * @param CcPref $ccPref Object to remove from the list of results - * - * @return CcPrefQuery The current query, for fluid interface - */ - public function prune($ccPref = null) - { - if ($ccPref) { - $this->addUsingAlias(CcPrefPeer::ID, $ccPref->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcPrefQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSchedule.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSchedule.php deleted file mode 100644 index 39bad3761..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSchedule.php +++ /dev/null @@ -1,1560 +0,0 @@ -clip_length = '00:00:00'; - $this->fade_in = '00:00:00'; - $this->fade_out = '00:00:00'; - $this->cue_in = '00:00:00'; - $this->cue_out = '00:00:00'; - } - - /** - * Initializes internal state of BaseCcSchedule object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /** - * Get the [playlist_id] column value. - * - * @return int - */ - public function getPlaylistId() - { - return $this->playlist_id; - } - - /** - * Get the [optionally formatted] temporal [starts] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getStarts($format = 'Y-m-d H:i:s') - { - if ($this->starts === null) { - return null; - } - - - - try { - $dt = new DateTime($this->starts); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->starts, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [ends] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getEnds($format = 'Y-m-d H:i:s') - { - if ($this->ends === null) { - return null; - } - - - - try { - $dt = new DateTime($this->ends); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ends, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [group_id] column value. - * - * @return int - */ - public function getGroupId() - { - return $this->group_id; - } - - /** - * Get the [file_id] column value. - * - * @return int - */ - public function getFileId() - { - return $this->file_id; - } - - /** - * Get the [optionally formatted] temporal [clip_length] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getClipLength($format = '%X') - { - if ($this->clip_length === null) { - return null; - } - - - - try { - $dt = new DateTime($this->clip_length); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->clip_length, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [fade_in] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getFadeIn($format = '%X') - { - if ($this->fade_in === null) { - return null; - } - - - - try { - $dt = new DateTime($this->fade_in); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->fade_in, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [fade_out] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getFadeOut($format = '%X') - { - if ($this->fade_out === null) { - return null; - } - - - - try { - $dt = new DateTime($this->fade_out); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->fade_out, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [cue_in] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getCueIn($format = '%X') - { - if ($this->cue_in === null) { - return null; - } - - - - try { - $dt = new DateTime($this->cue_in); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cue_in, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [cue_out] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getCueOut($format = '%X') - { - if ($this->cue_out === null) { - return null; - } - - - - try { - $dt = new DateTime($this->cue_out); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cue_out, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [id] column. - * - * @param string $v new value - * @return CcSchedule The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcSchedulePeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [playlist_id] column. - * - * @param int $v new value - * @return CcSchedule The current object (for fluent API support) - */ - public function setPlaylistId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->playlist_id !== $v) { - $this->playlist_id = $v; - $this->modifiedColumns[] = CcSchedulePeer::PLAYLIST_ID; - } - - return $this; - } // setPlaylistId() - - /** - * Sets the value of [starts] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setStarts($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->starts !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->starts !== null && $tmpDt = new DateTime($this->starts)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->starts = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcSchedulePeer::STARTS; - } - } // if either are not null - - return $this; - } // setStarts() - - /** - * Sets the value of [ends] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setEnds($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->ends !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->ends !== null && $tmpDt = new DateTime($this->ends)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->ends = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcSchedulePeer::ENDS; - } - } // if either are not null - - return $this; - } // setEnds() - - /** - * Set the value of [group_id] column. - * - * @param int $v new value - * @return CcSchedule The current object (for fluent API support) - */ - public function setGroupId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->group_id !== $v) { - $this->group_id = $v; - $this->modifiedColumns[] = CcSchedulePeer::GROUP_ID; - } - - return $this; - } // setGroupId() - - /** - * Set the value of [file_id] column. - * - * @param int $v new value - * @return CcSchedule The current object (for fluent API support) - */ - public function setFileId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->file_id !== $v) { - $this->file_id = $v; - $this->modifiedColumns[] = CcSchedulePeer::FILE_ID; - } - - return $this; - } // setFileId() - - /** - * Sets the value of [clip_length] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setClipLength($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->clip_length !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->clip_length !== null && $tmpDt = new DateTime($this->clip_length)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->clip_length = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcSchedulePeer::CLIP_LENGTH; - } - } // if either are not null - - return $this; - } // setClipLength() - - /** - * Sets the value of [fade_in] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setFadeIn($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->fade_in !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->fade_in !== null && $tmpDt = new DateTime($this->fade_in)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->fade_in = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcSchedulePeer::FADE_IN; - } - } // if either are not null - - return $this; - } // setFadeIn() - - /** - * Sets the value of [fade_out] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setFadeOut($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->fade_out !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->fade_out !== null && $tmpDt = new DateTime($this->fade_out)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->fade_out = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcSchedulePeer::FADE_OUT; - } - } // if either are not null - - return $this; - } // setFadeOut() - - /** - * Sets the value of [cue_in] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setCueIn($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->cue_in !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->cue_in !== null && $tmpDt = new DateTime($this->cue_in)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->cue_in = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcSchedulePeer::CUE_IN; - } - } // if either are not null - - return $this; - } // setCueIn() - - /** - * Sets the value of [cue_out] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSchedule The current object (for fluent API support) - */ - public function setCueOut($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->cue_out !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->cue_out !== null && $tmpDt = new DateTime($this->cue_out)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default - ) - { - $this->cue_out = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcSchedulePeer::CUE_OUT; - } - } // if either are not null - - return $this; - } // setCueOut() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->clip_length !== '00:00:00') { - return false; - } - - if ($this->fade_in !== '00:00:00') { - return false; - } - - if ($this->fade_out !== '00:00:00') { - return false; - } - - if ($this->cue_in !== '00:00:00') { - return false; - } - - if ($this->cue_out !== '00:00:00') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (string) $row[$startcol + 0] : null; - $this->playlist_id = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->starts = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->ends = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->group_id = ($row[$startcol + 4] !== null) ? (int) $row[$startcol + 4] : null; - $this->file_id = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null; - $this->clip_length = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->fade_in = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null; - $this->fade_out = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; - $this->cue_in = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null; - $this->cue_out = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 11; // 11 = CcSchedulePeer::NUM_COLUMNS - CcSchedulePeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcSchedule object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcSchedulePeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcScheduleQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcSchedulePeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows = 1; - $this->setNew(false); - } else { - $affectedRows = CcSchedulePeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - if (($retval = CcSchedulePeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSchedulePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getPlaylistId(); - break; - case 2: - return $this->getStarts(); - break; - case 3: - return $this->getEnds(); - break; - case 4: - return $this->getGroupId(); - break; - case 5: - return $this->getFileId(); - break; - case 6: - return $this->getClipLength(); - break; - case 7: - return $this->getFadeIn(); - break; - case 8: - return $this->getFadeOut(); - break; - case 9: - return $this->getCueIn(); - break; - case 10: - return $this->getCueOut(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true) - { - $keys = CcSchedulePeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getPlaylistId(), - $keys[2] => $this->getStarts(), - $keys[3] => $this->getEnds(), - $keys[4] => $this->getGroupId(), - $keys[5] => $this->getFileId(), - $keys[6] => $this->getClipLength(), - $keys[7] => $this->getFadeIn(), - $keys[8] => $this->getFadeOut(), - $keys[9] => $this->getCueIn(), - $keys[10] => $this->getCueOut(), - ); - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSchedulePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setPlaylistId($value); - break; - case 2: - $this->setStarts($value); - break; - case 3: - $this->setEnds($value); - break; - case 4: - $this->setGroupId($value); - break; - case 5: - $this->setFileId($value); - break; - case 6: - $this->setClipLength($value); - break; - case 7: - $this->setFadeIn($value); - break; - case 8: - $this->setFadeOut($value); - break; - case 9: - $this->setCueIn($value); - break; - case 10: - $this->setCueOut($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcSchedulePeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setPlaylistId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setStarts($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setEnds($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setGroupId($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setFileId($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setClipLength($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setFadeIn($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setFadeOut($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setCueIn($arr[$keys[9]]); - if (array_key_exists($keys[10], $arr)) $this->setCueOut($arr[$keys[10]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcSchedulePeer::DATABASE_NAME); - - if ($this->isColumnModified(CcSchedulePeer::ID)) $criteria->add(CcSchedulePeer::ID, $this->id); - if ($this->isColumnModified(CcSchedulePeer::PLAYLIST_ID)) $criteria->add(CcSchedulePeer::PLAYLIST_ID, $this->playlist_id); - if ($this->isColumnModified(CcSchedulePeer::STARTS)) $criteria->add(CcSchedulePeer::STARTS, $this->starts); - if ($this->isColumnModified(CcSchedulePeer::ENDS)) $criteria->add(CcSchedulePeer::ENDS, $this->ends); - if ($this->isColumnModified(CcSchedulePeer::GROUP_ID)) $criteria->add(CcSchedulePeer::GROUP_ID, $this->group_id); - if ($this->isColumnModified(CcSchedulePeer::FILE_ID)) $criteria->add(CcSchedulePeer::FILE_ID, $this->file_id); - if ($this->isColumnModified(CcSchedulePeer::CLIP_LENGTH)) $criteria->add(CcSchedulePeer::CLIP_LENGTH, $this->clip_length); - if ($this->isColumnModified(CcSchedulePeer::FADE_IN)) $criteria->add(CcSchedulePeer::FADE_IN, $this->fade_in); - if ($this->isColumnModified(CcSchedulePeer::FADE_OUT)) $criteria->add(CcSchedulePeer::FADE_OUT, $this->fade_out); - if ($this->isColumnModified(CcSchedulePeer::CUE_IN)) $criteria->add(CcSchedulePeer::CUE_IN, $this->cue_in); - if ($this->isColumnModified(CcSchedulePeer::CUE_OUT)) $criteria->add(CcSchedulePeer::CUE_OUT, $this->cue_out); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcSchedulePeer::DATABASE_NAME); - $criteria->add(CcSchedulePeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return string - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param string $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcSchedule (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setId($this->id); - $copyObj->setPlaylistId($this->playlist_id); - $copyObj->setStarts($this->starts); - $copyObj->setEnds($this->ends); - $copyObj->setGroupId($this->group_id); - $copyObj->setFileId($this->file_id); - $copyObj->setClipLength($this->clip_length); - $copyObj->setFadeIn($this->fade_in); - $copyObj->setFadeOut($this->fade_out); - $copyObj->setCueIn($this->cue_in); - $copyObj->setCueOut($this->cue_out); - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcSchedule Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcSchedulePeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcSchedulePeer(); - } - return self::$peer; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->playlist_id = null; - $this->starts = null; - $this->ends = null; - $this->group_id = null; - $this->file_id = null; - $this->clip_length = null; - $this->fade_in = null; - $this->fade_out = null; - $this->cue_in = null; - $this->cue_out = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcSchedule diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSchedulePeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSchedulePeer.php deleted file mode 100644 index c62a304c7..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSchedulePeer.php +++ /dev/null @@ -1,780 +0,0 @@ - array ('Id', 'PlaylistId', 'Starts', 'Ends', 'GroupId', 'FileId', 'ClipLength', 'FadeIn', 'FadeOut', 'CueIn', 'CueOut', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'playlistId', 'starts', 'ends', 'groupId', 'fileId', 'clipLength', 'fadeIn', 'fadeOut', 'cueIn', 'cueOut', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::PLAYLIST_ID, self::STARTS, self::ENDS, self::GROUP_ID, self::FILE_ID, self::CLIP_LENGTH, self::FADE_IN, self::FADE_OUT, self::CUE_IN, self::CUE_OUT, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'PLAYLIST_ID', 'STARTS', 'ENDS', 'GROUP_ID', 'FILE_ID', 'CLIP_LENGTH', 'FADE_IN', 'FADE_OUT', 'CUE_IN', 'CUE_OUT', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'playlist_id', 'starts', 'ends', 'group_id', 'file_id', 'clip_length', 'fade_in', 'fade_out', 'cue_in', 'cue_out', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'PlaylistId' => 1, 'Starts' => 2, 'Ends' => 3, 'GroupId' => 4, 'FileId' => 5, 'ClipLength' => 6, 'FadeIn' => 7, 'FadeOut' => 8, 'CueIn' => 9, 'CueOut' => 10, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'playlistId' => 1, 'starts' => 2, 'ends' => 3, 'groupId' => 4, 'fileId' => 5, 'clipLength' => 6, 'fadeIn' => 7, 'fadeOut' => 8, 'cueIn' => 9, 'cueOut' => 10, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::PLAYLIST_ID => 1, self::STARTS => 2, self::ENDS => 3, self::GROUP_ID => 4, self::FILE_ID => 5, self::CLIP_LENGTH => 6, self::FADE_IN => 7, self::FADE_OUT => 8, self::CUE_IN => 9, self::CUE_OUT => 10, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'PLAYLIST_ID' => 1, 'STARTS' => 2, 'ENDS' => 3, 'GROUP_ID' => 4, 'FILE_ID' => 5, 'CLIP_LENGTH' => 6, 'FADE_IN' => 7, 'FADE_OUT' => 8, 'CUE_IN' => 9, 'CUE_OUT' => 10, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'playlist_id' => 1, 'starts' => 2, 'ends' => 3, 'group_id' => 4, 'file_id' => 5, 'clip_length' => 6, 'fade_in' => 7, 'fade_out' => 8, 'cue_in' => 9, 'cue_out' => 10, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcSchedulePeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcSchedulePeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcSchedulePeer::ID); - $criteria->addSelectColumn(CcSchedulePeer::PLAYLIST_ID); - $criteria->addSelectColumn(CcSchedulePeer::STARTS); - $criteria->addSelectColumn(CcSchedulePeer::ENDS); - $criteria->addSelectColumn(CcSchedulePeer::GROUP_ID); - $criteria->addSelectColumn(CcSchedulePeer::FILE_ID); - $criteria->addSelectColumn(CcSchedulePeer::CLIP_LENGTH); - $criteria->addSelectColumn(CcSchedulePeer::FADE_IN); - $criteria->addSelectColumn(CcSchedulePeer::FADE_OUT); - $criteria->addSelectColumn(CcSchedulePeer::CUE_IN); - $criteria->addSelectColumn(CcSchedulePeer::CUE_OUT); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.PLAYLIST_ID'); - $criteria->addSelectColumn($alias . '.STARTS'); - $criteria->addSelectColumn($alias . '.ENDS'); - $criteria->addSelectColumn($alias . '.GROUP_ID'); - $criteria->addSelectColumn($alias . '.FILE_ID'); - $criteria->addSelectColumn($alias . '.CLIP_LENGTH'); - $criteria->addSelectColumn($alias . '.FADE_IN'); - $criteria->addSelectColumn($alias . '.FADE_OUT'); - $criteria->addSelectColumn($alias . '.CUE_IN'); - $criteria->addSelectColumn($alias . '.CUE_OUT'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSchedulePeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSchedulePeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcSchedule - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcSchedulePeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcSchedulePeer::populateObjects(CcSchedulePeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcSchedulePeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcSchedule $value A CcSchedule object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcSchedule $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcSchedule object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcSchedule) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSchedule object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcSchedule Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_schedule - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (string) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcSchedulePeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcSchedulePeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcSchedulePeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcSchedulePeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcSchedule object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcSchedulePeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcSchedulePeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcSchedulePeer::NUM_COLUMNS; - } else { - $cls = CcSchedulePeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcSchedulePeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcSchedulePeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcSchedulePeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcScheduleTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcSchedulePeer::CLASS_DEFAULT : CcSchedulePeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcSchedule or Criteria object. - * - * @param mixed $values Criteria or CcSchedule object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcSchedule object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcSchedule or Criteria object. - * - * @param mixed $values Criteria or CcSchedule object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcSchedulePeer::ID); - $value = $criteria->remove(CcSchedulePeer::ID); - if ($value) { - $selectCriteria->add(CcSchedulePeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcSchedulePeer::TABLE_NAME); - } - - } else { // $values is CcSchedule object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_schedule table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcSchedulePeer::TABLE_NAME, $con, CcSchedulePeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcSchedulePeer::clearInstancePool(); - CcSchedulePeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcSchedule or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcSchedule object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcSchedulePeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcSchedule) { // it's a model object - // invalidate the cache for this single object - CcSchedulePeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcSchedulePeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcSchedulePeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcSchedulePeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcSchedule object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcSchedule $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcSchedule $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcSchedulePeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcSchedulePeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcSchedulePeer::DATABASE_NAME, CcSchedulePeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param string $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcSchedule - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcSchedulePeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcSchedulePeer::DATABASE_NAME); - $criteria->add(CcSchedulePeer::ID, $pk); - - $v = CcSchedulePeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcSchedulePeer::DATABASE_NAME); - $criteria->add(CcSchedulePeer::ID, $pks, Criteria::IN); - $objs = CcSchedulePeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcSchedulePeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcSchedulePeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcScheduleQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcScheduleQuery.php deleted file mode 100644 index 22435bf77..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcScheduleQuery.php +++ /dev/null @@ -1,515 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcSchedule|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcSchedulePeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcSchedulePeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcSchedulePeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param string|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcSchedulePeer::ID, $id, $comparison); - } - - /** - * Filter the query on the playlist_id column - * - * @param int|array $playlistId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByPlaylistId($playlistId = null, $comparison = null) - { - if (is_array($playlistId)) { - $useMinMax = false; - if (isset($playlistId['min'])) { - $this->addUsingAlias(CcSchedulePeer::PLAYLIST_ID, $playlistId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($playlistId['max'])) { - $this->addUsingAlias(CcSchedulePeer::PLAYLIST_ID, $playlistId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::PLAYLIST_ID, $playlistId, $comparison); - } - - /** - * Filter the query on the starts column - * - * @param string|array $starts The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByStarts($starts = null, $comparison = null) - { - if (is_array($starts)) { - $useMinMax = false; - if (isset($starts['min'])) { - $this->addUsingAlias(CcSchedulePeer::STARTS, $starts['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($starts['max'])) { - $this->addUsingAlias(CcSchedulePeer::STARTS, $starts['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::STARTS, $starts, $comparison); - } - - /** - * Filter the query on the ends column - * - * @param string|array $ends The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByEnds($ends = null, $comparison = null) - { - if (is_array($ends)) { - $useMinMax = false; - if (isset($ends['min'])) { - $this->addUsingAlias(CcSchedulePeer::ENDS, $ends['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($ends['max'])) { - $this->addUsingAlias(CcSchedulePeer::ENDS, $ends['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::ENDS, $ends, $comparison); - } - - /** - * Filter the query on the group_id column - * - * @param int|array $groupId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByGroupId($groupId = null, $comparison = null) - { - if (is_array($groupId)) { - $useMinMax = false; - if (isset($groupId['min'])) { - $this->addUsingAlias(CcSchedulePeer::GROUP_ID, $groupId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($groupId['max'])) { - $this->addUsingAlias(CcSchedulePeer::GROUP_ID, $groupId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::GROUP_ID, $groupId, $comparison); - } - - /** - * Filter the query on the file_id column - * - * @param int|array $fileId The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByFileId($fileId = null, $comparison = null) - { - if (is_array($fileId)) { - $useMinMax = false; - if (isset($fileId['min'])) { - $this->addUsingAlias(CcSchedulePeer::FILE_ID, $fileId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($fileId['max'])) { - $this->addUsingAlias(CcSchedulePeer::FILE_ID, $fileId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::FILE_ID, $fileId, $comparison); - } - - /** - * Filter the query on the clip_length column - * - * @param string|array $clipLength The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByClipLength($clipLength = null, $comparison = null) - { - if (is_array($clipLength)) { - $useMinMax = false; - if (isset($clipLength['min'])) { - $this->addUsingAlias(CcSchedulePeer::CLIP_LENGTH, $clipLength['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($clipLength['max'])) { - $this->addUsingAlias(CcSchedulePeer::CLIP_LENGTH, $clipLength['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::CLIP_LENGTH, $clipLength, $comparison); - } - - /** - * Filter the query on the fade_in column - * - * @param string|array $fadeIn The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByFadeIn($fadeIn = null, $comparison = null) - { - if (is_array($fadeIn)) { - $useMinMax = false; - if (isset($fadeIn['min'])) { - $this->addUsingAlias(CcSchedulePeer::FADE_IN, $fadeIn['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($fadeIn['max'])) { - $this->addUsingAlias(CcSchedulePeer::FADE_IN, $fadeIn['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::FADE_IN, $fadeIn, $comparison); - } - - /** - * Filter the query on the fade_out column - * - * @param string|array $fadeOut The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByFadeOut($fadeOut = null, $comparison = null) - { - if (is_array($fadeOut)) { - $useMinMax = false; - if (isset($fadeOut['min'])) { - $this->addUsingAlias(CcSchedulePeer::FADE_OUT, $fadeOut['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($fadeOut['max'])) { - $this->addUsingAlias(CcSchedulePeer::FADE_OUT, $fadeOut['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::FADE_OUT, $fadeOut, $comparison); - } - - /** - * Filter the query on the cue_in column - * - * @param string|array $cueIn The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByCueIn($cueIn = null, $comparison = null) - { - if (is_array($cueIn)) { - $useMinMax = false; - if (isset($cueIn['min'])) { - $this->addUsingAlias(CcSchedulePeer::CUE_IN, $cueIn['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($cueIn['max'])) { - $this->addUsingAlias(CcSchedulePeer::CUE_IN, $cueIn['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::CUE_IN, $cueIn, $comparison); - } - - /** - * Filter the query on the cue_out column - * - * @param string|array $cueOut The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function filterByCueOut($cueOut = null, $comparison = null) - { - if (is_array($cueOut)) { - $useMinMax = false; - if (isset($cueOut['min'])) { - $this->addUsingAlias(CcSchedulePeer::CUE_OUT, $cueOut['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($cueOut['max'])) { - $this->addUsingAlias(CcSchedulePeer::CUE_OUT, $cueOut['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSchedulePeer::CUE_OUT, $cueOut, $comparison); - } - - /** - * Exclude object from result - * - * @param CcSchedule $ccSchedule Object to remove from the list of results - * - * @return CcScheduleQuery The current query, for fluid interface - */ - public function prune($ccSchedule = null) - { - if ($ccSchedule) { - $this->addUsingAlias(CcSchedulePeer::ID, $ccSchedule->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcScheduleQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSess.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSess.php deleted file mode 100644 index a68aa8e12..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSess.php +++ /dev/null @@ -1,949 +0,0 @@ -sessid; - } - - /** - * Get the [userid] column value. - * - * @return int - */ - public function getUserid() - { - return $this->userid; - } - - /** - * Get the [login] column value. - * - * @return string - */ - public function getLogin() - { - return $this->login; - } - - /** - * Get the [optionally formatted] temporal [ts] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getTs($format = 'Y-m-d H:i:s') - { - if ($this->ts === null) { - return null; - } - - - - try { - $dt = new DateTime($this->ts); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ts, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [sessid] column. - * - * @param string $v new value - * @return CcSess The current object (for fluent API support) - */ - public function setSessid($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->sessid !== $v) { - $this->sessid = $v; - $this->modifiedColumns[] = CcSessPeer::SESSID; - } - - return $this; - } // setSessid() - - /** - * Set the value of [userid] column. - * - * @param int $v new value - * @return CcSess The current object (for fluent API support) - */ - public function setUserid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->userid !== $v) { - $this->userid = $v; - $this->modifiedColumns[] = CcSessPeer::USERID; - } - - if ($this->aCcSubjs !== null && $this->aCcSubjs->getId() !== $v) { - $this->aCcSubjs = null; - } - - return $this; - } // setUserid() - - /** - * Set the value of [login] column. - * - * @param string $v new value - * @return CcSess The current object (for fluent API support) - */ - public function setLogin($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->login !== $v) { - $this->login = $v; - $this->modifiedColumns[] = CcSessPeer::LOGIN; - } - - return $this; - } // setLogin() - - /** - * Sets the value of [ts] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSess The current object (for fluent API support) - */ - public function setTs($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->ts !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->ts !== null && $tmpDt = new DateTime($this->ts)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->ts = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcSessPeer::TS; - } - } // if either are not null - - return $this; - } // setTs() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->sessid = ($row[$startcol + 0] !== null) ? (string) $row[$startcol + 0] : null; - $this->userid = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->login = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->ts = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 4; // 4 = CcSessPeer::NUM_COLUMNS - CcSessPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcSess object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - if ($this->aCcSubjs !== null && $this->userid !== $this->aCcSubjs->getId()) { - $this->aCcSubjs = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcSessPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aCcSubjs = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcSessQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcSessPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if ($this->aCcSubjs->isModified() || $this->aCcSubjs->isNew()) { - $affectedRows += $this->aCcSubjs->save($con); - } - $this->setCcSubjs($this->aCcSubjs); - } - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows += 1; - $this->setNew(false); - } else { - $affectedRows += CcSessPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - // We call the validate method on the following object(s) if they - // were passed to this object by their coresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aCcSubjs !== null) { - if (!$this->aCcSubjs->validate($columns)) { - $failureMap = array_merge($failureMap, $this->aCcSubjs->getValidationFailures()); - } - } - - - if (($retval = CcSessPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getSessid(); - break; - case 1: - return $this->getUserid(); - break; - case 2: - return $this->getLogin(); - break; - case 3: - return $this->getTs(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $includeForeignObjects = false) - { - $keys = CcSessPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getSessid(), - $keys[1] => $this->getUserid(), - $keys[2] => $this->getLogin(), - $keys[3] => $this->getTs(), - ); - if ($includeForeignObjects) { - if (null !== $this->aCcSubjs) { - $result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, true); - } - } - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setSessid($value); - break; - case 1: - $this->setUserid($value); - break; - case 2: - $this->setLogin($value); - break; - case 3: - $this->setTs($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcSessPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setSessid($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setUserid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setLogin($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setTs($arr[$keys[3]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcSessPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcSessPeer::SESSID)) $criteria->add(CcSessPeer::SESSID, $this->sessid); - if ($this->isColumnModified(CcSessPeer::USERID)) $criteria->add(CcSessPeer::USERID, $this->userid); - if ($this->isColumnModified(CcSessPeer::LOGIN)) $criteria->add(CcSessPeer::LOGIN, $this->login); - if ($this->isColumnModified(CcSessPeer::TS)) $criteria->add(CcSessPeer::TS, $this->ts); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcSessPeer::DATABASE_NAME); - $criteria->add(CcSessPeer::SESSID, $this->sessid); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return string - */ - public function getPrimaryKey() - { - return $this->getSessid(); - } - - /** - * Generic method to set the primary key (sessid column). - * - * @param string $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setSessid($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getSessid(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcSess (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setSessid($this->sessid); - $copyObj->setUserid($this->userid); - $copyObj->setLogin($this->login); - $copyObj->setTs($this->ts); - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcSess Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcSessPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcSessPeer(); - } - return self::$peer; - } - - /** - * Declares an association between this object and a CcSubjs object. - * - * @param CcSubjs $v - * @return CcSess The current object (for fluent API support) - * @throws PropelException - */ - public function setCcSubjs(CcSubjs $v = null) - { - if ($v === null) { - $this->setUserid(NULL); - } else { - $this->setUserid($v->getId()); - } - - $this->aCcSubjs = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the CcSubjs object, it will not be re-added. - if ($v !== null) { - $v->addCcSess($this); - } - - return $this; - } - - - /** - * Get the associated CcSubjs object - * - * @param PropelPDO Optional Connection object. - * @return CcSubjs The associated CcSubjs object. - * @throws PropelException - */ - public function getCcSubjs(PropelPDO $con = null) - { - if ($this->aCcSubjs === null && ($this->userid !== null)) { - $this->aCcSubjs = CcSubjsQuery::create()->findPk($this->userid, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aCcSubjs->addCcSesss($this); - */ - } - return $this->aCcSubjs; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->sessid = null; - $this->userid = null; - $this->login = null; - $this->ts = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aCcSubjs = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcSess diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSessPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSessPeer.php deleted file mode 100644 index 0ca095e21..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSessPeer.php +++ /dev/null @@ -1,979 +0,0 @@ - array ('Sessid', 'Userid', 'Login', 'Ts', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('sessid', 'userid', 'login', 'ts', ), - BasePeer::TYPE_COLNAME => array (self::SESSID, self::USERID, self::LOGIN, self::TS, ), - BasePeer::TYPE_RAW_COLNAME => array ('SESSID', 'USERID', 'LOGIN', 'TS', ), - BasePeer::TYPE_FIELDNAME => array ('sessid', 'userid', 'login', 'ts', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Sessid' => 0, 'Userid' => 1, 'Login' => 2, 'Ts' => 3, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('sessid' => 0, 'userid' => 1, 'login' => 2, 'ts' => 3, ), - BasePeer::TYPE_COLNAME => array (self::SESSID => 0, self::USERID => 1, self::LOGIN => 2, self::TS => 3, ), - BasePeer::TYPE_RAW_COLNAME => array ('SESSID' => 0, 'USERID' => 1, 'LOGIN' => 2, 'TS' => 3, ), - BasePeer::TYPE_FIELDNAME => array ('sessid' => 0, 'userid' => 1, 'login' => 2, 'ts' => 3, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcSessPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcSessPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcSessPeer::SESSID); - $criteria->addSelectColumn(CcSessPeer::USERID); - $criteria->addSelectColumn(CcSessPeer::LOGIN); - $criteria->addSelectColumn(CcSessPeer::TS); - } else { - $criteria->addSelectColumn($alias . '.SESSID'); - $criteria->addSelectColumn($alias . '.USERID'); - $criteria->addSelectColumn($alias . '.LOGIN'); - $criteria->addSelectColumn($alias . '.TS'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcSess - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcSessPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcSessPeer::populateObjects(CcSessPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcSessPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcSess $value A CcSess object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcSess $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getSessid(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcSess object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcSess) { - $key = (string) $value->getSessid(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSess object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcSess Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_sess - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (string) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcSessPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcSessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcSessPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcSessPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcSess object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcSessPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcSessPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcSessPeer::NUM_COLUMNS; - } else { - $cls = CcSessPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcSessPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - - /** - * Returns the number of rows matching criteria, joining the related CcSubjs table - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcSessPeer::USERID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - - /** - * Selects a collection of CcSess objects pre-filled with their CcSubjs objects. - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcSess objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcSessPeer::addSelectColumns($criteria); - $startcol = (CcSessPeer::NUM_COLUMNS - CcSessPeer::NUM_LAZY_LOAD_COLUMNS); - CcSubjsPeer::addSelectColumns($criteria); - - $criteria->addJoin(CcSessPeer::USERID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcSessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcSessPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - - $cls = CcSessPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcSessPeer::addInstanceToPool($obj1, $key1); - } // if $obj1 already loaded - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 already loaded - - // Add the $obj1 (CcSess) to $obj2 (CcSubjs) - $obj2->addCcSess($obj1); - - } // if joined row was not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - - /** - * Returns the number of rows matching criteria, joining all related tables - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return int Number of matching rows. - */ - public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - // we're going to modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSessPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSessPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria->addJoin(CcSessPeer::USERID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - - /** - * Selects a collection of CcSess objects pre-filled with all related objects. - * - * @param Criteria $criteria - * @param PropelPDO $con - * @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN - * @return array Array of CcSess objects. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN) - { - $criteria = clone $criteria; - - // Set the correct dbName if it has not been overridden - if ($criteria->getDbName() == Propel::getDefaultDB()) { - $criteria->setDbName(self::DATABASE_NAME); - } - - CcSessPeer::addSelectColumns($criteria); - $startcol2 = (CcSessPeer::NUM_COLUMNS - CcSessPeer::NUM_LAZY_LOAD_COLUMNS); - - CcSubjsPeer::addSelectColumns($criteria); - $startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS); - - $criteria->addJoin(CcSessPeer::USERID, CcSubjsPeer::ID, $join_behavior); - - $stmt = BasePeer::doSelect($criteria, $con); - $results = array(); - - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key1 = CcSessPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj1 = CcSessPeer::getInstanceFromPool($key1))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj1->hydrate($row, 0, true); // rehydrate - } else { - $cls = CcSessPeer::getOMClass(false); - - $obj1 = new $cls(); - $obj1->hydrate($row); - CcSessPeer::addInstanceToPool($obj1, $key1); - } // if obj1 already loaded - - // Add objects for joined CcSubjs rows - - $key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2); - if ($key2 !== null) { - $obj2 = CcSubjsPeer::getInstanceFromPool($key2); - if (!$obj2) { - - $cls = CcSubjsPeer::getOMClass(false); - - $obj2 = new $cls(); - $obj2->hydrate($row, $startcol2); - CcSubjsPeer::addInstanceToPool($obj2, $key2); - } // if obj2 loaded - - // Add the $obj1 (CcSess) to the collection in $obj2 (CcSubjs) - $obj2->addCcSess($obj1); - } // if joined row not null - - $results[] = $obj1; - } - $stmt->closeCursor(); - return $results; - } - - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcSessPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcSessPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcSessTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcSessPeer::CLASS_DEFAULT : CcSessPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcSess or Criteria object. - * - * @param mixed $values Criteria or CcSess object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcSess object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcSess or Criteria object. - * - * @param mixed $values Criteria or CcSess object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcSessPeer::SESSID); - $value = $criteria->remove(CcSessPeer::SESSID); - if ($value) { - $selectCriteria->add(CcSessPeer::SESSID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcSessPeer::TABLE_NAME); - } - - } else { // $values is CcSess object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_sess table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcSessPeer::TABLE_NAME, $con, CcSessPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcSessPeer::clearInstancePool(); - CcSessPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcSess or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcSess object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcSessPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcSess) { // it's a model object - // invalidate the cache for this single object - CcSessPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcSessPeer::SESSID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcSessPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcSessPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcSess object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcSess $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcSess $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcSessPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcSessPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcSessPeer::DATABASE_NAME, CcSessPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param string $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcSess - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcSessPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcSessPeer::DATABASE_NAME); - $criteria->add(CcSessPeer::SESSID, $pk); - - $v = CcSessPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSessPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcSessPeer::DATABASE_NAME); - $criteria->add(CcSessPeer::SESSID, $pks, Criteria::IN); - $objs = CcSessPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcSessPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcSessPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSessQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSessQuery.php deleted file mode 100644 index f2462c695..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSessQuery.php +++ /dev/null @@ -1,334 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcSess|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcSessPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcSessPeer::SESSID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcSessPeer::SESSID, $keys, Criteria::IN); - } - - /** - * Filter the query on the sessid column - * - * @param string $sessid The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterBySessid($sessid = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($sessid)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $sessid)) { - $sessid = str_replace('*', '%', $sessid); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSessPeer::SESSID, $sessid, $comparison); - } - - /** - * Filter the query on the userid column - * - * @param int|array $userid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByUserid($userid = null, $comparison = null) - { - if (is_array($userid)) { - $useMinMax = false; - if (isset($userid['min'])) { - $this->addUsingAlias(CcSessPeer::USERID, $userid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($userid['max'])) { - $this->addUsingAlias(CcSessPeer::USERID, $userid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSessPeer::USERID, $userid, $comparison); - } - - /** - * Filter the query on the login column - * - * @param string $login The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByLogin($login = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($login)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $login)) { - $login = str_replace('*', '%', $login); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSessPeer::LOGIN, $login, $comparison); - } - - /** - * Filter the query on the ts column - * - * @param string|array $ts The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByTs($ts = null, $comparison = null) - { - if (is_array($ts)) { - $useMinMax = false; - if (isset($ts['min'])) { - $this->addUsingAlias(CcSessPeer::TS, $ts['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($ts['max'])) { - $this->addUsingAlias(CcSessPeer::TS, $ts['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSessPeer::TS, $ts, $comparison); - } - - /** - * Filter the query by a related CcSubjs object - * - * @param CcSubjs $ccSubjs the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSessQuery The current query, for fluid interface - */ - public function filterByCcSubjs($ccSubjs, $comparison = null) - { - return $this - ->addUsingAlias(CcSessPeer::USERID, $ccSubjs->getId(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSubjs relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSessQuery The current query, for fluid interface - */ - public function joinCcSubjs($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSubjs'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSubjs'); - } - - return $this; - } - - /** - * Use the CcSubjs relation CcSubjs object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery A secondary query class using the current class as primary query - */ - public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSubjs($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery'); - } - - /** - * Exclude object from result - * - * @param CcSess $ccSess Object to remove from the list of results - * - * @return CcSessQuery The current query, for fluid interface - */ - public function prune($ccSess = null) - { - if ($ccSess) { - $this->addUsingAlias(CcSessPeer::SESSID, $ccSess->getSessid(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcSessQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSmemb.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSmemb.php deleted file mode 100644 index bb98b5c1e..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSmemb.php +++ /dev/null @@ -1,891 +0,0 @@ -uid = 0; - $this->gid = 0; - $this->level = 0; - } - - /** - * Initializes internal state of BaseCcSmemb object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * Get the [uid] column value. - * - * @return int - */ - public function getUid() - { - return $this->uid; - } - - /** - * Get the [gid] column value. - * - * @return int - */ - public function getGid() - { - return $this->gid; - } - - /** - * Get the [level] column value. - * - * @return int - */ - public function getLevel() - { - return $this->level; - } - - /** - * Get the [mid] column value. - * - * @return int - */ - public function getMid() - { - return $this->mid; - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcSmemb The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcSmembPeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [uid] column. - * - * @param int $v new value - * @return CcSmemb The current object (for fluent API support) - */ - public function setUid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->uid !== $v || $this->isNew()) { - $this->uid = $v; - $this->modifiedColumns[] = CcSmembPeer::UID; - } - - return $this; - } // setUid() - - /** - * Set the value of [gid] column. - * - * @param int $v new value - * @return CcSmemb The current object (for fluent API support) - */ - public function setGid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->gid !== $v || $this->isNew()) { - $this->gid = $v; - $this->modifiedColumns[] = CcSmembPeer::GID; - } - - return $this; - } // setGid() - - /** - * Set the value of [level] column. - * - * @param int $v new value - * @return CcSmemb The current object (for fluent API support) - */ - public function setLevel($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->level !== $v || $this->isNew()) { - $this->level = $v; - $this->modifiedColumns[] = CcSmembPeer::LEVEL; - } - - return $this; - } // setLevel() - - /** - * Set the value of [mid] column. - * - * @param int $v new value - * @return CcSmemb The current object (for fluent API support) - */ - public function setMid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->mid !== $v) { - $this->mid = $v; - $this->modifiedColumns[] = CcSmembPeer::MID; - } - - return $this; - } // setMid() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->uid !== 0) { - return false; - } - - if ($this->gid !== 0) { - return false; - } - - if ($this->level !== 0) { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->uid = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; - $this->gid = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null; - $this->level = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null; - $this->mid = ($row[$startcol + 4] !== null) ? (int) $row[$startcol + 4] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 5; // 5 = CcSmembPeer::NUM_COLUMNS - CcSmembPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcSmemb object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcSmembPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcSmembQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcSmembPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows = 1; - $this->setNew(false); - } else { - $affectedRows = CcSmembPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - if (($retval = CcSmembPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSmembPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getUid(); - break; - case 2: - return $this->getGid(); - break; - case 3: - return $this->getLevel(); - break; - case 4: - return $this->getMid(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true) - { - $keys = CcSmembPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getUid(), - $keys[2] => $this->getGid(), - $keys[3] => $this->getLevel(), - $keys[4] => $this->getMid(), - ); - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSmembPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setUid($value); - break; - case 2: - $this->setGid($value); - break; - case 3: - $this->setLevel($value); - break; - case 4: - $this->setMid($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcSmembPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setUid($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setGid($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setLevel($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setMid($arr[$keys[4]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcSmembPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcSmembPeer::ID)) $criteria->add(CcSmembPeer::ID, $this->id); - if ($this->isColumnModified(CcSmembPeer::UID)) $criteria->add(CcSmembPeer::UID, $this->uid); - if ($this->isColumnModified(CcSmembPeer::GID)) $criteria->add(CcSmembPeer::GID, $this->gid); - if ($this->isColumnModified(CcSmembPeer::LEVEL)) $criteria->add(CcSmembPeer::LEVEL, $this->level); - if ($this->isColumnModified(CcSmembPeer::MID)) $criteria->add(CcSmembPeer::MID, $this->mid); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcSmembPeer::DATABASE_NAME); - $criteria->add(CcSmembPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcSmemb (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setId($this->id); - $copyObj->setUid($this->uid); - $copyObj->setGid($this->gid); - $copyObj->setLevel($this->level); - $copyObj->setMid($this->mid); - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcSmemb Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcSmembPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcSmembPeer(); - } - return self::$peer; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->uid = null; - $this->gid = null; - $this->level = null; - $this->mid = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcSmemb diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSmembPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSmembPeer.php deleted file mode 100644 index 152440c7e..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSmembPeer.php +++ /dev/null @@ -1,750 +0,0 @@ - array ('Id', 'Uid', 'Gid', 'Level', 'Mid', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'uid', 'gid', 'level', 'mid', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::UID, self::GID, self::LEVEL, self::MID, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'UID', 'GID', 'LEVEL', 'MID', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'uid', 'gid', 'level', 'mid', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Uid' => 1, 'Gid' => 2, 'Level' => 3, 'Mid' => 4, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'uid' => 1, 'gid' => 2, 'level' => 3, 'mid' => 4, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::UID => 1, self::GID => 2, self::LEVEL => 3, self::MID => 4, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'UID' => 1, 'GID' => 2, 'LEVEL' => 3, 'MID' => 4, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'uid' => 1, 'gid' => 2, 'level' => 3, 'mid' => 4, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcSmembPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcSmembPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcSmembPeer::ID); - $criteria->addSelectColumn(CcSmembPeer::UID); - $criteria->addSelectColumn(CcSmembPeer::GID); - $criteria->addSelectColumn(CcSmembPeer::LEVEL); - $criteria->addSelectColumn(CcSmembPeer::MID); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.UID'); - $criteria->addSelectColumn($alias . '.GID'); - $criteria->addSelectColumn($alias . '.LEVEL'); - $criteria->addSelectColumn($alias . '.MID'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSmembPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSmembPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcSmemb - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcSmembPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcSmembPeer::populateObjects(CcSmembPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcSmembPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcSmemb $value A CcSmemb object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcSmemb $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcSmemb object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcSmemb) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSmemb object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcSmemb Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_smemb - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcSmembPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcSmembPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcSmembPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcSmembPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcSmemb object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcSmembPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcSmembPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcSmembPeer::NUM_COLUMNS; - } else { - $cls = CcSmembPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcSmembPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcSmembPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcSmembPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcSmembTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcSmembPeer::CLASS_DEFAULT : CcSmembPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcSmemb or Criteria object. - * - * @param mixed $values Criteria or CcSmemb object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcSmemb object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcSmemb or Criteria object. - * - * @param mixed $values Criteria or CcSmemb object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcSmembPeer::ID); - $value = $criteria->remove(CcSmembPeer::ID); - if ($value) { - $selectCriteria->add(CcSmembPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcSmembPeer::TABLE_NAME); - } - - } else { // $values is CcSmemb object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_smemb table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcSmembPeer::TABLE_NAME, $con, CcSmembPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcSmembPeer::clearInstancePool(); - CcSmembPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcSmemb or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcSmemb object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcSmembPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcSmemb) { // it's a model object - // invalidate the cache for this single object - CcSmembPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcSmembPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcSmembPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcSmembPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcSmemb object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcSmemb $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcSmemb $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcSmembPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcSmembPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcSmembPeer::DATABASE_NAME, CcSmembPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcSmemb - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcSmembPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcSmembPeer::DATABASE_NAME); - $criteria->add(CcSmembPeer::ID, $pk); - - $v = CcSmembPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcSmembPeer::DATABASE_NAME); - $criteria->add(CcSmembPeer::ID, $pks, Criteria::IN); - $objs = CcSmembPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcSmembPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcSmembPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSmembQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSmembQuery.php deleted file mode 100644 index c0ac62c18..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSmembQuery.php +++ /dev/null @@ -1,305 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcSmemb|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcSmembPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcSmembPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcSmembPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcSmembPeer::ID, $id, $comparison); - } - - /** - * Filter the query on the uid column - * - * @param int|array $uid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByUid($uid = null, $comparison = null) - { - if (is_array($uid)) { - $useMinMax = false; - if (isset($uid['min'])) { - $this->addUsingAlias(CcSmembPeer::UID, $uid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($uid['max'])) { - $this->addUsingAlias(CcSmembPeer::UID, $uid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSmembPeer::UID, $uid, $comparison); - } - - /** - * Filter the query on the gid column - * - * @param int|array $gid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByGid($gid = null, $comparison = null) - { - if (is_array($gid)) { - $useMinMax = false; - if (isset($gid['min'])) { - $this->addUsingAlias(CcSmembPeer::GID, $gid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($gid['max'])) { - $this->addUsingAlias(CcSmembPeer::GID, $gid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSmembPeer::GID, $gid, $comparison); - } - - /** - * Filter the query on the level column - * - * @param int|array $level The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByLevel($level = null, $comparison = null) - { - if (is_array($level)) { - $useMinMax = false; - if (isset($level['min'])) { - $this->addUsingAlias(CcSmembPeer::LEVEL, $level['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($level['max'])) { - $this->addUsingAlias(CcSmembPeer::LEVEL, $level['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSmembPeer::LEVEL, $level, $comparison); - } - - /** - * Filter the query on the mid column - * - * @param int|array $mid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function filterByMid($mid = null, $comparison = null) - { - if (is_array($mid)) { - $useMinMax = false; - if (isset($mid['min'])) { - $this->addUsingAlias(CcSmembPeer::MID, $mid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($mid['max'])) { - $this->addUsingAlias(CcSmembPeer::MID, $mid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSmembPeer::MID, $mid, $comparison); - } - - /** - * Exclude object from result - * - * @param CcSmemb $ccSmemb Object to remove from the list of results - * - * @return CcSmembQuery The current query, for fluid interface - */ - public function prune($ccSmemb = null) - { - if ($ccSmemb) { - $this->addUsingAlias(CcSmembPeer::ID, $ccSmemb->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcSmembQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjs.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSubjs.php deleted file mode 100644 index 58796a099..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjs.php +++ /dev/null @@ -1,1969 +0,0 @@ -login = ''; - $this->pass = ''; - $this->type = 'U'; - $this->realname = ''; - } - - /** - * Initializes internal state of BaseCcSubjs object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * Get the [login] column value. - * - * @return string - */ - public function getLogin() - { - return $this->login; - } - - /** - * Get the [pass] column value. - * - * @return string - */ - public function getPass() - { - return $this->pass; - } - - /** - * Get the [type] column value. - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Get the [realname] column value. - * - * @return string - */ - public function getRealname() - { - return $this->realname; - } - - /** - * Get the [optionally formatted] temporal [lastlogin] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getLastlogin($format = 'Y-m-d H:i:s') - { - if ($this->lastlogin === null) { - return null; - } - - - - try { - $dt = new DateTime($this->lastlogin); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->lastlogin, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [lastfail] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getLastfail($format = 'Y-m-d H:i:s') - { - if ($this->lastfail === null) { - return null; - } - - - - try { - $dt = new DateTime($this->lastfail); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->lastfail, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcSubjs The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcSubjsPeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [login] column. - * - * @param string $v new value - * @return CcSubjs The current object (for fluent API support) - */ - public function setLogin($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->login !== $v || $this->isNew()) { - $this->login = $v; - $this->modifiedColumns[] = CcSubjsPeer::LOGIN; - } - - return $this; - } // setLogin() - - /** - * Set the value of [pass] column. - * - * @param string $v new value - * @return CcSubjs The current object (for fluent API support) - */ - public function setPass($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->pass !== $v || $this->isNew()) { - $this->pass = $v; - $this->modifiedColumns[] = CcSubjsPeer::PASS; - } - - return $this; - } // setPass() - - /** - * Set the value of [type] column. - * - * @param string $v new value - * @return CcSubjs The current object (for fluent API support) - */ - public function setType($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->type !== $v || $this->isNew()) { - $this->type = $v; - $this->modifiedColumns[] = CcSubjsPeer::TYPE; - } - - return $this; - } // setType() - - /** - * Set the value of [realname] column. - * - * @param string $v new value - * @return CcSubjs The current object (for fluent API support) - */ - public function setRealname($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->realname !== $v || $this->isNew()) { - $this->realname = $v; - $this->modifiedColumns[] = CcSubjsPeer::REALNAME; - } - - return $this; - } // setRealname() - - /** - * Sets the value of [lastlogin] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSubjs The current object (for fluent API support) - */ - public function setLastlogin($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->lastlogin !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->lastlogin !== null && $tmpDt = new DateTime($this->lastlogin)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->lastlogin = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcSubjsPeer::LASTLOGIN; - } - } // if either are not null - - return $this; - } // setLastlogin() - - /** - * Sets the value of [lastfail] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcSubjs The current object (for fluent API support) - */ - public function setLastfail($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->lastfail !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->lastfail !== null && $tmpDt = new DateTime($this->lastfail)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->lastfail = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcSubjsPeer::LASTFAIL; - } - } // if either are not null - - return $this; - } // setLastfail() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->login !== '') { - return false; - } - - if ($this->pass !== '') { - return false; - } - - if ($this->type !== 'U') { - return false; - } - - if ($this->realname !== '') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->login = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->pass = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->type = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->realname = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->lastlogin = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->lastfail = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 7; // 7 = CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcSubjs object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcSubjsPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->collCcAccesss = null; - - $this->collCcFiless = null; - - $this->collCcPermss = null; - - $this->collCcPlaylists = null; - - $this->collCcPrefs = null; - - $this->collCcSesss = null; - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcSubjsQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcSubjsPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows = 1; - $this->setNew(false); - } else { - $affectedRows = CcSubjsPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - if ($this->collCcAccesss !== null) { - foreach ($this->collCcAccesss as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->collCcFiless !== null) { - foreach ($this->collCcFiless as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->collCcPermss !== null) { - foreach ($this->collCcPermss as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->collCcPlaylists !== null) { - foreach ($this->collCcPlaylists as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->collCcPrefs !== null) { - foreach ($this->collCcPrefs as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->collCcSesss !== null) { - foreach ($this->collCcSesss as $referrerFK) { - if (!$referrerFK->isDeleted()) { - $affectedRows += $referrerFK->save($con); - } - } - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - if (($retval = CcSubjsPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - if ($this->collCcAccesss !== null) { - foreach ($this->collCcAccesss as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - if ($this->collCcFiless !== null) { - foreach ($this->collCcFiless as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - if ($this->collCcPermss !== null) { - foreach ($this->collCcPermss as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - if ($this->collCcPlaylists !== null) { - foreach ($this->collCcPlaylists as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - if ($this->collCcPrefs !== null) { - foreach ($this->collCcPrefs as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - if ($this->collCcSesss !== null) { - foreach ($this->collCcSesss as $referrerFK) { - if (!$referrerFK->validate($columns)) { - $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures()); - } - } - } - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSubjsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getLogin(); - break; - case 2: - return $this->getPass(); - break; - case 3: - return $this->getType(); - break; - case 4: - return $this->getRealname(); - break; - case 5: - return $this->getLastlogin(); - break; - case 6: - return $this->getLastfail(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true) - { - $keys = CcSubjsPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getLogin(), - $keys[2] => $this->getPass(), - $keys[3] => $this->getType(), - $keys[4] => $this->getRealname(), - $keys[5] => $this->getLastlogin(), - $keys[6] => $this->getLastfail(), - ); - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcSubjsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setLogin($value); - break; - case 2: - $this->setPass($value); - break; - case 3: - $this->setType($value); - break; - case 4: - $this->setRealname($value); - break; - case 5: - $this->setLastlogin($value); - break; - case 6: - $this->setLastfail($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcSubjsPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setLogin($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setPass($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setType($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setRealname($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setLastlogin($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setLastfail($arr[$keys[6]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcSubjsPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcSubjsPeer::ID)) $criteria->add(CcSubjsPeer::ID, $this->id); - if ($this->isColumnModified(CcSubjsPeer::LOGIN)) $criteria->add(CcSubjsPeer::LOGIN, $this->login); - if ($this->isColumnModified(CcSubjsPeer::PASS)) $criteria->add(CcSubjsPeer::PASS, $this->pass); - if ($this->isColumnModified(CcSubjsPeer::TYPE)) $criteria->add(CcSubjsPeer::TYPE, $this->type); - if ($this->isColumnModified(CcSubjsPeer::REALNAME)) $criteria->add(CcSubjsPeer::REALNAME, $this->realname); - if ($this->isColumnModified(CcSubjsPeer::LASTLOGIN)) $criteria->add(CcSubjsPeer::LASTLOGIN, $this->lastlogin); - if ($this->isColumnModified(CcSubjsPeer::LASTFAIL)) $criteria->add(CcSubjsPeer::LASTFAIL, $this->lastfail); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcSubjsPeer::DATABASE_NAME); - $criteria->add(CcSubjsPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcSubjs (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setId($this->id); - $copyObj->setLogin($this->login); - $copyObj->setPass($this->pass); - $copyObj->setType($this->type); - $copyObj->setRealname($this->realname); - $copyObj->setLastlogin($this->lastlogin); - $copyObj->setLastfail($this->lastfail); - - if ($deepCopy) { - // important: temporarily setNew(false) because this affects the behavior of - // the getter/setter methods for fkey referrer objects. - $copyObj->setNew(false); - - foreach ($this->getCcAccesss() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcAccess($relObj->copy($deepCopy)); - } - } - - foreach ($this->getCcFiless() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcFiles($relObj->copy($deepCopy)); - } - } - - foreach ($this->getCcPermss() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcPerms($relObj->copy($deepCopy)); - } - } - - foreach ($this->getCcPlaylists() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcPlaylist($relObj->copy($deepCopy)); - } - } - - foreach ($this->getCcPrefs() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcPref($relObj->copy($deepCopy)); - } - } - - foreach ($this->getCcSesss() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addCcSess($relObj->copy($deepCopy)); - } - } - - } // if ($deepCopy) - - - $copyObj->setNew(true); - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcSubjs Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcSubjsPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcSubjsPeer(); - } - return self::$peer; - } - - /** - * Clears out the collCcAccesss collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcAccesss() - */ - public function clearCcAccesss() - { - $this->collCcAccesss = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcAccesss collection. - * - * By default this just sets the collCcAccesss collection to an empty array (like clearcollCcAccesss()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcAccesss() - { - $this->collCcAccesss = new PropelObjectCollection(); - $this->collCcAccesss->setModel('CcAccess'); - } - - /** - * Gets an array of CcAccess objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcAccess[] List of CcAccess objects - * @throws PropelException - */ - public function getCcAccesss($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcAccesss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcAccesss) { - // return empty collection - $this->initCcAccesss(); - } else { - $collCcAccesss = CcAccessQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcAccesss; - } - $this->collCcAccesss = $collCcAccesss; - } - } - return $this->collCcAccesss; - } - - /** - * Returns the number of related CcAccess objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcAccess objects. - * @throws PropelException - */ - public function countCcAccesss(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcAccesss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcAccesss) { - return 0; - } else { - $query = CcAccessQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcAccesss); - } - } - - /** - * Method called to associate a CcAccess object to this object - * through the CcAccess foreign key attribute. - * - * @param CcAccess $l CcAccess - * @return void - * @throws PropelException - */ - public function addCcAccess(CcAccess $l) - { - if ($this->collCcAccesss === null) { - $this->initCcAccesss(); - } - if (!$this->collCcAccesss->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcAccesss[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears out the collCcFiless collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcFiless() - */ - public function clearCcFiless() - { - $this->collCcFiless = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcFiless collection. - * - * By default this just sets the collCcFiless collection to an empty array (like clearcollCcFiless()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcFiless() - { - $this->collCcFiless = new PropelObjectCollection(); - $this->collCcFiless->setModel('CcFiles'); - } - - /** - * Gets an array of CcFiles objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcFiles[] List of CcFiles objects - * @throws PropelException - */ - public function getCcFiless($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcFiless || null !== $criteria) { - if ($this->isNew() && null === $this->collCcFiless) { - // return empty collection - $this->initCcFiless(); - } else { - $collCcFiless = CcFilesQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcFiless; - } - $this->collCcFiless = $collCcFiless; - } - } - return $this->collCcFiless; - } - - /** - * Returns the number of related CcFiles objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcFiles objects. - * @throws PropelException - */ - public function countCcFiless(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcFiless || null !== $criteria) { - if ($this->isNew() && null === $this->collCcFiless) { - return 0; - } else { - $query = CcFilesQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcFiless); - } - } - - /** - * Method called to associate a CcFiles object to this object - * through the CcFiles foreign key attribute. - * - * @param CcFiles $l CcFiles - * @return void - * @throws PropelException - */ - public function addCcFiles(CcFiles $l) - { - if ($this->collCcFiless === null) { - $this->initCcFiless(); - } - if (!$this->collCcFiless->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcFiless[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears out the collCcPermss collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcPermss() - */ - public function clearCcPermss() - { - $this->collCcPermss = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcPermss collection. - * - * By default this just sets the collCcPermss collection to an empty array (like clearcollCcPermss()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcPermss() - { - $this->collCcPermss = new PropelObjectCollection(); - $this->collCcPermss->setModel('CcPerms'); - } - - /** - * Gets an array of CcPerms objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcPerms[] List of CcPerms objects - * @throws PropelException - */ - public function getCcPermss($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcPermss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPermss) { - // return empty collection - $this->initCcPermss(); - } else { - $collCcPermss = CcPermsQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcPermss; - } - $this->collCcPermss = $collCcPermss; - } - } - return $this->collCcPermss; - } - - /** - * Returns the number of related CcPerms objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcPerms objects. - * @throws PropelException - */ - public function countCcPermss(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcPermss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPermss) { - return 0; - } else { - $query = CcPermsQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcPermss); - } - } - - /** - * Method called to associate a CcPerms object to this object - * through the CcPerms foreign key attribute. - * - * @param CcPerms $l CcPerms - * @return void - * @throws PropelException - */ - public function addCcPerms(CcPerms $l) - { - if ($this->collCcPermss === null) { - $this->initCcPermss(); - } - if (!$this->collCcPermss->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcPermss[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears out the collCcPlaylists collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcPlaylists() - */ - public function clearCcPlaylists() - { - $this->collCcPlaylists = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcPlaylists collection. - * - * By default this just sets the collCcPlaylists collection to an empty array (like clearcollCcPlaylists()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcPlaylists() - { - $this->collCcPlaylists = new PropelObjectCollection(); - $this->collCcPlaylists->setModel('CcPlaylist'); - } - - /** - * Gets an array of CcPlaylist objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcPlaylist[] List of CcPlaylist objects - * @throws PropelException - */ - public function getCcPlaylists($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcPlaylists || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylists) { - // return empty collection - $this->initCcPlaylists(); - } else { - $collCcPlaylists = CcPlaylistQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcPlaylists; - } - $this->collCcPlaylists = $collCcPlaylists; - } - } - return $this->collCcPlaylists; - } - - /** - * Returns the number of related CcPlaylist objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcPlaylist objects. - * @throws PropelException - */ - public function countCcPlaylists(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcPlaylists || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPlaylists) { - return 0; - } else { - $query = CcPlaylistQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcPlaylists); - } - } - - /** - * Method called to associate a CcPlaylist object to this object - * through the CcPlaylist foreign key attribute. - * - * @param CcPlaylist $l CcPlaylist - * @return void - * @throws PropelException - */ - public function addCcPlaylist(CcPlaylist $l) - { - if ($this->collCcPlaylists === null) { - $this->initCcPlaylists(); - } - if (!$this->collCcPlaylists->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcPlaylists[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears out the collCcPrefs collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcPrefs() - */ - public function clearCcPrefs() - { - $this->collCcPrefs = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcPrefs collection. - * - * By default this just sets the collCcPrefs collection to an empty array (like clearcollCcPrefs()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcPrefs() - { - $this->collCcPrefs = new PropelObjectCollection(); - $this->collCcPrefs->setModel('CcPref'); - } - - /** - * Gets an array of CcPref objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcPref[] List of CcPref objects - * @throws PropelException - */ - public function getCcPrefs($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcPrefs || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPrefs) { - // return empty collection - $this->initCcPrefs(); - } else { - $collCcPrefs = CcPrefQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcPrefs; - } - $this->collCcPrefs = $collCcPrefs; - } - } - return $this->collCcPrefs; - } - - /** - * Returns the number of related CcPref objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcPref objects. - * @throws PropelException - */ - public function countCcPrefs(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcPrefs || null !== $criteria) { - if ($this->isNew() && null === $this->collCcPrefs) { - return 0; - } else { - $query = CcPrefQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcPrefs); - } - } - - /** - * Method called to associate a CcPref object to this object - * through the CcPref foreign key attribute. - * - * @param CcPref $l CcPref - * @return void - * @throws PropelException - */ - public function addCcPref(CcPref $l) - { - if ($this->collCcPrefs === null) { - $this->initCcPrefs(); - } - if (!$this->collCcPrefs->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcPrefs[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears out the collCcSesss collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addCcSesss() - */ - public function clearCcSesss() - { - $this->collCcSesss = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Initializes the collCcSesss collection. - * - * By default this just sets the collCcSesss collection to an empty array (like clearcollCcSesss()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initCcSesss() - { - $this->collCcSesss = new PropelObjectCollection(); - $this->collCcSesss->setModel('CcSess'); - } - - /** - * Gets an array of CcSess objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this CcSubjs is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param PropelPDO $con optional connection object - * @return PropelCollection|array CcSess[] List of CcSess objects - * @throws PropelException - */ - public function getCcSesss($criteria = null, PropelPDO $con = null) - { - if(null === $this->collCcSesss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcSesss) { - // return empty collection - $this->initCcSesss(); - } else { - $collCcSesss = CcSessQuery::create(null, $criteria) - ->filterByCcSubjs($this) - ->find($con); - if (null !== $criteria) { - return $collCcSesss; - } - $this->collCcSesss = $collCcSesss; - } - } - return $this->collCcSesss; - } - - /** - * Returns the number of related CcSess objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param PropelPDO $con - * @return int Count of related CcSess objects. - * @throws PropelException - */ - public function countCcSesss(Criteria $criteria = null, $distinct = false, PropelPDO $con = null) - { - if(null === $this->collCcSesss || null !== $criteria) { - if ($this->isNew() && null === $this->collCcSesss) { - return 0; - } else { - $query = CcSessQuery::create(null, $criteria); - if($distinct) { - $query->distinct(); - } - return $query - ->filterByCcSubjs($this) - ->count($con); - } - } else { - return count($this->collCcSesss); - } - } - - /** - * Method called to associate a CcSess object to this object - * through the CcSess foreign key attribute. - * - * @param CcSess $l CcSess - * @return void - * @throws PropelException - */ - public function addCcSess(CcSess $l) - { - if ($this->collCcSesss === null) { - $this->initCcSesss(); - } - if (!$this->collCcSesss->contains($l)) { // only add it if the **same** object is not already associated - $this->collCcSesss[]= $l; - $l->setCcSubjs($this); - } - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->login = null; - $this->pass = null; - $this->type = null; - $this->realname = null; - $this->lastlogin = null; - $this->lastfail = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - if ($this->collCcAccesss) { - foreach ((array) $this->collCcAccesss as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collCcFiless) { - foreach ((array) $this->collCcFiless as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collCcPermss) { - foreach ((array) $this->collCcPermss as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collCcPlaylists) { - foreach ((array) $this->collCcPlaylists as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collCcPrefs) { - foreach ((array) $this->collCcPrefs as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collCcSesss) { - foreach ((array) $this->collCcSesss as $o) { - $o->clearAllReferences($deep); - } - } - } // if ($deep) - - $this->collCcAccesss = null; - $this->collCcFiless = null; - $this->collCcPermss = null; - $this->collCcPlaylists = null; - $this->collCcPrefs = null; - $this->collCcSesss = null; - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcSubjs diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsPeer.php deleted file mode 100644 index f4bc75f9f..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsPeer.php +++ /dev/null @@ -1,769 +0,0 @@ - array ('Id', 'Login', 'Pass', 'Type', 'Realname', 'Lastlogin', 'Lastfail', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'login', 'pass', 'type', 'realname', 'lastlogin', 'lastfail', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::LOGIN, self::PASS, self::TYPE, self::REALNAME, self::LASTLOGIN, self::LASTFAIL, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'LOGIN', 'PASS', 'TYPE', 'REALNAME', 'LASTLOGIN', 'LASTFAIL', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'login', 'pass', 'type', 'realname', 'lastlogin', 'lastfail', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Login' => 1, 'Pass' => 2, 'Type' => 3, 'Realname' => 4, 'Lastlogin' => 5, 'Lastfail' => 6, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'login' => 1, 'pass' => 2, 'type' => 3, 'realname' => 4, 'lastlogin' => 5, 'lastfail' => 6, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::LOGIN => 1, self::PASS => 2, self::TYPE => 3, self::REALNAME => 4, self::LASTLOGIN => 5, self::LASTFAIL => 6, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'LOGIN' => 1, 'PASS' => 2, 'TYPE' => 3, 'REALNAME' => 4, 'LASTLOGIN' => 5, 'LASTFAIL' => 6, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'login' => 1, 'pass' => 2, 'type' => 3, 'realname' => 4, 'lastlogin' => 5, 'lastfail' => 6, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcSubjsPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcSubjsPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcSubjsPeer::ID); - $criteria->addSelectColumn(CcSubjsPeer::LOGIN); - $criteria->addSelectColumn(CcSubjsPeer::PASS); - $criteria->addSelectColumn(CcSubjsPeer::TYPE); - $criteria->addSelectColumn(CcSubjsPeer::REALNAME); - $criteria->addSelectColumn(CcSubjsPeer::LASTLOGIN); - $criteria->addSelectColumn(CcSubjsPeer::LASTFAIL); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.LOGIN'); - $criteria->addSelectColumn($alias . '.PASS'); - $criteria->addSelectColumn($alias . '.TYPE'); - $criteria->addSelectColumn($alias . '.REALNAME'); - $criteria->addSelectColumn($alias . '.LASTLOGIN'); - $criteria->addSelectColumn($alias . '.LASTFAIL'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcSubjsPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcSubjsPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcSubjs - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcSubjsPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcSubjsPeer::populateObjects(CcSubjsPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcSubjsPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcSubjs $value A CcSubjs object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcSubjs $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcSubjs object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcSubjs) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSubjs object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcSubjs Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_subjs - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - // Invalidate objects in CcPermsPeer instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - CcPermsPeer::clearInstancePool(); - // Invalidate objects in CcPrefPeer instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - CcPrefPeer::clearInstancePool(); - // Invalidate objects in CcSessPeer instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - CcSessPeer::clearInstancePool(); - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcSubjsPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcSubjsPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcSubjsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcSubjsPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcSubjs object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcSubjsPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcSubjsPeer::NUM_COLUMNS; - } else { - $cls = CcSubjsPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcSubjsPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcSubjsPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcSubjsPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcSubjsTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcSubjsPeer::CLASS_DEFAULT : CcSubjsPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcSubjs or Criteria object. - * - * @param mixed $values Criteria or CcSubjs object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcSubjs object - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcSubjs or Criteria object. - * - * @param mixed $values Criteria or CcSubjs object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcSubjsPeer::ID); - $value = $criteria->remove(CcSubjsPeer::ID); - if ($value) { - $selectCriteria->add(CcSubjsPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcSubjsPeer::TABLE_NAME); - } - - } else { // $values is CcSubjs object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_subjs table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcSubjsPeer::TABLE_NAME, $con, CcSubjsPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcSubjsPeer::clearInstancePool(); - CcSubjsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcSubjs or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcSubjs object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcSubjsPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcSubjs) { // it's a model object - // invalidate the cache for this single object - CcSubjsPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcSubjsPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcSubjsPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcSubjsPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcSubjs object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcSubjs $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcSubjs $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcSubjsPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcSubjsPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcSubjsPeer::DATABASE_NAME, CcSubjsPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcSubjs - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcSubjsPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcSubjsPeer::DATABASE_NAME); - $criteria->add(CcSubjsPeer::ID, $pk); - - $v = CcSubjsPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcSubjsPeer::DATABASE_NAME); - $criteria->add(CcSubjsPeer::ID, $pks, Criteria::IN); - $objs = CcSubjsPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcSubjsPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcSubjsPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsQuery.php deleted file mode 100644 index af3b6fe5e..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcSubjsQuery.php +++ /dev/null @@ -1,747 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcSubjs|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcSubjsPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcSubjsPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcSubjsPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcSubjsPeer::ID, $id, $comparison); - } - - /** - * Filter the query on the login column - * - * @param string $login The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByLogin($login = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($login)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $login)) { - $login = str_replace('*', '%', $login); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSubjsPeer::LOGIN, $login, $comparison); - } - - /** - * Filter the query on the pass column - * - * @param string $pass The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByPass($pass = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($pass)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $pass)) { - $pass = str_replace('*', '%', $pass); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSubjsPeer::PASS, $pass, $comparison); - } - - /** - * Filter the query on the type column - * - * @param string $type The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByType($type = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($type)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $type)) { - $type = str_replace('*', '%', $type); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSubjsPeer::TYPE, $type, $comparison); - } - - /** - * Filter the query on the realname column - * - * @param string $realname The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByRealname($realname = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($realname)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $realname)) { - $realname = str_replace('*', '%', $realname); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcSubjsPeer::REALNAME, $realname, $comparison); - } - - /** - * Filter the query on the lastlogin column - * - * @param string|array $lastlogin The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByLastlogin($lastlogin = null, $comparison = null) - { - if (is_array($lastlogin)) { - $useMinMax = false; - if (isset($lastlogin['min'])) { - $this->addUsingAlias(CcSubjsPeer::LASTLOGIN, $lastlogin['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($lastlogin['max'])) { - $this->addUsingAlias(CcSubjsPeer::LASTLOGIN, $lastlogin['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSubjsPeer::LASTLOGIN, $lastlogin, $comparison); - } - - /** - * Filter the query on the lastfail column - * - * @param string|array $lastfail The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByLastfail($lastfail = null, $comparison = null) - { - if (is_array($lastfail)) { - $useMinMax = false; - if (isset($lastfail['min'])) { - $this->addUsingAlias(CcSubjsPeer::LASTFAIL, $lastfail['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($lastfail['max'])) { - $this->addUsingAlias(CcSubjsPeer::LASTFAIL, $lastfail['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcSubjsPeer::LASTFAIL, $lastfail, $comparison); - } - - /** - * Filter the query by a related CcAccess object - * - * @param CcAccess $ccAccess the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcAccess($ccAccess, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccAccess->getOwner(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcAccess relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcAccess($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcAccess'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcAccess'); - } - - return $this; - } - - /** - * Use the CcAccess relation CcAccess object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcAccessQuery A secondary query class using the current class as primary query - */ - public function useCcAccessQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcAccess($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcAccess', 'CcAccessQuery'); - } - - /** - * Filter the query by a related CcFiles object - * - * @param CcFiles $ccFiles the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcFiles($ccFiles, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccFiles->getEditedby(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcFiles relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcFiles($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcFiles'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcFiles'); - } - - return $this; - } - - /** - * Use the CcFiles relation CcFiles object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcFilesQuery A secondary query class using the current class as primary query - */ - public function useCcFilesQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcFiles($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcFiles', 'CcFilesQuery'); - } - - /** - * Filter the query by a related CcPerms object - * - * @param CcPerms $ccPerms the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcPerms($ccPerms, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccPerms->getSubj(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPerms relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcPerms($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPerms'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPerms'); - } - - return $this; - } - - /** - * Use the CcPerms relation CcPerms object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPermsQuery A secondary query class using the current class as primary query - */ - public function useCcPermsQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPerms($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPerms', 'CcPermsQuery'); - } - - /** - * Filter the query by a related CcPlaylist object - * - * @param CcPlaylist $ccPlaylist the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcPlaylist($ccPlaylist, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccPlaylist->getDbEditedby(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPlaylist relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcPlaylist($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPlaylist'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPlaylist'); - } - - return $this; - } - - /** - * Use the CcPlaylist relation CcPlaylist object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPlaylistQuery A secondary query class using the current class as primary query - */ - public function useCcPlaylistQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPlaylist($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPlaylist', 'CcPlaylistQuery'); - } - - /** - * Filter the query by a related CcPref object - * - * @param CcPref $ccPref the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcPref($ccPref, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccPref->getSubjid(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcPref relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcPref($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcPref'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcPref'); - } - - return $this; - } - - /** - * Use the CcPref relation CcPref object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcPrefQuery A secondary query class using the current class as primary query - */ - public function useCcPrefQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcPref($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcPref', 'CcPrefQuery'); - } - - /** - * Filter the query by a related CcSess object - * - * @param CcSess $ccSess the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function filterByCcSess($ccSess, $comparison = null) - { - return $this - ->addUsingAlias(CcSubjsPeer::ID, $ccSess->getUserid(), $comparison); - } - - /** - * Adds a JOIN clause to the query using the CcSess relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function joinCcSess($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('CcSess'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'CcSess'); - } - - return $this; - } - - /** - * Use the CcSess relation CcSess object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return CcSessQuery A secondary query class using the current class as primary query - */ - public function useCcSessQuery($relationAlias = '', $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinCcSess($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'CcSess', 'CcSessQuery'); - } - - /** - * Exclude object from result - * - * @param CcSubjs $ccSubjs Object to remove from the list of results - * - * @return CcSubjsQuery The current query, for fluid interface - */ - public function prune($ccSubjs = null) - { - if ($ccSubjs) { - $this->addUsingAlias(CcSubjsPeer::ID, $ccSubjs->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcSubjsQuery diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcTrans.php b/backend/propel-db/build/classes/campcaster/om/BaseCcTrans.php deleted file mode 100644 index e7ce7ef9f..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcTrans.php +++ /dev/null @@ -1,1903 +0,0 @@ -lock = 'N'; - } - - /** - * Initializes internal state of BaseCcTrans object. - * @see applyDefaults() - */ - public function __construct() - { - parent::__construct(); - $this->applyDefaultValues(); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * Get the [trtok] column value. - * - * @return string - */ - public function getTrtok() - { - return $this->trtok; - } - - /** - * Get the [direction] column value. - * - * @return string - */ - public function getDirection() - { - return $this->direction; - } - - /** - * Get the [state] column value. - * - * @return string - */ - public function getState() - { - return $this->state; - } - - /** - * Get the [trtype] column value. - * - * @return string - */ - public function getTrtype() - { - return $this->trtype; - } - - /** - * Get the [lock] column value. - * - * @return string - */ - public function getLock() - { - return $this->lock; - } - - /** - * Get the [target] column value. - * - * @return string - */ - public function getTarget() - { - return $this->target; - } - - /** - * Get the [rtrtok] column value. - * - * @return string - */ - public function getRtrtok() - { - return $this->rtrtok; - } - - /** - * Get the [mdtrtok] column value. - * - * @return string - */ - public function getMdtrtok() - { - return $this->mdtrtok; - } - - /** - * Get the [gunid] column value. - * - * @return string - */ - public function getGunid() - { - return $this->gunid; - } - - /** - * Get the [pdtoken] column value. - * - * @return string - */ - public function getPdtoken() - { - return $this->pdtoken; - } - - /** - * Get the [url] column value. - * - * @return string - */ - public function getUrl() - { - return $this->url; - } - - /** - * Get the [localfile] column value. - * - * @return string - */ - public function getLocalfile() - { - return $this->localfile; - } - - /** - * Get the [fname] column value. - * - * @return string - */ - public function getFname() - { - return $this->fname; - } - - /** - * Get the [title] column value. - * - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Get the [expectedsum] column value. - * - * @return string - */ - public function getExpectedsum() - { - return $this->expectedsum; - } - - /** - * Get the [realsum] column value. - * - * @return string - */ - public function getRealsum() - { - return $this->realsum; - } - - /** - * Get the [expectedsize] column value. - * - * @return int - */ - public function getExpectedsize() - { - return $this->expectedsize; - } - - /** - * Get the [realsize] column value. - * - * @return int - */ - public function getRealsize() - { - return $this->realsize; - } - - /** - * Get the [uid] column value. - * - * @return int - */ - public function getUid() - { - return $this->uid; - } - - /** - * Get the [errmsg] column value. - * - * @return string - */ - public function getErrmsg() - { - return $this->errmsg; - } - - /** - * Get the [jobpid] column value. - * - * @return int - */ - public function getJobpid() - { - return $this->jobpid; - } - - /** - * Get the [optionally formatted] temporal [start] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getStart($format = 'Y-m-d H:i:s') - { - if ($this->start === null) { - return null; - } - - - - try { - $dt = new DateTime($this->start); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->start, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Get the [optionally formatted] temporal [ts] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw DateTime object will be returned. - * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getTs($format = 'Y-m-d H:i:s') - { - if ($this->ts === null) { - return null; - } - - - - try { - $dt = new DateTime($this->ts); - } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ts, true), $x); - } - - if ($format === null) { - // Because propel.useDateTimeClass is TRUE, we return a DateTime object. - return $dt; - } elseif (strpos($format, '%') !== false) { - return strftime($format, $dt->format('U')); - } else { - return $dt->format($format); - } - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = CcTransPeer::ID; - } - - return $this; - } // setId() - - /** - * Set the value of [trtok] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setTrtok($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->trtok !== $v) { - $this->trtok = $v; - $this->modifiedColumns[] = CcTransPeer::TRTOK; - } - - return $this; - } // setTrtok() - - /** - * Set the value of [direction] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setDirection($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->direction !== $v) { - $this->direction = $v; - $this->modifiedColumns[] = CcTransPeer::DIRECTION; - } - - return $this; - } // setDirection() - - /** - * Set the value of [state] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setState($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->state !== $v) { - $this->state = $v; - $this->modifiedColumns[] = CcTransPeer::STATE; - } - - return $this; - } // setState() - - /** - * Set the value of [trtype] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setTrtype($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->trtype !== $v) { - $this->trtype = $v; - $this->modifiedColumns[] = CcTransPeer::TRTYPE; - } - - return $this; - } // setTrtype() - - /** - * Set the value of [lock] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setLock($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->lock !== $v || $this->isNew()) { - $this->lock = $v; - $this->modifiedColumns[] = CcTransPeer::LOCK; - } - - return $this; - } // setLock() - - /** - * Set the value of [target] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setTarget($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->target !== $v) { - $this->target = $v; - $this->modifiedColumns[] = CcTransPeer::TARGET; - } - - return $this; - } // setTarget() - - /** - * Set the value of [rtrtok] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setRtrtok($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->rtrtok !== $v) { - $this->rtrtok = $v; - $this->modifiedColumns[] = CcTransPeer::RTRTOK; - } - - return $this; - } // setRtrtok() - - /** - * Set the value of [mdtrtok] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setMdtrtok($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->mdtrtok !== $v) { - $this->mdtrtok = $v; - $this->modifiedColumns[] = CcTransPeer::MDTRTOK; - } - - return $this; - } // setMdtrtok() - - /** - * Set the value of [gunid] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setGunid($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->gunid !== $v) { - $this->gunid = $v; - $this->modifiedColumns[] = CcTransPeer::GUNID; - } - - return $this; - } // setGunid() - - /** - * Set the value of [pdtoken] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setPdtoken($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->pdtoken !== $v) { - $this->pdtoken = $v; - $this->modifiedColumns[] = CcTransPeer::PDTOKEN; - } - - return $this; - } // setPdtoken() - - /** - * Set the value of [url] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setUrl($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->url !== $v) { - $this->url = $v; - $this->modifiedColumns[] = CcTransPeer::URL; - } - - return $this; - } // setUrl() - - /** - * Set the value of [localfile] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setLocalfile($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->localfile !== $v) { - $this->localfile = $v; - $this->modifiedColumns[] = CcTransPeer::LOCALFILE; - } - - return $this; - } // setLocalfile() - - /** - * Set the value of [fname] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setFname($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->fname !== $v) { - $this->fname = $v; - $this->modifiedColumns[] = CcTransPeer::FNAME; - } - - return $this; - } // setFname() - - /** - * Set the value of [title] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setTitle($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->title !== $v) { - $this->title = $v; - $this->modifiedColumns[] = CcTransPeer::TITLE; - } - - return $this; - } // setTitle() - - /** - * Set the value of [expectedsum] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setExpectedsum($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->expectedsum !== $v) { - $this->expectedsum = $v; - $this->modifiedColumns[] = CcTransPeer::EXPECTEDSUM; - } - - return $this; - } // setExpectedsum() - - /** - * Set the value of [realsum] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setRealsum($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->realsum !== $v) { - $this->realsum = $v; - $this->modifiedColumns[] = CcTransPeer::REALSUM; - } - - return $this; - } // setRealsum() - - /** - * Set the value of [expectedsize] column. - * - * @param int $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setExpectedsize($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->expectedsize !== $v) { - $this->expectedsize = $v; - $this->modifiedColumns[] = CcTransPeer::EXPECTEDSIZE; - } - - return $this; - } // setExpectedsize() - - /** - * Set the value of [realsize] column. - * - * @param int $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setRealsize($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->realsize !== $v) { - $this->realsize = $v; - $this->modifiedColumns[] = CcTransPeer::REALSIZE; - } - - return $this; - } // setRealsize() - - /** - * Set the value of [uid] column. - * - * @param int $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setUid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->uid !== $v) { - $this->uid = $v; - $this->modifiedColumns[] = CcTransPeer::UID; - } - - return $this; - } // setUid() - - /** - * Set the value of [errmsg] column. - * - * @param string $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setErrmsg($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->errmsg !== $v) { - $this->errmsg = $v; - $this->modifiedColumns[] = CcTransPeer::ERRMSG; - } - - return $this; - } // setErrmsg() - - /** - * Set the value of [jobpid] column. - * - * @param int $v new value - * @return CcTrans The current object (for fluent API support) - */ - public function setJobpid($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->jobpid !== $v) { - $this->jobpid = $v; - $this->modifiedColumns[] = CcTransPeer::JOBPID; - } - - return $this; - } // setJobpid() - - /** - * Sets the value of [start] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcTrans The current object (for fluent API support) - */ - public function setStart($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->start !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->start !== null && $tmpDt = new DateTime($this->start)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->start = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcTransPeer::START; - } - } // if either are not null - - return $this; - } // setStart() - - /** - * Sets the value of [ts] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will - * be treated as NULL for temporal objects. - * @return CcTrans The current object (for fluent API support) - */ - public function setTs($v) - { - // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') - // -- which is unexpected, to say the least. - if ($v === null || $v === '') { - $dt = null; - } elseif ($v instanceof DateTime) { - $dt = $v; - } else { - // some string/numeric value passed; we normalize that so that we can - // validate it. - try { - if (is_numeric($v)) { // if it's a unix timestamp - $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); - // We have to explicitly specify and then change the time zone because of a - // DateTime bug: http://bugs.php.net/bug.php?id=43003 - $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); - } else { - $dt = new DateTime($v); - } - } catch (Exception $x) { - throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); - } - } - - if ( $this->ts !== null || $dt !== null ) { - // (nested ifs are a little easier to read in this case) - - $currNorm = ($this->ts !== null && $tmpDt = new DateTime($this->ts)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; - $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; - - if ( ($currNorm !== $newNorm) // normalized values don't match - ) - { - $this->ts = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); - $this->modifiedColumns[] = CcTransPeer::TS; - } - } // if either are not null - - return $this; - } // setTs() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->lock !== 'N') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM) - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false) - { - try { - - $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null; - $this->trtok = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null; - $this->direction = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; - $this->state = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; - $this->trtype = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; - $this->lock = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null; - $this->target = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; - $this->rtrtok = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null; - $this->mdtrtok = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; - $this->gunid = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null; - $this->pdtoken = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null; - $this->url = ($row[$startcol + 11] !== null) ? (string) $row[$startcol + 11] : null; - $this->localfile = ($row[$startcol + 12] !== null) ? (string) $row[$startcol + 12] : null; - $this->fname = ($row[$startcol + 13] !== null) ? (string) $row[$startcol + 13] : null; - $this->title = ($row[$startcol + 14] !== null) ? (string) $row[$startcol + 14] : null; - $this->expectedsum = ($row[$startcol + 15] !== null) ? (string) $row[$startcol + 15] : null; - $this->realsum = ($row[$startcol + 16] !== null) ? (string) $row[$startcol + 16] : null; - $this->expectedsize = ($row[$startcol + 17] !== null) ? (int) $row[$startcol + 17] : null; - $this->realsize = ($row[$startcol + 18] !== null) ? (int) $row[$startcol + 18] : null; - $this->uid = ($row[$startcol + 19] !== null) ? (int) $row[$startcol + 19] : null; - $this->errmsg = ($row[$startcol + 20] !== null) ? (string) $row[$startcol + 20] : null; - $this->jobpid = ($row[$startcol + 21] !== null) ? (int) $row[$startcol + 21] : null; - $this->start = ($row[$startcol + 22] !== null) ? (string) $row[$startcol + 22] : null; - $this->ts = ($row[$startcol + 23] !== null) ? (string) $row[$startcol + 23] : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 24; // 24 = CcTransPeer::NUM_COLUMNS - CcTransPeer::NUM_LAZY_LOAD_COLUMNS). - - } catch (Exception $e) { - throw new PropelException("Error populating CcTrans object", $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param PropelPDO $con (optional) The PropelPDO connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $stmt = CcTransPeer::doSelectStmt($this->buildPkeyCriteria(), $con); - $row = $stmt->fetch(PDO::FETCH_NUM); - $stmt->closeCursor(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true); // rehydrate - - if ($deep) { // also de-associate any related objects? - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param PropelPDO $con - * @return void - * @throws PropelException - * @see BaseObject::setDeleted() - * @see BaseObject::isDeleted() - */ - public function delete(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - try { - $ret = $this->preDelete($con); - if ($ret) { - CcTransQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()) - ->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(PropelPDO $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - CcTransPeer::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param PropelPDO $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(PropelPDO $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - if ($this->isNew() ) { - $this->modifiedColumns[] = CcTransPeer::ID; - } - - // If this object has been modified, then save it to the database. - if ($this->isModified()) { - if ($this->isNew()) { - $criteria = $this->buildCriteria(); - if ($criteria->keyContainsValue(CcTransPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcTransPeer::ID.')'); - } - - $pk = BasePeer::doInsert($criteria, $con); - $affectedRows = 1; - $this->setId($pk); //[IMV] update autoincrement primary key - $this->setNew(false); - } else { - $affectedRows = CcTransPeer::doUpdate($this, $con); - } - - $this->resetModified(); // [HL] After being saved an object is no longer 'modified' - } - - $this->alreadyInSave = false; - - } - return $affectedRows; - } // doSave() - - /** - * Array of ValidationFailed objects. - * @var array ValidationFailed[] - */ - protected $validationFailures = array(); - - /** - * Gets any ValidationFailed objects that resulted from last call to validate(). - * - * - * @return array ValidationFailed[] - * @see validate() - */ - public function getValidationFailures() - { - return $this->validationFailures; - } - - /** - * Validates the objects modified field values and all objects related to this table. - * - * If $columns is either a column name or an array of column names - * only those columns are validated. - * - * @param mixed $columns Column name or an array of column names. - * @return boolean Whether all columns pass validation. - * @see doValidate() - * @see getValidationFailures() - */ - public function validate($columns = null) - { - $res = $this->doValidate($columns); - if ($res === true) { - $this->validationFailures = array(); - return true; - } else { - $this->validationFailures = $res; - return false; - } - } - - /** - * This function performs the validation work for complex object models. - * - * In addition to checking the current object, all related objects will - * also be validated. If all pass then true is returned; otherwise - * an aggreagated array of ValidationFailed objects will be returned. - * - * @param array $columns Array of column names to validate. - * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. - */ - protected function doValidate($columns = null) - { - if (!$this->alreadyInValidation) { - $this->alreadyInValidation = true; - $retval = null; - - $failureMap = array(); - - - if (($retval = CcTransPeer::doValidate($this, $columns)) !== true) { - $failureMap = array_merge($failureMap, $retval); - } - - - - $this->alreadyInValidation = false; - } - - return (!empty($failureMap) ? $failureMap : true); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return mixed Value of field. - */ - public function getByName($name, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcTransPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - $field = $this->getByPosition($pos); - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getTrtok(); - break; - case 2: - return $this->getDirection(); - break; - case 3: - return $this->getState(); - break; - case 4: - return $this->getTrtype(); - break; - case 5: - return $this->getLock(); - break; - case 6: - return $this->getTarget(); - break; - case 7: - return $this->getRtrtok(); - break; - case 8: - return $this->getMdtrtok(); - break; - case 9: - return $this->getGunid(); - break; - case 10: - return $this->getPdtoken(); - break; - case 11: - return $this->getUrl(); - break; - case 12: - return $this->getLocalfile(); - break; - case 13: - return $this->getFname(); - break; - case 14: - return $this->getTitle(); - break; - case 15: - return $this->getExpectedsum(); - break; - case 16: - return $this->getRealsum(); - break; - case 17: - return $this->getExpectedsize(); - break; - case 18: - return $this->getRealsize(); - break; - case 19: - return $this->getUid(); - break; - case 20: - return $this->getErrmsg(); - break; - case 21: - return $this->getJobpid(); - break; - case 22: - return $this->getStart(); - break; - case 23: - return $this->getTs(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * Defaults to BasePeer::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true) - { - $keys = CcTransPeer::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getTrtok(), - $keys[2] => $this->getDirection(), - $keys[3] => $this->getState(), - $keys[4] => $this->getTrtype(), - $keys[5] => $this->getLock(), - $keys[6] => $this->getTarget(), - $keys[7] => $this->getRtrtok(), - $keys[8] => $this->getMdtrtok(), - $keys[9] => $this->getGunid(), - $keys[10] => $this->getPdtoken(), - $keys[11] => $this->getUrl(), - $keys[12] => $this->getLocalfile(), - $keys[13] => $this->getFname(), - $keys[14] => $this->getTitle(), - $keys[15] => $this->getExpectedsum(), - $keys[16] => $this->getRealsum(), - $keys[17] => $this->getExpectedsize(), - $keys[18] => $this->getRealsize(), - $keys[19] => $this->getUid(), - $keys[20] => $this->getErrmsg(), - $keys[21] => $this->getJobpid(), - $keys[22] => $this->getStart(), - $keys[23] => $this->getTs(), - ); - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name peer name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return void - */ - public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) - { - $pos = CcTransPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setTrtok($value); - break; - case 2: - $this->setDirection($value); - break; - case 3: - $this->setState($value); - break; - case 4: - $this->setTrtype($value); - break; - case 5: - $this->setLock($value); - break; - case 6: - $this->setTarget($value); - break; - case 7: - $this->setRtrtok($value); - break; - case 8: - $this->setMdtrtok($value); - break; - case 9: - $this->setGunid($value); - break; - case 10: - $this->setPdtoken($value); - break; - case 11: - $this->setUrl($value); - break; - case 12: - $this->setLocalfile($value); - break; - case 13: - $this->setFname($value); - break; - case 14: - $this->setTitle($value); - break; - case 15: - $this->setExpectedsum($value); - break; - case 16: - $this->setRealsum($value); - break; - case 17: - $this->setExpectedsize($value); - break; - case 18: - $this->setRealsize($value); - break; - case 19: - $this->setUid($value); - break; - case 20: - $this->setErrmsg($value); - break; - case 21: - $this->setJobpid($value); - break; - case 22: - $this->setStart($value); - break; - case 23: - $this->setTs($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. - * The default key type is the column's phpname (e.g. 'AuthorId') - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) - { - $keys = CcTransPeer::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setTrtok($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setDirection($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setState($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setTrtype($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setLock($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setTarget($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setRtrtok($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setMdtrtok($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setGunid($arr[$keys[9]]); - if (array_key_exists($keys[10], $arr)) $this->setPdtoken($arr[$keys[10]]); - if (array_key_exists($keys[11], $arr)) $this->setUrl($arr[$keys[11]]); - if (array_key_exists($keys[12], $arr)) $this->setLocalfile($arr[$keys[12]]); - if (array_key_exists($keys[13], $arr)) $this->setFname($arr[$keys[13]]); - if (array_key_exists($keys[14], $arr)) $this->setTitle($arr[$keys[14]]); - if (array_key_exists($keys[15], $arr)) $this->setExpectedsum($arr[$keys[15]]); - if (array_key_exists($keys[16], $arr)) $this->setRealsum($arr[$keys[16]]); - if (array_key_exists($keys[17], $arr)) $this->setExpectedsize($arr[$keys[17]]); - if (array_key_exists($keys[18], $arr)) $this->setRealsize($arr[$keys[18]]); - if (array_key_exists($keys[19], $arr)) $this->setUid($arr[$keys[19]]); - if (array_key_exists($keys[20], $arr)) $this->setErrmsg($arr[$keys[20]]); - if (array_key_exists($keys[21], $arr)) $this->setJobpid($arr[$keys[21]]); - if (array_key_exists($keys[22], $arr)) $this->setStart($arr[$keys[22]]); - if (array_key_exists($keys[23], $arr)) $this->setTs($arr[$keys[23]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(CcTransPeer::DATABASE_NAME); - - if ($this->isColumnModified(CcTransPeer::ID)) $criteria->add(CcTransPeer::ID, $this->id); - if ($this->isColumnModified(CcTransPeer::TRTOK)) $criteria->add(CcTransPeer::TRTOK, $this->trtok); - if ($this->isColumnModified(CcTransPeer::DIRECTION)) $criteria->add(CcTransPeer::DIRECTION, $this->direction); - if ($this->isColumnModified(CcTransPeer::STATE)) $criteria->add(CcTransPeer::STATE, $this->state); - if ($this->isColumnModified(CcTransPeer::TRTYPE)) $criteria->add(CcTransPeer::TRTYPE, $this->trtype); - if ($this->isColumnModified(CcTransPeer::LOCK)) $criteria->add(CcTransPeer::LOCK, $this->lock); - if ($this->isColumnModified(CcTransPeer::TARGET)) $criteria->add(CcTransPeer::TARGET, $this->target); - if ($this->isColumnModified(CcTransPeer::RTRTOK)) $criteria->add(CcTransPeer::RTRTOK, $this->rtrtok); - if ($this->isColumnModified(CcTransPeer::MDTRTOK)) $criteria->add(CcTransPeer::MDTRTOK, $this->mdtrtok); - if ($this->isColumnModified(CcTransPeer::GUNID)) $criteria->add(CcTransPeer::GUNID, $this->gunid); - if ($this->isColumnModified(CcTransPeer::PDTOKEN)) $criteria->add(CcTransPeer::PDTOKEN, $this->pdtoken); - if ($this->isColumnModified(CcTransPeer::URL)) $criteria->add(CcTransPeer::URL, $this->url); - if ($this->isColumnModified(CcTransPeer::LOCALFILE)) $criteria->add(CcTransPeer::LOCALFILE, $this->localfile); - if ($this->isColumnModified(CcTransPeer::FNAME)) $criteria->add(CcTransPeer::FNAME, $this->fname); - if ($this->isColumnModified(CcTransPeer::TITLE)) $criteria->add(CcTransPeer::TITLE, $this->title); - if ($this->isColumnModified(CcTransPeer::EXPECTEDSUM)) $criteria->add(CcTransPeer::EXPECTEDSUM, $this->expectedsum); - if ($this->isColumnModified(CcTransPeer::REALSUM)) $criteria->add(CcTransPeer::REALSUM, $this->realsum); - if ($this->isColumnModified(CcTransPeer::EXPECTEDSIZE)) $criteria->add(CcTransPeer::EXPECTEDSIZE, $this->expectedsize); - if ($this->isColumnModified(CcTransPeer::REALSIZE)) $criteria->add(CcTransPeer::REALSIZE, $this->realsize); - if ($this->isColumnModified(CcTransPeer::UID)) $criteria->add(CcTransPeer::UID, $this->uid); - if ($this->isColumnModified(CcTransPeer::ERRMSG)) $criteria->add(CcTransPeer::ERRMSG, $this->errmsg); - if ($this->isColumnModified(CcTransPeer::JOBPID)) $criteria->add(CcTransPeer::JOBPID, $this->jobpid); - if ($this->isColumnModified(CcTransPeer::START)) $criteria->add(CcTransPeer::START, $this->start); - if ($this->isColumnModified(CcTransPeer::TS)) $criteria->add(CcTransPeer::TS, $this->ts); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(CcTransPeer::DATABASE_NAME); - $criteria->add(CcTransPeer::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of CcTrans (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false) - { - $copyObj->setTrtok($this->trtok); - $copyObj->setDirection($this->direction); - $copyObj->setState($this->state); - $copyObj->setTrtype($this->trtype); - $copyObj->setLock($this->lock); - $copyObj->setTarget($this->target); - $copyObj->setRtrtok($this->rtrtok); - $copyObj->setMdtrtok($this->mdtrtok); - $copyObj->setGunid($this->gunid); - $copyObj->setPdtoken($this->pdtoken); - $copyObj->setUrl($this->url); - $copyObj->setLocalfile($this->localfile); - $copyObj->setFname($this->fname); - $copyObj->setTitle($this->title); - $copyObj->setExpectedsum($this->expectedsum); - $copyObj->setRealsum($this->realsum); - $copyObj->setExpectedsize($this->expectedsize); - $copyObj->setRealsize($this->realsize); - $copyObj->setUid($this->uid); - $copyObj->setErrmsg($this->errmsg); - $copyObj->setJobpid($this->jobpid); - $copyObj->setStart($this->start); - $copyObj->setTs($this->ts); - - $copyObj->setNew(true); - $copyObj->setId(NULL); // this is a auto-increment column, so set to default value - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return CcTrans Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - return $copyObj; - } - - /** - * Returns a peer instance associated with this om. - * - * Since Peer classes are not to have any instance attributes, this method returns the - * same instance for all member of this class. The method could therefore - * be static, but this would prevent one from overriding the behavior. - * - * @return CcTransPeer - */ - public function getPeer() - { - if (self::$peer === null) { - self::$peer = new CcTransPeer(); - } - return self::$peer; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->trtok = null; - $this->direction = null; - $this->state = null; - $this->trtype = null; - $this->lock = null; - $this->target = null; - $this->rtrtok = null; - $this->mdtrtok = null; - $this->gunid = null; - $this->pdtoken = null; - $this->url = null; - $this->localfile = null; - $this->fname = null; - $this->title = null; - $this->expectedsum = null; - $this->realsum = null; - $this->expectedsize = null; - $this->realsize = null; - $this->uid = null; - $this->errmsg = null; - $this->jobpid = null; - $this->start = null; - $this->ts = null; - $this->alreadyInSave = false; - $this->alreadyInValidation = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all collections of referencing foreign keys. - * - * This method is a user-space workaround for PHP's inability to garbage collect objects - * with circular references. This is currently necessary when using Propel in certain - * daemon or large-volumne/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all associated objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - } - - /** - * Catches calls to virtual methods - */ - public function __call($name, $params) - { - if (preg_match('/get(\w+)/', $name, $matches)) { - $virtualColumn = $matches[1]; - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - // no lcfirst in php<5.3... - $virtualColumn[0] = strtolower($virtualColumn[0]); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - throw new PropelException('Call to undefined method: ' . $name); - } - -} // BaseCcTrans diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcTransPeer.php b/backend/propel-db/build/classes/campcaster/om/BaseCcTransPeer.php deleted file mode 100644 index c8dd333a9..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcTransPeer.php +++ /dev/null @@ -1,849 +0,0 @@ - array ('Id', 'Trtok', 'Direction', 'State', 'Trtype', 'Lock', 'Target', 'Rtrtok', 'Mdtrtok', 'Gunid', 'Pdtoken', 'Url', 'Localfile', 'Fname', 'Title', 'Expectedsum', 'Realsum', 'Expectedsize', 'Realsize', 'Uid', 'Errmsg', 'Jobpid', 'Start', 'Ts', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'trtok', 'direction', 'state', 'trtype', 'lock', 'target', 'rtrtok', 'mdtrtok', 'gunid', 'pdtoken', 'url', 'localfile', 'fname', 'title', 'expectedsum', 'realsum', 'expectedsize', 'realsize', 'uid', 'errmsg', 'jobpid', 'start', 'ts', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::TRTOK, self::DIRECTION, self::STATE, self::TRTYPE, self::LOCK, self::TARGET, self::RTRTOK, self::MDTRTOK, self::GUNID, self::PDTOKEN, self::URL, self::LOCALFILE, self::FNAME, self::TITLE, self::EXPECTEDSUM, self::REALSUM, self::EXPECTEDSIZE, self::REALSIZE, self::UID, self::ERRMSG, self::JOBPID, self::START, self::TS, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'TRTOK', 'DIRECTION', 'STATE', 'TRTYPE', 'LOCK', 'TARGET', 'RTRTOK', 'MDTRTOK', 'GUNID', 'PDTOKEN', 'URL', 'LOCALFILE', 'FNAME', 'TITLE', 'EXPECTEDSUM', 'REALSUM', 'EXPECTEDSIZE', 'REALSIZE', 'UID', 'ERRMSG', 'JOBPID', 'START', 'TS', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'trtok', 'direction', 'state', 'trtype', 'lock', 'target', 'rtrtok', 'mdtrtok', 'gunid', 'pdtoken', 'url', 'localfile', 'fname', 'title', 'expectedsum', 'realsum', 'expectedsize', 'realsize', 'uid', 'errmsg', 'jobpid', 'start', 'ts', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 - */ - private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Trtok' => 1, 'Direction' => 2, 'State' => 3, 'Trtype' => 4, 'Lock' => 5, 'Target' => 6, 'Rtrtok' => 7, 'Mdtrtok' => 8, 'Gunid' => 9, 'Pdtoken' => 10, 'Url' => 11, 'Localfile' => 12, 'Fname' => 13, 'Title' => 14, 'Expectedsum' => 15, 'Realsum' => 16, 'Expectedsize' => 17, 'Realsize' => 18, 'Uid' => 19, 'Errmsg' => 20, 'Jobpid' => 21, 'Start' => 22, 'Ts' => 23, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'trtok' => 1, 'direction' => 2, 'state' => 3, 'trtype' => 4, 'lock' => 5, 'target' => 6, 'rtrtok' => 7, 'mdtrtok' => 8, 'gunid' => 9, 'pdtoken' => 10, 'url' => 11, 'localfile' => 12, 'fname' => 13, 'title' => 14, 'expectedsum' => 15, 'realsum' => 16, 'expectedsize' => 17, 'realsize' => 18, 'uid' => 19, 'errmsg' => 20, 'jobpid' => 21, 'start' => 22, 'ts' => 23, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::TRTOK => 1, self::DIRECTION => 2, self::STATE => 3, self::TRTYPE => 4, self::LOCK => 5, self::TARGET => 6, self::RTRTOK => 7, self::MDTRTOK => 8, self::GUNID => 9, self::PDTOKEN => 10, self::URL => 11, self::LOCALFILE => 12, self::FNAME => 13, self::TITLE => 14, self::EXPECTEDSUM => 15, self::REALSUM => 16, self::EXPECTEDSIZE => 17, self::REALSIZE => 18, self::UID => 19, self::ERRMSG => 20, self::JOBPID => 21, self::START => 22, self::TS => 23, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'TRTOK' => 1, 'DIRECTION' => 2, 'STATE' => 3, 'TRTYPE' => 4, 'LOCK' => 5, 'TARGET' => 6, 'RTRTOK' => 7, 'MDTRTOK' => 8, 'GUNID' => 9, 'PDTOKEN' => 10, 'URL' => 11, 'LOCALFILE' => 12, 'FNAME' => 13, 'TITLE' => 14, 'EXPECTEDSUM' => 15, 'REALSUM' => 16, 'EXPECTEDSIZE' => 17, 'REALSIZE' => 18, 'UID' => 19, 'ERRMSG' => 20, 'JOBPID' => 21, 'START' => 22, 'TS' => 23, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'trtok' => 1, 'direction' => 2, 'state' => 3, 'trtype' => 4, 'lock' => 5, 'target' => 6, 'rtrtok' => 7, 'mdtrtok' => 8, 'gunid' => 9, 'pdtoken' => 10, 'url' => 11, 'localfile' => 12, 'fname' => 13, 'title' => 14, 'expectedsum' => 15, 'realsum' => 16, 'expectedsize' => 17, 'realsize' => 18, 'uid' => 19, 'errmsg' => 20, 'jobpid' => 21, 'start' => 22, 'ts' => 23, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, ) - ); - - /** - * Translates a fieldname to another type - * - * @param string $name field name - * @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @param string $toType One of the class type constants - * @return string translated name of the field. - * @throws PropelException - if the specified name could not be found in the fieldname mappings. - */ - static public function translateFieldName($name, $fromType, $toType) - { - $toNames = self::getFieldNames($toType); - $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; - if ($key === null) { - throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); - } - return $toNames[$key]; - } - - /** - * Returns an array of field names. - * - * @param string $type The type of fieldnames to return: - * One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM - * @return array A list of field names - */ - - static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) - { - if (!array_key_exists($type, self::$fieldNames)) { - throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.'); - } - return self::$fieldNames[$type]; - } - - /** - * Convenience method which changes table.column to alias.column. - * - * Using this method you can maintain SQL abstraction while using column aliases. - * - * $c->addAlias("alias1", TablePeer::TABLE_NAME); - * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); - * - * @param string $alias The alias for the current table. - * @param string $column The column name for current table. (i.e. CcTransPeer::COLUMN_NAME). - * @return string - */ - public static function alias($alias, $column) - { - return str_replace(CcTransPeer::TABLE_NAME.'.', $alias.'.', $column); - } - - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(CcTransPeer::ID); - $criteria->addSelectColumn(CcTransPeer::TRTOK); - $criteria->addSelectColumn(CcTransPeer::DIRECTION); - $criteria->addSelectColumn(CcTransPeer::STATE); - $criteria->addSelectColumn(CcTransPeer::TRTYPE); - $criteria->addSelectColumn(CcTransPeer::LOCK); - $criteria->addSelectColumn(CcTransPeer::TARGET); - $criteria->addSelectColumn(CcTransPeer::RTRTOK); - $criteria->addSelectColumn(CcTransPeer::MDTRTOK); - $criteria->addSelectColumn(CcTransPeer::GUNID); - $criteria->addSelectColumn(CcTransPeer::PDTOKEN); - $criteria->addSelectColumn(CcTransPeer::URL); - $criteria->addSelectColumn(CcTransPeer::LOCALFILE); - $criteria->addSelectColumn(CcTransPeer::FNAME); - $criteria->addSelectColumn(CcTransPeer::TITLE); - $criteria->addSelectColumn(CcTransPeer::EXPECTEDSUM); - $criteria->addSelectColumn(CcTransPeer::REALSUM); - $criteria->addSelectColumn(CcTransPeer::EXPECTEDSIZE); - $criteria->addSelectColumn(CcTransPeer::REALSIZE); - $criteria->addSelectColumn(CcTransPeer::UID); - $criteria->addSelectColumn(CcTransPeer::ERRMSG); - $criteria->addSelectColumn(CcTransPeer::JOBPID); - $criteria->addSelectColumn(CcTransPeer::START); - $criteria->addSelectColumn(CcTransPeer::TS); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.TRTOK'); - $criteria->addSelectColumn($alias . '.DIRECTION'); - $criteria->addSelectColumn($alias . '.STATE'); - $criteria->addSelectColumn($alias . '.TRTYPE'); - $criteria->addSelectColumn($alias . '.LOCK'); - $criteria->addSelectColumn($alias . '.TARGET'); - $criteria->addSelectColumn($alias . '.RTRTOK'); - $criteria->addSelectColumn($alias . '.MDTRTOK'); - $criteria->addSelectColumn($alias . '.GUNID'); - $criteria->addSelectColumn($alias . '.PDTOKEN'); - $criteria->addSelectColumn($alias . '.URL'); - $criteria->addSelectColumn($alias . '.LOCALFILE'); - $criteria->addSelectColumn($alias . '.FNAME'); - $criteria->addSelectColumn($alias . '.TITLE'); - $criteria->addSelectColumn($alias . '.EXPECTEDSUM'); - $criteria->addSelectColumn($alias . '.REALSUM'); - $criteria->addSelectColumn($alias . '.EXPECTEDSIZE'); - $criteria->addSelectColumn($alias . '.REALSIZE'); - $criteria->addSelectColumn($alias . '.UID'); - $criteria->addSelectColumn($alias . '.ERRMSG'); - $criteria->addSelectColumn($alias . '.JOBPID'); - $criteria->addSelectColumn($alias . '.START'); - $criteria->addSelectColumn($alias . '.TS'); - } - } - - /** - * Returns the number of rows matching criteria. - * - * @param Criteria $criteria - * @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead. - * @param PropelPDO $con - * @return int Number of matching rows. - */ - public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null) - { - // we may modify criteria, so copy it first - $criteria = clone $criteria; - - // We need to set the primary table name, since in the case that there are no WHERE columns - // it will be impossible for the BasePeer::createSelectSql() method to determine which - // tables go into the FROM clause. - $criteria->setPrimaryTableName(CcTransPeer::TABLE_NAME); - - if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { - $criteria->setDistinct(); - } - - if (!$criteria->hasSelectClause()) { - CcTransPeer::addSelectColumns($criteria); - } - - $criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count - $criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName - - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - // BasePeer returns a PDOStatement - $stmt = BasePeer::doCount($criteria, $con); - - if ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $count = (int) $row[0]; - } else { - $count = 0; // no rows returned; we infer that means 0 matches. - } - $stmt->closeCursor(); - return $count; - } - /** - * Method to select one object from the DB. - * - * @param Criteria $criteria object used to create the SELECT statement. - * @param PropelPDO $con - * @return CcTrans - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelectOne(Criteria $criteria, PropelPDO $con = null) - { - $critcopy = clone $criteria; - $critcopy->setLimit(1); - $objects = CcTransPeer::doSelect($critcopy, $con); - if ($objects) { - return $objects[0]; - } - return null; - } - /** - * Method to do selects. - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con - * @return array Array of selected Objects - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doSelect(Criteria $criteria, PropelPDO $con = null) - { - return CcTransPeer::populateObjects(CcTransPeer::doSelectStmt($criteria, $con)); - } - /** - * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement. - * - * Use this method directly if you want to work with an executed statement durirectly (for example - * to perform your own object hydration). - * - * @param Criteria $criteria The Criteria object used to build the SELECT statement. - * @param PropelPDO $con The connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return PDOStatement The executed PDOStatement object. - * @see BasePeer::doSelect() - */ - public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - if (!$criteria->hasSelectClause()) { - $criteria = clone $criteria; - CcTransPeer::addSelectColumns($criteria); - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - // BasePeer returns a PDOStatement - return BasePeer::doSelect($criteria, $con); - } - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doSelect*() - * methods in your stub classes -- you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by doSelect*() - * and retrieveByPK*() calls. - * - * @param CcTrans $value A CcTrans object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool(CcTrans $obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if ($key === null) { - $key = (string) $obj->getId(); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A CcTrans object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && $value !== null) { - if (is_object($value) && $value instanceof CcTrans) { - $key = (string) $value->getId(); - } elseif (is_scalar($value)) { - // assume we've been passed a primary key - $key = (string) $value; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcTrans object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } // removeInstanceFromPool() - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param string $key The key (@see getPrimaryKeyHash()) for this instance. - * @return CcTrans Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled. - * @see getPrimaryKeyHash() - */ - public static function getInstanceFromPool($key) - { - if (Propel::isInstancePoolingEnabled()) { - if (isset(self::$instances[$key])) { - return self::$instances[$key]; - } - } - return null; // just to be explicit - } - - /** - * Clear the instance pool. - * - * @return void - */ - public static function clearInstancePool() - { - self::$instances = array(); - } - - /** - * Method to invalidate the instance pool of all tables related to cc_trans - * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return string A string version of PK or NULL if the components of primary key in result array are all null. - */ - public static function getPrimaryKeyHashFromRow($row, $startcol = 0) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[$startcol] === null) { - return null; - } - return (string) $row[$startcol]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $startcol = 0) - { - return (int) $row[$startcol]; - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(PDOStatement $stmt) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = CcTransPeer::getOMClass(false); - // populate the object(s) - while ($row = $stmt->fetch(PDO::FETCH_NUM)) { - $key = CcTransPeer::getPrimaryKeyHashFromRow($row, 0); - if (null !== ($obj = CcTransPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - CcTransPeer::addInstanceToPool($obj, $key); - } // if key exists - } - $stmt->closeCursor(); - return $results; - } - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row PropelPDO resultset row. - * @param int $startcol The 0-based offset for reading from the resultset row. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (CcTrans object, last column rank) - */ - public static function populateObject($row, $startcol = 0) - { - $key = CcTransPeer::getPrimaryKeyHashFromRow($row, $startcol); - if (null !== ($obj = CcTransPeer::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $startcol, true); // rehydrate - $col = $startcol + CcTransPeer::NUM_COLUMNS; - } else { - $cls = CcTransPeer::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $startcol); - CcTransPeer::addInstanceToPool($obj, $key); - } - return array($obj, $col); - } - /** - * Returns the TableMap related to this peer. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this peer class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getDatabaseMap(BaseCcTransPeer::DATABASE_NAME); - if (!$dbMap->hasTable(BaseCcTransPeer::TABLE_NAME)) - { - $dbMap->addTableObject(new CcTransTableMap()); - } - } - - /** - * The class that the Peer will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is tranalted into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? CcTransPeer::CLASS_DEFAULT : CcTransPeer::OM_CLASS; - } - - /** - * Method perform an INSERT on the database, given a CcTrans or Criteria object. - * - * @param mixed $values Criteria or CcTrans object containing data that is used to create the INSERT statement. - * @param PropelPDO $con the PropelPDO connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - } else { - $criteria = $values->buildCriteria(); // build Criteria from CcTrans object - } - - if ($criteria->containsKey(CcTransPeer::ID) && $criteria->keyContainsValue(CcTransPeer::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcTransPeer::ID.')'); - } - - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = BasePeer::doInsert($criteria, $con); - $con->commit(); - } catch(PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - - /** - * Method perform an UPDATE on the database, given a CcTrans or Criteria object. - * - * @param mixed $values Criteria or CcTrans object containing data that is used to create the UPDATE statement. - * @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions). - * @return int The number of affected rows (if supported by underlying database driver). - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doUpdate($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - $selectCriteria = new Criteria(self::DATABASE_NAME); - - if ($values instanceof Criteria) { - $criteria = clone $values; // rename for clarity - - $comparison = $criteria->getComparison(CcTransPeer::ID); - $value = $criteria->remove(CcTransPeer::ID); - if ($value) { - $selectCriteria->add(CcTransPeer::ID, $value, $comparison); - } else { - $selectCriteria->setPrimaryTableName(CcTransPeer::TABLE_NAME); - } - - } else { // $values is CcTrans object - $criteria = $values->buildCriteria(); // gets full criteria - $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) - } - - // set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - return BasePeer::doUpdate($selectCriteria, $criteria, $con); - } - - /** - * Method to DELETE all rows from the cc_trans table. - * - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll($con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += BasePeer::doDeleteAll(CcTransPeer::TABLE_NAME, $con, CcTransPeer::DATABASE_NAME); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - CcTransPeer::clearInstancePool(); - CcTransPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Method perform a DELETE on the database, given a CcTrans or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or CcTrans object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param PropelPDO $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); - } - - if ($values instanceof Criteria) { - // invalidate the cache for all objects of this type, since we have no - // way of knowing (without running a query) what objects should be invalidated - // from the cache based on this Criteria. - CcTransPeer::clearInstancePool(); - // rename for clarity - $criteria = clone $values; - } elseif ($values instanceof CcTrans) { // it's a model object - // invalidate the cache for this single object - CcTransPeer::removeInstanceFromPool($values); - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(CcTransPeer::ID, (array) $values, Criteria::IN); - // invalidate the cache for this object(s) - foreach ((array) $values as $singleval) { - CcTransPeer::removeInstanceFromPool($singleval); - } - } - - // Set the correct dbName - $criteria->setDbName(self::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - $affectedRows += BasePeer::doDelete($criteria, $con); - CcTransPeer::clearRelatedInstancePool(); - $con->commit(); - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Validates all modified columns of given CcTrans object. - * If parameter $columns is either a single column name or an array of column names - * than only those columns are validated. - * - * NOTICE: This does not apply to primary or foreign keys for now. - * - * @param CcTrans $obj The object to validate. - * @param mixed $cols Column name or array of column names. - * - * @return mixed TRUE if all columns are valid or the error message of the first invalid column. - */ - public static function doValidate(CcTrans $obj, $cols = null) - { - $columns = array(); - - if ($cols) { - $dbMap = Propel::getDatabaseMap(CcTransPeer::DATABASE_NAME); - $tableMap = $dbMap->getTable(CcTransPeer::TABLE_NAME); - - if (! is_array($cols)) { - $cols = array($cols); - } - - foreach ($cols as $colName) { - if ($tableMap->containsColumn($colName)) { - $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); - $columns[$colName] = $obj->$get(); - } - } - } else { - - } - - return BasePeer::doValidate(CcTransPeer::DATABASE_NAME, CcTransPeer::TABLE_NAME, $columns); - } - - /** - * Retrieve a single object by pkey. - * - * @param int $pk the primary key. - * @param PropelPDO $con the connection to use - * @return CcTrans - */ - public static function retrieveByPK($pk, PropelPDO $con = null) - { - - if (null !== ($obj = CcTransPeer::getInstanceFromPool((string) $pk))) { - return $obj; - } - - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $criteria = new Criteria(CcTransPeer::DATABASE_NAME); - $criteria->add(CcTransPeer::ID, $pk); - - $v = CcTransPeer::doSelect($criteria, $con); - - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param PropelPDO $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, PropelPDO $con = null) - { - if ($con === null) { - $con = Propel::getConnection(CcTransPeer::DATABASE_NAME, Propel::CONNECTION_READ); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(CcTransPeer::DATABASE_NAME); - $criteria->add(CcTransPeer::ID, $pks, Criteria::IN); - $objs = CcTransPeer::doSelect($criteria, $con); - } - return $objs; - } - -} // BaseCcTransPeer - -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -BaseCcTransPeer::buildTableMap(); - diff --git a/backend/propel-db/build/classes/campcaster/om/BaseCcTransQuery.php b/backend/propel-db/build/classes/campcaster/om/BaseCcTransQuery.php deleted file mode 100644 index e00396ef6..000000000 --- a/backend/propel-db/build/classes/campcaster/om/BaseCcTransQuery.php +++ /dev/null @@ -1,826 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - return $query; - } - - /** - * Find object by primary key - * Use instance pooling to avoid a database query if the object exists - * - * $obj = $c->findPk(12, $con); - * - * @param mixed $key Primary key to use for the query - * @param PropelPDO $con an optional connection object - * - * @return CcTrans|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ((null !== ($obj = CcTransPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) { - // the object is alredy in the instance pool - return $obj; - } else { - // the object has not been requested yet, or the formatter is not an object formatter - $criteria = $this->isKeepQuery() ? clone $this : $this; - $stmt = $criteria - ->filterByPrimaryKey($key) - ->getSelectStatement($con); - return $criteria->getFormatter()->init($criteria)->formatOne($stmt); - } - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param PropelPDO $con an optional connection object - * - * @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - $criteria = $this->isKeepQuery() ? clone $this : $this; - return $this - ->filterByPrimaryKeys($keys) - ->find($con); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - return $this->addUsingAlias(CcTransPeer::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - return $this->addUsingAlias(CcTransPeer::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * @param int|array $id The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id) && null === $comparison) { - $comparison = Criteria::IN; - } - return $this->addUsingAlias(CcTransPeer::ID, $id, $comparison); - } - - /** - * Filter the query on the trtok column - * - * @param string $trtok The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByTrtok($trtok = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($trtok)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $trtok)) { - $trtok = str_replace('*', '%', $trtok); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::TRTOK, $trtok, $comparison); - } - - /** - * Filter the query on the direction column - * - * @param string $direction The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByDirection($direction = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($direction)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $direction)) { - $direction = str_replace('*', '%', $direction); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::DIRECTION, $direction, $comparison); - } - - /** - * Filter the query on the state column - * - * @param string $state The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByState($state = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($state)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $state)) { - $state = str_replace('*', '%', $state); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::STATE, $state, $comparison); - } - - /** - * Filter the query on the trtype column - * - * @param string $trtype The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByTrtype($trtype = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($trtype)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $trtype)) { - $trtype = str_replace('*', '%', $trtype); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::TRTYPE, $trtype, $comparison); - } - - /** - * Filter the query on the lock column - * - * @param string $lock The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByLock($lock = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($lock)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $lock)) { - $lock = str_replace('*', '%', $lock); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::LOCK, $lock, $comparison); - } - - /** - * Filter the query on the target column - * - * @param string $target The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByTarget($target = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($target)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $target)) { - $target = str_replace('*', '%', $target); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::TARGET, $target, $comparison); - } - - /** - * Filter the query on the rtrtok column - * - * @param string $rtrtok The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByRtrtok($rtrtok = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($rtrtok)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $rtrtok)) { - $rtrtok = str_replace('*', '%', $rtrtok); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::RTRTOK, $rtrtok, $comparison); - } - - /** - * Filter the query on the mdtrtok column - * - * @param string $mdtrtok The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByMdtrtok($mdtrtok = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($mdtrtok)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $mdtrtok)) { - $mdtrtok = str_replace('*', '%', $mdtrtok); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::MDTRTOK, $mdtrtok, $comparison); - } - - /** - * Filter the query on the gunid column - * - * @param string $gunid The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByGunid($gunid = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($gunid)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $gunid)) { - $gunid = str_replace('*', '%', $gunid); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::GUNID, $gunid, $comparison); - } - - /** - * Filter the query on the pdtoken column - * - * @param string|array $pdtoken The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByPdtoken($pdtoken = null, $comparison = null) - { - if (is_array($pdtoken)) { - $useMinMax = false; - if (isset($pdtoken['min'])) { - $this->addUsingAlias(CcTransPeer::PDTOKEN, $pdtoken['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($pdtoken['max'])) { - $this->addUsingAlias(CcTransPeer::PDTOKEN, $pdtoken['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::PDTOKEN, $pdtoken, $comparison); - } - - /** - * Filter the query on the url column - * - * @param string $url The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByUrl($url = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($url)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $url)) { - $url = str_replace('*', '%', $url); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::URL, $url, $comparison); - } - - /** - * Filter the query on the localfile column - * - * @param string $localfile The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByLocalfile($localfile = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($localfile)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $localfile)) { - $localfile = str_replace('*', '%', $localfile); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::LOCALFILE, $localfile, $comparison); - } - - /** - * Filter the query on the fname column - * - * @param string $fname The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByFname($fname = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($fname)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $fname)) { - $fname = str_replace('*', '%', $fname); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::FNAME, $fname, $comparison); - } - - /** - * Filter the query on the title column - * - * @param string $title The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByTitle($title = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($title)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $title)) { - $title = str_replace('*', '%', $title); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::TITLE, $title, $comparison); - } - - /** - * Filter the query on the expectedsum column - * - * @param string $expectedsum The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByExpectedsum($expectedsum = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($expectedsum)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $expectedsum)) { - $expectedsum = str_replace('*', '%', $expectedsum); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::EXPECTEDSUM, $expectedsum, $comparison); - } - - /** - * Filter the query on the realsum column - * - * @param string $realsum The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByRealsum($realsum = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($realsum)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $realsum)) { - $realsum = str_replace('*', '%', $realsum); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::REALSUM, $realsum, $comparison); - } - - /** - * Filter the query on the expectedsize column - * - * @param int|array $expectedsize The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByExpectedsize($expectedsize = null, $comparison = null) - { - if (is_array($expectedsize)) { - $useMinMax = false; - if (isset($expectedsize['min'])) { - $this->addUsingAlias(CcTransPeer::EXPECTEDSIZE, $expectedsize['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($expectedsize['max'])) { - $this->addUsingAlias(CcTransPeer::EXPECTEDSIZE, $expectedsize['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::EXPECTEDSIZE, $expectedsize, $comparison); - } - - /** - * Filter the query on the realsize column - * - * @param int|array $realsize The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByRealsize($realsize = null, $comparison = null) - { - if (is_array($realsize)) { - $useMinMax = false; - if (isset($realsize['min'])) { - $this->addUsingAlias(CcTransPeer::REALSIZE, $realsize['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($realsize['max'])) { - $this->addUsingAlias(CcTransPeer::REALSIZE, $realsize['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::REALSIZE, $realsize, $comparison); - } - - /** - * Filter the query on the uid column - * - * @param int|array $uid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByUid($uid = null, $comparison = null) - { - if (is_array($uid)) { - $useMinMax = false; - if (isset($uid['min'])) { - $this->addUsingAlias(CcTransPeer::UID, $uid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($uid['max'])) { - $this->addUsingAlias(CcTransPeer::UID, $uid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::UID, $uid, $comparison); - } - - /** - * Filter the query on the errmsg column - * - * @param string $errmsg The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByErrmsg($errmsg = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($errmsg)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $errmsg)) { - $errmsg = str_replace('*', '%', $errmsg); - $comparison = Criteria::LIKE; - } - } - return $this->addUsingAlias(CcTransPeer::ERRMSG, $errmsg, $comparison); - } - - /** - * Filter the query on the jobpid column - * - * @param int|array $jobpid The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByJobpid($jobpid = null, $comparison = null) - { - if (is_array($jobpid)) { - $useMinMax = false; - if (isset($jobpid['min'])) { - $this->addUsingAlias(CcTransPeer::JOBPID, $jobpid['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($jobpid['max'])) { - $this->addUsingAlias(CcTransPeer::JOBPID, $jobpid['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::JOBPID, $jobpid, $comparison); - } - - /** - * Filter the query on the start column - * - * @param string|array $start The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByStart($start = null, $comparison = null) - { - if (is_array($start)) { - $useMinMax = false; - if (isset($start['min'])) { - $this->addUsingAlias(CcTransPeer::START, $start['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($start['max'])) { - $this->addUsingAlias(CcTransPeer::START, $start['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::START, $start, $comparison); - } - - /** - * Filter the query on the ts column - * - * @param string|array $ts The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return CcTransQuery The current query, for fluid interface - */ - public function filterByTs($ts = null, $comparison = null) - { - if (is_array($ts)) { - $useMinMax = false; - if (isset($ts['min'])) { - $this->addUsingAlias(CcTransPeer::TS, $ts['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($ts['max'])) { - $this->addUsingAlias(CcTransPeer::TS, $ts['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - return $this->addUsingAlias(CcTransPeer::TS, $ts, $comparison); - } - - /** - * Exclude object from result - * - * @param CcTrans $ccTrans Object to remove from the list of results - * - * @return CcTransQuery The current query, for fluid interface - */ - public function prune($ccTrans = null) - { - if ($ccTrans) { - $this->addUsingAlias(CcTransPeer::ID, $ccTrans->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - -} // BaseCcTransQuery diff --git a/backend/propel-db/build/conf/campcaster-conf.php b/backend/propel-db/build/conf/campcaster-conf.php deleted file mode 100644 index 562e1fffb..000000000 --- a/backend/propel-db/build/conf/campcaster-conf.php +++ /dev/null @@ -1,20 +0,0 @@ - - array ( - 'campcaster' => - array ( - 'adapter' => 'pgsql', - 'connection' => - array ( - 'dsn' => 'pgsql:host=localhost;port=5432;dbname=campcaster;user=campcaster;password=campcaster', - ), - ), - 'default' => 'campcaster', - ), - 'generator_version' => '1.5.2', -); -$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-campcaster-conf.php'); -return $conf; \ No newline at end of file diff --git a/backend/propel-db/build/conf/classmap-campcaster-conf.php b/backend/propel-db/build/conf/classmap-campcaster-conf.php deleted file mode 100644 index b5e883082..000000000 --- a/backend/propel-db/build/conf/classmap-campcaster-conf.php +++ /dev/null @@ -1,88 +0,0 @@ - 'campcaster/map/CcAccessTableMap.php', - 'CcAccessPeer' => 'campcaster/CcAccessPeer.php', - 'CcAccess' => 'campcaster/CcAccess.php', - 'CcAccessQuery' => 'campcaster/CcAccessQuery.php', - 'BaseCcAccessPeer' => 'campcaster/om/BaseCcAccessPeer.php', - 'BaseCcAccess' => 'campcaster/om/BaseCcAccess.php', - 'BaseCcAccessQuery' => 'campcaster/om/BaseCcAccessQuery.php', - 'CcBackupTableMap' => 'campcaster/map/CcBackupTableMap.php', - 'CcBackupPeer' => 'campcaster/CcBackupPeer.php', - 'CcBackup' => 'campcaster/CcBackup.php', - 'CcBackupQuery' => 'campcaster/CcBackupQuery.php', - 'BaseCcBackupPeer' => 'campcaster/om/BaseCcBackupPeer.php', - 'BaseCcBackup' => 'campcaster/om/BaseCcBackup.php', - 'BaseCcBackupQuery' => 'campcaster/om/BaseCcBackupQuery.php', - 'CcFilesTableMap' => 'campcaster/map/CcFilesTableMap.php', - 'CcFilesPeer' => 'campcaster/CcFilesPeer.php', - 'CcFiles' => 'campcaster/CcFiles.php', - 'CcFilesQuery' => 'campcaster/CcFilesQuery.php', - 'BaseCcFilesPeer' => 'campcaster/om/BaseCcFilesPeer.php', - 'BaseCcFiles' => 'campcaster/om/BaseCcFiles.php', - 'BaseCcFilesQuery' => 'campcaster/om/BaseCcFilesQuery.php', - 'CcPermsTableMap' => 'campcaster/map/CcPermsTableMap.php', - 'CcPermsPeer' => 'campcaster/CcPermsPeer.php', - 'CcPerms' => 'campcaster/CcPerms.php', - 'CcPermsQuery' => 'campcaster/CcPermsQuery.php', - 'BaseCcPermsPeer' => 'campcaster/om/BaseCcPermsPeer.php', - 'BaseCcPerms' => 'campcaster/om/BaseCcPerms.php', - 'BaseCcPermsQuery' => 'campcaster/om/BaseCcPermsQuery.php', - 'CcPlaylistTableMap' => 'campcaster/map/CcPlaylistTableMap.php', - 'CcPlaylistPeer' => 'campcaster/CcPlaylistPeer.php', - 'CcPlaylist' => 'campcaster/CcPlaylist.php', - 'CcPlaylistQuery' => 'campcaster/CcPlaylistQuery.php', - 'BaseCcPlaylistPeer' => 'campcaster/om/BaseCcPlaylistPeer.php', - 'BaseCcPlaylist' => 'campcaster/om/BaseCcPlaylist.php', - 'BaseCcPlaylistQuery' => 'campcaster/om/BaseCcPlaylistQuery.php', - 'CcPlaylistcontentsTableMap' => 'campcaster/map/CcPlaylistcontentsTableMap.php', - 'CcPlaylistcontentsPeer' => 'campcaster/CcPlaylistcontentsPeer.php', - 'CcPlaylistcontents' => 'campcaster/CcPlaylistcontents.php', - 'CcPlaylistcontentsQuery' => 'campcaster/CcPlaylistcontentsQuery.php', - 'BaseCcPlaylistcontentsPeer' => 'campcaster/om/BaseCcPlaylistcontentsPeer.php', - 'BaseCcPlaylistcontents' => 'campcaster/om/BaseCcPlaylistcontents.php', - 'BaseCcPlaylistcontentsQuery' => 'campcaster/om/BaseCcPlaylistcontentsQuery.php', - 'CcPrefTableMap' => 'campcaster/map/CcPrefTableMap.php', - 'CcPrefPeer' => 'campcaster/CcPrefPeer.php', - 'CcPref' => 'campcaster/CcPref.php', - 'CcPrefQuery' => 'campcaster/CcPrefQuery.php', - 'BaseCcPrefPeer' => 'campcaster/om/BaseCcPrefPeer.php', - 'BaseCcPref' => 'campcaster/om/BaseCcPref.php', - 'BaseCcPrefQuery' => 'campcaster/om/BaseCcPrefQuery.php', - 'CcScheduleTableMap' => 'campcaster/map/CcScheduleTableMap.php', - 'CcSchedulePeer' => 'campcaster/CcSchedulePeer.php', - 'CcSchedule' => 'campcaster/CcSchedule.php', - 'CcScheduleQuery' => 'campcaster/CcScheduleQuery.php', - 'BaseCcSchedulePeer' => 'campcaster/om/BaseCcSchedulePeer.php', - 'BaseCcSchedule' => 'campcaster/om/BaseCcSchedule.php', - 'BaseCcScheduleQuery' => 'campcaster/om/BaseCcScheduleQuery.php', - 'CcSessTableMap' => 'campcaster/map/CcSessTableMap.php', - 'CcSessPeer' => 'campcaster/CcSessPeer.php', - 'CcSess' => 'campcaster/CcSess.php', - 'CcSessQuery' => 'campcaster/CcSessQuery.php', - 'BaseCcSessPeer' => 'campcaster/om/BaseCcSessPeer.php', - 'BaseCcSess' => 'campcaster/om/BaseCcSess.php', - 'BaseCcSessQuery' => 'campcaster/om/BaseCcSessQuery.php', - 'CcSmembTableMap' => 'campcaster/map/CcSmembTableMap.php', - 'CcSmembPeer' => 'campcaster/CcSmembPeer.php', - 'CcSmemb' => 'campcaster/CcSmemb.php', - 'CcSmembQuery' => 'campcaster/CcSmembQuery.php', - 'BaseCcSmembPeer' => 'campcaster/om/BaseCcSmembPeer.php', - 'BaseCcSmemb' => 'campcaster/om/BaseCcSmemb.php', - 'BaseCcSmembQuery' => 'campcaster/om/BaseCcSmembQuery.php', - 'CcSubjsTableMap' => 'campcaster/map/CcSubjsTableMap.php', - 'CcSubjsPeer' => 'campcaster/CcSubjsPeer.php', - 'CcSubjs' => 'campcaster/CcSubjs.php', - 'CcSubjsQuery' => 'campcaster/CcSubjsQuery.php', - 'BaseCcSubjsPeer' => 'campcaster/om/BaseCcSubjsPeer.php', - 'BaseCcSubjs' => 'campcaster/om/BaseCcSubjs.php', - 'BaseCcSubjsQuery' => 'campcaster/om/BaseCcSubjsQuery.php', - 'CcTransTableMap' => 'campcaster/map/CcTransTableMap.php', - 'CcTransPeer' => 'campcaster/CcTransPeer.php', - 'CcTrans' => 'campcaster/CcTrans.php', - 'CcTransQuery' => 'campcaster/CcTransQuery.php', - 'BaseCcTransPeer' => 'campcaster/om/BaseCcTransPeer.php', - 'BaseCcTrans' => 'campcaster/om/BaseCcTrans.php', - 'BaseCcTransQuery' => 'campcaster/om/BaseCcTransQuery.php', -); \ No newline at end of file diff --git a/backend/propel-db/build/sql/schema.sql b/backend/propel-db/build/sql/schema.sql deleted file mode 100644 index 38ae1b962..000000000 --- a/backend/propel-db/build/sql/schema.sql +++ /dev/null @@ -1,388 +0,0 @@ - ------------------------------------------------------------------------------ --- cc_access ------------------------------------------------------------------------------ - -DROP TABLE "cc_access" CASCADE; - - -CREATE TABLE "cc_access" -( - "id" serial NOT NULL, - "gunid" CHAR(32), - "token" INT8, - "chsum" CHAR(32) default '' NOT NULL, - "ext" VARCHAR(128) default '' NOT NULL, - "type" VARCHAR(20) default '' NOT NULL, - "parent" INT8, - "owner" INTEGER, - "ts" TIMESTAMP, - PRIMARY KEY ("id") -); - -COMMENT ON TABLE "cc_access" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_access_gunid_idx" ON "cc_access" ("gunid"); - -CREATE INDEX "cc_access_parent_idx" ON "cc_access" ("parent"); - -CREATE INDEX "cc_access_token_idx" ON "cc_access" ("token"); - ------------------------------------------------------------------------------ --- cc_backup ------------------------------------------------------------------------------ - -DROP TABLE "cc_backup" CASCADE; - - -CREATE TABLE "cc_backup" -( - "token" VARCHAR(64) NOT NULL, - "sessionid" VARCHAR(64) NOT NULL, - "status" VARCHAR(32) NOT NULL, - "fromtime" TIMESTAMP NOT NULL, - "totime" TIMESTAMP NOT NULL, - PRIMARY KEY ("token") -); - -COMMENT ON TABLE "cc_backup" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_files ------------------------------------------------------------------------------ - -DROP TABLE "cc_files" CASCADE; - - -CREATE TABLE "cc_files" -( - "id" serial NOT NULL, - "gunid" CHAR(32) NOT NULL, - "name" VARCHAR(255) default '' NOT NULL, - "mime" VARCHAR(255) default '' NOT NULL, - "ftype" VARCHAR(128) default '' NOT NULL, - "filepath" TEXT default '', - "state" VARCHAR(128) default 'empty' NOT NULL, - "currentlyaccessing" INTEGER default 0 NOT NULL, - "editedby" INTEGER, - "mtime" TIMESTAMP(6), - "md5" CHAR(32), - "track_title" VARCHAR(512), - "artist_name" VARCHAR(512), - "bit_rate" VARCHAR(32), - "sample_rate" VARCHAR(32), - "format" VARCHAR(128), - "length" TIME, - "album_title" VARCHAR(512), - "genre" VARCHAR(64), - "comments" TEXT, - "year" VARCHAR(16), - "track_number" INTEGER, - "channels" INTEGER, - "url" VARCHAR(1024), - "bpm" VARCHAR(8), - "rating" VARCHAR(8), - "encoded_by" VARCHAR(255), - "disc_number" VARCHAR(8), - "mood" VARCHAR(64), - "label" VARCHAR(512), - "composer" VARCHAR(512), - "encoder" VARCHAR(64), - "checksum" VARCHAR(256), - "lyrics" TEXT, - "orchestra" VARCHAR(512), - "conductor" VARCHAR(512), - "lyricist" VARCHAR(512), - "original_lyricist" VARCHAR(512), - "radio_station_name" VARCHAR(512), - "info_url" VARCHAR(512), - "artist_url" VARCHAR(512), - "audio_source_url" VARCHAR(512), - "radio_station_url" VARCHAR(512), - "buy_this_url" VARCHAR(512), - "isrc_number" VARCHAR(512), - "catalog_number" VARCHAR(512), - "original_artist" VARCHAR(512), - "copyright" VARCHAR(512), - "report_datetime" VARCHAR(32), - "report_location" VARCHAR(512), - "report_organization" VARCHAR(512), - "subject" VARCHAR(512), - "contributor" VARCHAR(512), - "language" VARCHAR(512), - PRIMARY KEY ("id"), - CONSTRAINT "cc_files_gunid_idx" UNIQUE ("gunid") -); - -COMMENT ON TABLE "cc_files" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_files_md5_idx" ON "cc_files" ("md5"); - -CREATE INDEX "cc_files_name_idx" ON "cc_files" ("name"); - ------------------------------------------------------------------------------ --- cc_perms ------------------------------------------------------------------------------ - -DROP TABLE "cc_perms" CASCADE; - - -CREATE TABLE "cc_perms" -( - "permid" INTEGER NOT NULL, - "subj" INTEGER, - "action" VARCHAR(20), - "obj" INTEGER, - "type" CHAR(1), - PRIMARY KEY ("permid"), - CONSTRAINT "cc_perms_all_idx" UNIQUE ("subj","action","obj"), - CONSTRAINT "cc_perms_permid_idx" UNIQUE ("permid") -); - -COMMENT ON TABLE "cc_perms" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_perms_subj_obj_idx" ON "cc_perms" ("subj","obj"); - ------------------------------------------------------------------------------ --- cc_playlist ------------------------------------------------------------------------------ - -DROP TABLE "cc_playlist" CASCADE; - - -CREATE TABLE "cc_playlist" -( - "id" serial NOT NULL, - "name" VARCHAR(255) default '' NOT NULL, - "state" VARCHAR(128) default 'empty' NOT NULL, - "currentlyaccessing" INTEGER default 0 NOT NULL, - "editedby" INTEGER, - "mtime" TIMESTAMP(6), - "creator" VARCHAR(32), - "description" VARCHAR(512), - PRIMARY KEY ("id") -); - -COMMENT ON TABLE "cc_playlist" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_playlistcontents ------------------------------------------------------------------------------ - -DROP TABLE "cc_playlistcontents" CASCADE; - - -CREATE TABLE "cc_playlistcontents" -( - "id" serial NOT NULL, - "playlist_id" INTEGER, - "file_id" INTEGER, - "position" INTEGER, - "cliplength" TIME default '00:00:00', - "cuein" TIME default '00:00:00', - "cueout" TIME default '00:00:00', - "fadein" TIME default '00:00:00', - "fadeout" TIME default '00:00:00', - PRIMARY KEY ("id") -); - -COMMENT ON TABLE "cc_playlistcontents" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_pref ------------------------------------------------------------------------------ - -DROP TABLE "cc_pref" CASCADE; - - -CREATE TABLE "cc_pref" -( - "id" serial NOT NULL, - "subjid" INTEGER, - "keystr" VARCHAR(255), - "valstr" TEXT, - PRIMARY KEY ("id"), - CONSTRAINT "cc_pref_id_idx" UNIQUE ("id"), - CONSTRAINT "cc_pref_subj_key_idx" UNIQUE ("subjid","keystr") -); - -COMMENT ON TABLE "cc_pref" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_pref_subjid_idx" ON "cc_pref" ("subjid"); - ------------------------------------------------------------------------------ --- cc_schedule ------------------------------------------------------------------------------ - -DROP TABLE "cc_schedule" CASCADE; - - -CREATE TABLE "cc_schedule" -( - "id" INT8 NOT NULL, - "playlist_id" INTEGER NOT NULL, - "starts" TIMESTAMP NOT NULL, - "ends" TIMESTAMP NOT NULL, - "group_id" INTEGER, - "file_id" INTEGER, - "clip_length" TIME default '00:00:00', - "fade_in" TIME default '00:00:00', - "fade_out" TIME default '00:00:00', - "cue_in" TIME default '00:00:00', - "cue_out" TIME default '00:00:00', - "schedule_group_played" BOOLEAN default 'f', - "media_item_played" BOOLEAN default 'f', - PRIMARY KEY ("id") -); - -COMMENT ON TABLE "cc_schedule" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_sess ------------------------------------------------------------------------------ - -DROP TABLE "cc_sess" CASCADE; - - -CREATE TABLE "cc_sess" -( - "sessid" CHAR(32) NOT NULL, - "userid" INTEGER, - "login" VARCHAR(255), - "ts" TIMESTAMP, - PRIMARY KEY ("sessid") -); - -COMMENT ON TABLE "cc_sess" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_sess_login_idx" ON "cc_sess" ("login"); - -CREATE INDEX "cc_sess_userid_idx" ON "cc_sess" ("userid"); - ------------------------------------------------------------------------------ --- cc_smemb ------------------------------------------------------------------------------ - -DROP TABLE "cc_smemb" CASCADE; - - -CREATE TABLE "cc_smemb" -( - "id" INTEGER NOT NULL, - "uid" INTEGER default 0 NOT NULL, - "gid" INTEGER default 0 NOT NULL, - "level" INTEGER default 0 NOT NULL, - "mid" INTEGER, - PRIMARY KEY ("id"), - CONSTRAINT "cc_smemb_id_idx" UNIQUE ("id") -); - -COMMENT ON TABLE "cc_smemb" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_subjs ------------------------------------------------------------------------------ - -DROP TABLE "cc_subjs" CASCADE; - - -CREATE TABLE "cc_subjs" -( - "id" INTEGER NOT NULL, - "login" VARCHAR(255) default '' NOT NULL, - "pass" VARCHAR(255) default '' NOT NULL, - "type" CHAR(1) default 'U' NOT NULL, - "realname" VARCHAR(255) default '' NOT NULL, - "lastlogin" TIMESTAMP, - "lastfail" TIMESTAMP, - PRIMARY KEY ("id"), - CONSTRAINT "cc_subjs_id_idx" UNIQUE ("id"), - CONSTRAINT "cc_subjs_login_idx" UNIQUE ("login") -); - -COMMENT ON TABLE "cc_subjs" IS ''; - - -SET search_path TO public; ------------------------------------------------------------------------------ --- cc_trans ------------------------------------------------------------------------------ - -DROP TABLE "cc_trans" CASCADE; - - -CREATE TABLE "cc_trans" -( - "id" serial NOT NULL, - "trtok" CHAR(16) NOT NULL, - "direction" VARCHAR(128) NOT NULL, - "state" VARCHAR(128) NOT NULL, - "trtype" VARCHAR(128) NOT NULL, - "lock" CHAR(1) default 'N' NOT NULL, - "target" VARCHAR(255), - "rtrtok" CHAR(16), - "mdtrtok" CHAR(16), - "gunid" CHAR(32), - "pdtoken" INT8, - "url" VARCHAR(255), - "localfile" VARCHAR(255), - "fname" VARCHAR(255), - "title" VARCHAR(255), - "expectedsum" CHAR(32), - "realsum" CHAR(32), - "expectedsize" INTEGER, - "realsize" INTEGER, - "uid" INTEGER, - "errmsg" VARCHAR(255), - "jobpid" INTEGER, - "start" TIMESTAMP, - "ts" TIMESTAMP, - PRIMARY KEY ("id"), - CONSTRAINT "cc_trans_id_idx" UNIQUE ("id"), - CONSTRAINT "cc_trans_token_idx" UNIQUE ("pdtoken"), - CONSTRAINT "cc_trans_trtok_idx" UNIQUE ("trtok") -); - -COMMENT ON TABLE "cc_trans" IS ''; - - -SET search_path TO public; -CREATE INDEX "cc_trans_gunid_idx" ON "cc_trans" ("gunid"); - -CREATE INDEX "cc_trans_state_idx" ON "cc_trans" ("state"); - -ALTER TABLE "cc_access" ADD CONSTRAINT "cc_access_owner_fkey" FOREIGN KEY ("owner") REFERENCES "cc_subjs" ("id"); - -ALTER TABLE "cc_files" ADD CONSTRAINT "cc_files_editedby_fkey" FOREIGN KEY ("editedby") REFERENCES "cc_subjs" ("id"); - -ALTER TABLE "cc_perms" ADD CONSTRAINT "cc_perms_subj_fkey" FOREIGN KEY ("subj") REFERENCES "cc_subjs" ("id") ON DELETE CASCADE; - -ALTER TABLE "cc_playlist" ADD CONSTRAINT "cc_playlist_editedby_fkey" FOREIGN KEY ("editedby") REFERENCES "cc_subjs" ("id"); - -ALTER TABLE "cc_playlistcontents" ADD CONSTRAINT "cc_playlistcontents_file_id_fkey" FOREIGN KEY ("file_id") REFERENCES "cc_files" ("id") ON DELETE CASCADE; - -ALTER TABLE "cc_playlistcontents" ADD CONSTRAINT "cc_playlistcontents_playlist_id_fkey" FOREIGN KEY ("playlist_id") REFERENCES "cc_playlist" ("id") ON DELETE CASCADE; - -ALTER TABLE "cc_pref" ADD CONSTRAINT "cc_pref_subjid_fkey" FOREIGN KEY ("subjid") REFERENCES "cc_subjs" ("id") ON DELETE CASCADE; - -ALTER TABLE "cc_sess" ADD CONSTRAINT "cc_sess_userid_fkey" FOREIGN KEY ("userid") REFERENCES "cc_subjs" ("id") ON DELETE CASCADE; diff --git a/backend/propel-db/build/sql/sequences.sql b/backend/propel-db/build/sql/sequences.sql deleted file mode 100644 index 2eb10faee..000000000 --- a/backend/propel-db/build/sql/sequences.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP SEQUENCE schedule_group_id_seq CASCADE; - -CREATE SEQUENCE schedule_group_id_seq; diff --git a/backend/propel-db/build/sql/sqldb.map b/backend/propel-db/build/sql/sqldb.map deleted file mode 100644 index 0eb7c6b2b..000000000 --- a/backend/propel-db/build/sql/sqldb.map +++ /dev/null @@ -1,5 +0,0 @@ -# Sqlfile -> Database map -schema.sql=campcaster -sequences.sql=campcaster -views.sql=campcaster -triggers.sql=campcaster diff --git a/backend/propel-db/build/sql/triggers.sql b/backend/propel-db/build/sql/triggers.sql deleted file mode 100644 index c059ffe80..000000000 --- a/backend/propel-db/build/sql/triggers.sql +++ /dev/null @@ -1,23 +0,0 @@ ----------------------------------------------------------------------------------- ---calculate_position() ----------------------------------------------------------------------------------- -DROP FUNCTION calculate_position() CASCADE; - -CREATE FUNCTION calculate_position() RETURNS trigger AS - ' - BEGIN - IF(TG_OP=''INSERT'') THEN - UPDATE cc_playlistcontents SET position = (position + 1) - WHERE (playlist_id = new.playlist_id AND position >= new.position AND id != new.id); - END IF; - IF(TG_OP=''DELETE'') THEN - UPDATE cc_playlistcontents SET position = (position - 1) - WHERE (playlist_id = old.playlist_id AND position > old.position); - END IF; - RETURN NULL; - END; - ' - LANGUAGE 'plpgsql'; - -CREATE TRIGGER calculate_position AFTER INSERT OR DELETE ON cc_playlistcontents -FOR EACH ROW EXECUTE PROCEDURE calculate_position(); diff --git a/backend/propel-db/build/sql/views.sql b/backend/propel-db/build/sql/views.sql deleted file mode 100644 index 08eec6a5b..000000000 --- a/backend/propel-db/build/sql/views.sql +++ /dev/null @@ -1,11 +0,0 @@ -------------------------------------------------------- ----cc_playlisttimes -------------------------------------------------------- - -CREATE VIEW cc_playlisttimes AS -SELECT pl.id, COALESCE(t.length, '00:00:00'::time without time zone) AS length - FROM cc_playlist pl - LEFT JOIN ( SELECT cc_playlistcontents.playlist_id AS id, - sum(cc_playlistcontents.cliplength::interval)::time without time zone AS length - FROM cc_playlistcontents - GROUP BY cc_playlistcontents.playlist_id) t ON pl.id = t.id; diff --git a/backend/propel-db/runtime-conf.xml b/backend/propel-db/runtime-conf.xml deleted file mode 100644 index 4c83aa481..000000000 --- a/backend/propel-db/runtime-conf.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - pgsql - - pgsql:host=localhost;port=5432;dbname=campcaster;user=campcaster;password=campcaster - - - - - diff --git a/backend/propel-db/schema.xml b/backend/propel-db/schema.xml deleted file mode 100644 index 8741b649c..000000000 --- a/backend/propel-db/schema.xml +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    diff --git a/backend/propel-db/test.php b/backend/propel-db/test.php deleted file mode 100644 index 3c6767d99..000000000 --- a/backend/propel-db/test.php +++ /dev/null @@ -1,14 +0,0 @@ -setName("Playlist in Campcaster!"); -$pl->save(); - diff --git a/backend/tests/0000000000010001 b/backend/tests/0000000000010001 deleted file mode 100644 index 5fe5264022e9dd6cc3a2ecc9ec5a31bb28051c07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179013 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ⅆWQ43`4~H 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 UJKO*B0U=4a=>K`^|GWhJ4^=A*WB>pF diff --git a/backend/tests/AllTests.php b/backend/tests/AllTests.php deleted file mode 100644 index add11030e..000000000 --- a/backend/tests/AllTests.php +++ /dev/null @@ -1,24 +0,0 @@ -addTestSuite("PlaylistTests"); -$suite->addTestSuite("SchedulerTests"); -//$suite->addTestSuite("SchedulerExportTests"); -$result = PHPUnit::run($suite); - -echo $result->toString(); - -?> diff --git a/backend/tests/PlaylistTests.php b/backend/tests/PlaylistTests.php deleted file mode 100644 index bd8bc95bf..000000000 --- a/backend/tests/PlaylistTests.php +++ /dev/null @@ -1,181 +0,0 @@ -getMessage()." ".$CC_DBC->getUserInfo()."\n"; - exit(1); -} -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -class PlaylistTests extends PHPUnit_TestCase { - - private $greenbox; - private $storedFile; - private $storedFile2; - - function __construct($name) { - parent::__construct($name); - } - - function setup() { - global $CC_CONFIG, $CC_DBC; - $this->greenbox = new GreenBox(); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10001.mp3"); - $this->storedFile = StoredFile::Insert($values, false); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10002.mp3"); - $this->storedFile2 = StoredFile::Insert($values, false); - - } - - function testGBCreatePlaylist() { - - $pl = new Playlist(); - $pl_id = $pl->create("Playlist UnitTest: create ".date("g:i a")); - - if (!is_int($pl_id)) { - $this->fail("problems creating playlist."); - return; - } - } - - function testGBLock() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist Metadata: lock ".date("g:i a")); - - $sessid = Alib::Login('root', 'q'); - - $res = $this->greenbox->lockPlaylistForEdit($pl_id, $sessid); - - if($res !== TRUE) { - $this->fail("problems locking playlist for editing."); - return; - } - } - - function testGBUnLock() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist UnitTest: unlock ".date("g:i a")); - - $sessid = Alib::Login('root', 'q'); - - $this->greenbox->lockPlaylistForEdit($pl_id, $sessid); - $res = $this->greenbox->releaseLockedPlaylist($pl_id, $sessid); - - if($res !== TRUE) { - $this->fail("problems unlocking playlist."); - return; - } - } - - function testGBSetPLMetaData() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist UnitTest: Set Metadata ".date("g:i a")); - - $res = $this->greenbox->setPLMetadataValue($pl_id, "dc:title", "Playlist Unit Test: Updated Title ".date("g:i a")); - - if($res !== TRUE) { - $this->fail("problems setting playlist metadata."); - return; - } - } - - function testGBGetPLMetaData() { - $pl = new Playlist(); - $name = "Playlist UnitTest: GetMetadata ".date("g:i a"); - $pl_id = $pl->create($name); - - $res = $this->greenbox->getPLMetadataValue($pl_id, "dc:title"); - - if($res !== $name) { - $this->fail("problems getting playlist metadata."); - return; - } - } - - function testAddAudioClip() { - - $pl = new Playlist(); - $pl_id = $pl->create("Playlist Unit Test ". date("g:i a")); - $res = $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile->getId()); - if($res !== TRUE) { - $this->fail("problems adding audioclip to playlist."); - return; - } - - $res = $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile2->getId()); - if($res !== TRUE) { - $this->fail("problems adding audioclip 2 to playlist."); - return; - } - } - - function testMoveAudioClip() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist Unit Test: Move ". date("g:i a")); - - $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile->getId()); - $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile2->getId()); - - $res = $this->greenbox->moveAudioClipInPlaylist($pl_id, 0, 1); - - if($res !== TRUE) { - $this->fail("problems moving audioclip in playlist."); - return; - } - } - - function testDeleteAudioClip() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist UnitTest: Delete ".date("g:i a")); - - $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile->getId()); - $res = $this->greenbox->delAudioClipFromPlaylist($pl_id, 0); - - if($res !== TRUE) { - $this->fail("problems deleting audioclip from playlist."); - return; - } - } - - function testFadeInfo() { - $pl = new Playlist(); - $pl_id = $pl->create("Playlist Unit Test: Fade Info " . date("g:i a")); - - $this->greenbox->addAudioClipToPlaylist($pl_id, $this->storedFile2->getId()); - - $res = $this->greenbox->changeFadeInfo($pl_id, 0, '00:00:01.14', null); - - if(!is_array($res) && count($res) !== 2) { - $this->fail("problems setting fade in playlist."); - return; - } - } -} - -?> diff --git a/backend/tests/SchedulerExportTests.php b/backend/tests/SchedulerExportTests.php deleted file mode 100644 index 6bdbd4ee2..000000000 --- a/backend/tests/SchedulerExportTests.php +++ /dev/null @@ -1,42 +0,0 @@ -query($sql); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10001.mp3"); - $this->storedFile = StoredFile::Insert($values, false); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10002.mp3"); - $this->storedFile2 = StoredFile::Insert($values, false); - - // Clear the schedule table - $sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"]; - $CC_DBC->query($sql); - - // Create a playlist - $playlist = new Playlist(); - $playlist->create("Scheduler Unit Test"); - $result = $playlist->addAudioClip($this->storedFile->getId()); - $result = $playlist->addAudioClip($this->storedFile2->getId()); - $result = $playlist->addAudioClip($this->storedFile2->getId()); - - // Schedule it - $i = new ScheduleGroup(); - $this->groupIdCreated = $i->add('2010-11-11 01:30:23', null, $playlist->getId()); - } - - public function testExport() { - echo Schedule::ExportRangeAsJson("2010-01-01 00:00:00", "2011-01-01 00:00:00"); - } -} - -?> \ No newline at end of file diff --git a/backend/tests/SchedulerTests.php b/backend/tests/SchedulerTests.php deleted file mode 100644 index 36c0084df..000000000 --- a/backend/tests/SchedulerTests.php +++ /dev/null @@ -1,128 +0,0 @@ -query($sql); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10001.mp3"); - $this->storedFile = StoredFile::Insert($values, false); - - // Add a file - $values = array("filepath" => dirname(__FILE__)."/test10002.mp3"); - $this->storedFile2 = StoredFile::Insert($values, false); - - // Clear the schedule table - //$sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"]; - //$CC_DBC->query($sql); - } - - function testDateToId() { - $dateStr = "2006-04-02 10:20:08.123456"; - $id = ScheduleGroup::dateToId($dateStr); - $expected = "20060402102008123"; - if ($id != $expected) { - $this->fail("Did not convert date to ID correctly #1: $id != $expected"); - } - - $dateStr = "2006-04-02 10:20:08"; - $id = ScheduleGroup::dateToId($dateStr); - $expected = "20060402102008000"; - if ($id != $expected) { - $this->fail("Did not convert date to ID correctly #2: $id != $expected"); - } - } - - function testAddAndRemoveAudioFile() { - $i = new ScheduleGroup(); - $this->groupIdCreated = $i->add('2010-10-10 01:30:23', $this->storedFile->getId()); - if (PEAR::isError($this->groupIdCreated)) { - $this->fail("Failed to create scheduled item: ". $this->groupIdCreated->getMessage()); - } - - $i = new ScheduleGroup($this->groupIdCreated); - $result = $i->remove(); - if ($result != 1) { - $this->fail("Did not remove item."); - } - } - - function testAddAndRemovePlaylist() { - // Create a playlist - $playlist = new Playlist(); - $playlist->create("Scheduler Unit Test ".uniqid()); - $result = $playlist->addAudioClip($this->storedFile->getId()); - $result = $playlist->addAudioClip($this->storedFile2->getId()); - $result = $playlist->addAudioClip($this->storedFile2->getId()); - - $i = new ScheduleGroup(); - $this->groupIdCreated = $i->add('2010-11-11 01:30:23', null, $playlist->getId()); - if (PEAR::isError($this->groupIdCreated)) { - $this->fail("Failed to create scheduled item: ". $this->groupIdCreated->getMessage()); - } - $group = new ScheduleGroup($this->groupIdCreated); - if ($group->count() != 3) { - $this->fail("Wrong number of items added."); - } - $items = $group->getItems(); - if (!is_array($items) || ($items[1]["starts"] != "2010-11-11 01:30:34.231")) { - $this->fail("Wrong start time for 2nd item."); - } - - $result = $group->remove(); - if ($result != 1) { - $this->fail("Did not remove item."); - } - - Playlist::Delete($playlist->getId()); - } - - function testIsScheduleEmptyInRange() { - $i = new ScheduleGroup(); - $this->groupIdCreated = $i->add('2011-10-10 01:30:23', $this->storedFile->getId()); - if (PEAR::isError($this->groupIdCreated)) { - $this->fail($this->groupIdCreated->getMessage()); - return; - } - if (Schedule::isScheduleEmptyInRange('2011-10-10 01:30:23', '00:00:12.555')) { - $this->fail("Reporting empty schedule when it isnt."); - return; - } - // echo "groupid: ".$this->groupIdCreated."\n"; - $success = $i->remove(); - if ($success === false) { - $this->fail("Failed to delete schedule group."); - return; - } - if (!Schedule::isScheduleEmptyInRange('2011-10-10 01:30:23', '00:00:12.555')) { - $this->fail("Reporting booked schedule when it isnt."); - return; - } - } - - function testGetItems() { - $i1 = new ScheduleGroup(); - $groupId1 = $i1->add('2008-01-01 12:00:00.000', $this->storedFile->getId()); - $i2 = new ScheduleGroup(); - $i2->addAfter($groupId1, $this->storedFile->getId()); - $items = Schedule::GetItems("2008-01-01", "2008-01-02"); - if (count($items) != 2) { - $this->fail("Wrong number of items returned."); - return; - } - $i1->remove(); - $i2->remove(); - } -} - -?> \ No newline at end of file diff --git a/backend/tests/StoredFileTests.php b/backend/tests/StoredFileTests.php deleted file mode 100644 index e2ebcca08..000000000 --- a/backend/tests/StoredFileTests.php +++ /dev/null @@ -1,87 +0,0 @@ -getMessage()." ".$CC_DBC->getUserInfo()."\n"; - exit(1); -} -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -class StoredFileTest extends PHPUnit_TestCase { - - function __construct($name) { - parent::__construct($name); - } - - function setup() { - } - - function testGetAudioMetadata() { - $filePath = dirname(__FILE__)."/ex1.mp3"; - $metadata = camp_get_audio_metadata($filePath); - if (PEAR::isError($metadata)) { - $this->fail($metadata->getMessage()); - return; - } - if (($metadata["dc:description"] != "Tmu sem tam videla ...") - || ($metadata["audio"]["dataformat"] != "mp3") - || ($metadata["dc:type"] != "Speech")) { - $str = " [dc:description] = " . $metadata["dc:description"] ."\n" - . " [audio][dataformat] = " . $metadata["audio"]["dataformat"]."\n" - . " [dc:type] = ".$metadata["dc:type"]."\n"; - $this->fail("Metadata has unexpected values:\n".$str); - } - //var_dump($metadata); - //$this->assertTrue(FALSE); - } - - function testDeleteAndPutFile() { - $STORAGE_SERVER_PATH = dirname(__FILE__)."/../../"; - $filePath = dirname(__FILE__)."/ex1.mp3"; - - // Delete any old data from previous tests - $md5 = md5_file($filePath); - $duplicate = StoredFile::RecallByMd5($md5); - if ($duplicate) { - $duplicate->delete(); - } - - // Test inserting a file by linking - $values = array("filepath" => $filePath, - "dc:description" => "Unit test ".time()); - $storedFile = StoredFile::Insert($values, false); - if (PEAR::isError($storedFile)) { - $this->fail("Failed to create StoredFile: ".$storedFile->getMessage()); - return; - } - //var_dump($storedFile); - $id = $storedFile->getId(); - if (!is_numeric($id)) { - $this->fail("StoredFile not created correctly. id = ".$id); - return; - } - - // Test loading metadata - $f = new StoredFile(); - $f->__setGunid($storedFile->getGunid()); - $f->loadMetadata(); - if (!is_array($md = $f->getMetadata())) { - $this->fail("Unable to load metadata."); - return; - } - //var_dump($md); - - // Check if the length field has been set. - $f2 = StoredFile::RecallByGunid($storedFile->getGunid()); - $m2 = $f2->getMetadata(); - if (!isset($m2["length"]) || $m2["length"] == "00:00:00.000000") { - $this->fail("Length not reporting correctly in metadata."); - return; - } - - } - -} -?> \ No newline at end of file diff --git a/backend/tests/analyze.php b/backend/tests/analyze.php deleted file mode 100755 index c1435b9c8..000000000 --- a/backend/tests/analyze.php +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/php -q -analyzeFile(); - -echo "r=$r (".gettype($r).")\n"; -if (PEAR::isError($r)) { - echo "ERR: ".$r->getMessage()."\n".$r->getUserInfo()."\n"; -} -if (is_array($r)) { - print_r($r); -} -echo"\n"; -?> \ No newline at end of file diff --git a/backend/tests/ex1.mp3 b/backend/tests/ex1.mp3 deleted file mode 100644 index 9d1f20156826f852d5362b8e73795cde983a8ee8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48611 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%0DD$mQWKc`}W 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

    &6{Ju<1&cR~#&fhE6NtMa@;`+|w{FKT#_rcQ* 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

    ;GaII%WRlLkqKr$|Hp$?!5 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 diff --git a/backend/tests/index.php b/backend/tests/index.php deleted file mode 100644 index 125fdaf8e..000000000 --- a/backend/tests/index.php +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/backend/tests/pdoTest.php b/backend/tests/pdoTest.php deleted file mode 100644 index 3aae4465b..000000000 --- a/backend/tests/pdoTest.php +++ /dev/null @@ -1,22 +0,0 @@ -= '2010-01-01 00:00:00.000') " - ." AND (ends <= (TIMESTAMP '2011-01-01 00:00:00.000' + INTERVAL '01:00:00.123456'))"; -$rows1 = $con->query($sql); -var_dump($rows1->fetchAll()); - -$sql2 = "SELECT COUNT(*) FROM cc_playlistcontents"; -$rows2 = $con->query($sql2); -var_dump($rows2->fetchAll()); - -$sql3 = "SELECT TIMESTAMP '2011-01-01 00:00:00.000' + INTERVAL '01:00:00.123456'"; -$result3 = $con->query($sql3); -var_dump($result3->fetchAll()); - -?> \ No newline at end of file diff --git a/backend/tests/plistEmbedded.xml b/backend/tests/plistEmbedded.xml deleted file mode 100644 index db9b7ce03..000000000 --- a/backend/tests/plistEmbedded.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - embedded playlist - 01:30:11.500000 - - - diff --git a/backend/tests/pypoTester.php b/backend/tests/pypoTester.php deleted file mode 100644 index 4443b14c1..000000000 --- a/backend/tests/pypoTester.php +++ /dev/null @@ -1,85 +0,0 @@ -delete(); -} -echo "done.\n"; - -// Create a new playlist -echo "Creating new playlist '$playlistName'..."; -$pl = new Playlist(); -$pl->create($playlistName); - -// Add a media clip -$mediaFile = StoredFile::findByOriginalName("Manolo Camp - Morning Coffee.mp3"); -if (is_null($mediaFile)) { - echo "Adding test audio clip to the database.\n"; - $v = array("filepath" => __DIR__."/../../audio_samples/OpSound/Manolo Camp - Morning Coffee.mp3"); - $mediaFile = StoredFile::Insert($v); - if (PEAR::isError($mediaFile)) { - var_dump($mediaFile); - exit(); - } -} -$pl->addAudioClip($mediaFile->getId()); -$mediaFile = StoredFile::findByOriginalName("Peter Rudenko - Opening.mp3"); -if (is_null($mediaFile)) { - echo "Adding test audio clip to the database.\n"; - $v = array("filepath" => __DIR__."/../../audio_samples/OpSound/Peter Rudenko - Opening.mp3"); - $mediaFile = StoredFile::Insert($v); - if (PEAR::isError($mediaFile)) { - var_dump($mediaFile); - exit(); - } -} -$pl->addAudioClip($mediaFile->getId()); -echo "done.\n"; - -//$pl2 = Playlist::findPlaylistByName("pypo_playlist_test"); -//var_dump($pl2); - -// Get current time -// In the format YYYY-MM-DD HH:MM:SS.nnnnnn -$startTime = date("Y-m-d H:i:s"); -$endTime = date("Y-m-d H:i:s", time()+(60*60)); - -echo "Removing everything from the scheduler between $startTime and $endTime..."; -// Scheduler: remove any playlists for the next hour -Schedule::RemoveItemsInRange($startTime, $endTime); -// Check for succcess -$scheduleClear = Schedule::isScheduleEmptyInRange($startTime, "01:00:00"); -if (!$scheduleClear) { - echo "\nERROR: Schedule could not be cleared.\n\n"; - var_dump(Schedule::GetItems($startTime, $endTime)); - exit; -} -echo "done.\n"; - -// Schedule the playlist for two minutes from now -echo "Scheduling new playlist...\n"; -$playTime = date("Y-m-d H:i:s", time()+(60*$minutesFromNow)); -$scheduleGroup = new ScheduleGroup(); -$scheduleGroup->add($playTime, null, $pl->getId()); - -echo " SUCCESS: Playlist scheduled at $playTime\n\n"; -?> \ No newline at end of file diff --git a/backend/tests/question.wav b/backend/tests/question.wav deleted file mode 100644 index 6c8b2a0cbfbd7dde822e8b94858217ac437034c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4189 zcmeHI$#SdO74@5Cm_JB+3OHvowdx_FNjwXl9k&rPQaRsadsMf!GnP zZjRSF5XKWBI9-o{IvKOhu5C9eJDMw-%e6);ist>p^%RTDh%>icR~pOlR7%cW<8m}5 z;{ElK%G1$82lK5l9ZwCS;Uz`M+2MU33FEO4*6+tmrbY|*a6QM`WHfi`u1!s5#F*8! z%hmZCtCiPlsj+W!C-2&=!MshatnF%hHk#<=<&s%5urAMSffi#{-CVk@#Zyx$K6QI6 z(G%Hg+G8Y6VeV~v$=6egwX^f3LQ9%a{iZ#HB25ckc{%3#jGCLt=~B2nJ(1$N-KVgx zCCV?S)MBZrmLJ=#FHp1?)otU+6IkKCJ;es(StT)N$Lu4}mZy2|G%T1uO)j=2#drCnFq{OfF$UT-xL-sp95zBL{wHxNB&m-ifVuX80n-)dK;#=Kj>uMZJq1elD1sdY>R+##`yJNi30BnQ?Q-9C<2eLA}qB zIOj}vdnmE8Txec?%6)w?S5VSyV@H^YPEyq|mS>#d=ZB4_FF6(E&DKM!`O1m6`vj}( zN_Wd+flYoXqpYq1OPonoxNB0hW`#8_4~4tt7aH2^3eONZ4LtL}T5$>rt1@;ZPICNm z8zPxoSy55NSmgvW$ae`^bE4swy9{akO7n_pgB4yd-Mq@(wICSan0gw|YhGGyd_&;Z zcvIz`wGv=}vJ8+cNOn|~k+T+L!z;=Z8>^LxvNHD!SNrUg zS65XN#cARhs$!rhjeU>|On|NSMu`hXI()+=E?PerO)(rFY9K?=9XCmQu+|(Lry*Fc zZ5*Znq=B`UMjp~s9eHu$fd)anwqBbkNMaWmx`o^@a*?f@4hlmLAzinTAB7m10Ng0T zy@sR6N0zQTC{57lp*h1Sd!{bOU)Iq?tVc$pmkZJjlNT5`)9g?_>J1 z#2N>o57vfFY9M477V?7tj0~_20%+1OAt>;WW12SdJm}W89pri*G-=xiC>J>dxUM^B z_&b{ClJHM?PXho@1vE(Ood!U>F=&JLAXy}z6tSQh0TwtC37Cfjjr8>$0Ekp|AO@oE z|GY511M~qt&{KO*&+rF<@CWtaJ~4!Xa(xio?_fZnJf+VJ1Pxg|Aj-ge0pySWy9?$b zBloKw0Aa`&@LWIw_?+D(=<9;WdFrXB24{>=cY|-jdjpW**pQ%y`B0EBL?gZQpfCJj zhC4{liyWH18tD>~vVFVX1H_RWf8t2qgKwhy<44XR3BqJ>oAl;BsONCKHk2clUv@DZ zDALMfP4~@#(=hiP^m7l}CGQVtL*0jCzrbfp4*)HZ-e6<``lmBYLehqyyGGi+N0Xh9 zm+WbIAK-5A%o`>ddID`2;L-OmCD1(}I~iJeR{0FRuB3N-?DUgFo)_u+VLdnkGt}r; z(vRB*eeLKw)F-Fj;0FVI_j!?N@0QOe_}}w~CVv$3&zDk4`m?!9q_57EQFEu`t56h>)Q~ZI}_x23>34U(i K=LY^48~6`~3n8=s diff --git a/backend/tests/test10001.mp3 b/backend/tests/test10001.mp3 deleted file mode 100644 index c5631e435ad823d1ee6d4ad564f3a4f2c81f863f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179802 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ɭ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%0ARrku@RdMZ5Fbm86abccSMuTj!px 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 hoKIC8;I565@0%8`X7E`R_gU2;wz@EuUSid? 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

    &9b42_E70hA*^svt;G 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

    +*T>@$*R;p`nXKc2F9b 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 z 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 diff --git a/backend/tests/test10003.mp3 b/backend/tests/test10003.mp3 deleted file mode 100644 index a98fa3730cbfc9c836f47e4b8bd7a0df062e5364..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184830 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�SW$h9y;USRO};4)jQ%R zL8WMp+KCCs5BG6$EN7}SjD!S1{Xs-&URa(;ns0VM@)Z}qJbw-vWYUx0CF;4cT3VTp zAZEyaBolj?)XZ(DPe`G#HVkNYf!;Yo7wJG^z-`NK)yq?a*NzMz;svLTZzV!E)?}Kp z#X}7;@v`Qm!XPC=v@SJ z>{gUj-Nt21NJJ9pq=;d}SSp@;%+Jz5e4Pu`Pf&hJ5bxiXl3hNH`vo>-Ll#TRo0L* zb?vfPE*DN;M zbS|kDQ%hMn@l}hV$C`RMCPcRCPTe0aV7diAUi{A#9PY|^-RceTlpacy48Nt|_>3L6 z2+`rS>%-iXfYt*;o-B<^WYsav#A+DYP2tTUkZay#b@q-pq9r1AFgs({?yC$V{Kna7 zCvDFt`&-eh%khiMmfMkLHj_(es9fm<;qyX)7W*%%UHz=E(k^O5%Q{d47;TB;<2Unq z2mqE6&YlP8Z2N%{o`D8WP;OG#c{xndPw8iU(ZeD6j92x;P4R)>r)&i7J?~b1dgw2{ zoXyiP9T8Oq^sJ;NHJN74XXvwT&j2^^%7KvHGq8uB8VVICKnkndE`gInRl*K>=pO5#NTGlZ`0~lS9*(HIyt%}_0+c6EL<+7v0WCCc6)I@2UQa? zNHsm!WBau1XQVh3kQ^O|!=XE`$cTf1Rd*B``<04rhvz|jX*Q1~37W@6?w4*{r2{w^B+vLNl9dTadeXNxf+Y&rDLw3*>$A~C6RP4obb@+JwH96`#L{&H z6gD5JuQg+K^U?Ri9re;!5ew(GK4pG=K_h)W>zW*uizJF@*{^4kL`LHJ%5$*KPIcy? zhDwNdrAj?{=?Fz4jSmgIc6;2(7?ufi3nMsjeB@5#_mVgkr-ZL-5DZgM(C?ZB$xh&B zjmgqr6FV|AP)@)E-?0Ui+?8JUV})abTF!miw8mJfQM9E~5(W`xFUMHo;aJ%Bwtubh zEz$d3Si0}c>$s$Ckmt8ZCIlFfSznNn zP04v(>wbOjqod3$eR+tcqXAK^jv3B7_9Gw|Pc(!ye99+OMNkzt0w5SVv~BXA9o;60 zwF(xjW_6$AqBSs_JNS-*XfM9%hO6k%^#n&-8=M+E^F^}rN8Jk>R%qjxJYmy}h`Syb z4F&|O%5r{wzGg-E`wm^IZ_bbrrs`U+KA=+cjpv7b`HiYHW1VrfZ}c9!2#7rnb7*P*3ongA=2STG|amM_Y0)lY|et+R=o;$;PGN3CZs<589z7%WE|Mc(w(qdT$j zCkC}*Adu1ZvAQ-Tw`Ga3%jVRBP`YMJ3;`vR1~2)t2U-vu7`&F|fJp!I0Df?Hr(f7q zM%r=5g`L;~kGW+-^2>=eLfWcGXGQDNrI3}Wczi@qf~k6L+EK>WCkipTdO(z(;E~=% z&q<3}YqjsxZxHUXv|)gY1l(+n2lNKPQ|a@VVRqQf_i8^1OP6MJQ>2h%vwu*QJ>VQ_$76Mu`MpZUSOi6ygYNte83 z&Eb>J4USi7`#}cx=`QBvkes$BZ2k6zjFU2S$=Y!wXrdRf= zej8GP7cQc5)nYQiDg8X<6ylu2j$-ZBw^bK;WRFdZ1Ig7diB`s#y?m60&;tAerozeL zj3quKoT zY3j96;5h1__#oq(cSqB*`ih}ymwVSR5pzVdzz9=Qrai){(%VPu=r=7;3LBvxySSRs zDGV_<>Gs?Q)j}BI2rzbufFay2laVDl-&LcyKDoW*h&XUs2<}uqDo=IJE;Q&+7d<}z zfc_vP5K9tC3Y7eQa}my50Xt&%ZQGxZp_R5h*T!c+dOK=r@N9S->i$hOftZx~y5*OA z%Zu3*^;+}TAD$+wf#2phcDYh?!6my`bNyOV1oHO zaAM9sV#WGX_OWoI>eu%3H*!>_9_1s4Cz4*_F0WujUr$Aijpx=ICwA1T;gKjkbi(dA zZEI5+35MbJVverqj*Y0CYBTp2Z!HqBP$>>a+xREI*QW%sqUblVG&)yFC(!2?f5R08 zS-8Aa>sqr-IFUt7E@ULeAK~d@g$R>aA)@#|P6<412OVSSuVSv9^9|f>I)s|$-9rZ0 zTt6uf;>&o)hG}vJT_6-UC!c8x z#H++_12!ewS#VL>q*jiikM+R5uLCi+{^`)(Wq$D|KVSzmG-Ym-l|j>&l?4YigRT{u zl1bxNZ0~TK$p&*mCnm2?xs|A;r@T5Mj2dd8ty1|*(BDRGok#8}gbOqH*%=KhHXoX3 z*vV$*x8GJUU@l8y6|1rDn1FYr{3g{1mI^s5=5BB+vp%IFiQ}z;5MfZmyVFi$&8W^u zsT^t@_X%6yd=R2|*dK{Venus6&mc20HVJ5$y>QOU7<%B^zrJh(M z0X?{gfYoVXyjC*z!IDbX?-@$U4~})^|3;a6M)g;}M{Yb;0p(w%+@+r30VQ##0sX7Q znpp-)xx=fFr1HIU?Wt?X`!zsva!T@VtBwq?1CvS=$J3&{JYEqzxs?6X{;sZuoZK6u zb>u(f=fz`BHf1&mt^B8Ki{l`y$=HOqKi*=4mvbcJa_fawlR ztb}_ajyi);YU*myBijsQT@-tVFB-SN56ytan{2z`F!!*hkd~(PWs8TrL!1_YA8?() zS!wsDBu~yP=a{py;SI$k7@JpGt?0F70qN!kfpfhK^I2W!(0UBq)p2gIA{WpXYG;F6 z#N=F%DcJpL=JS9AqaeB#V>PDws0`&Rvz`V=kVgN zCxfwzMHwZ6HA+BY%q(O3abS3jrFVtdXe+b?3wbWQtuUZ9|o1Y9P5 zQvA)U?3bQ+xL`gG4QzqesUhw6d})>)E(s>3u7m%fL!Z;$w4%gictvgVGVJ!qvD%r4 z=h=V)S&sL6Q|?57^G=DGAbO=TqLqL{y{_fntg1@YJTS16YhNH&cNM-_Ccz?*REU|k znPOSBIOTNs=7E*UQt5|YRvTmT$;f7*?M*vzWY4NvE$y>(e}x<>*-zg0jD|tJhA{AO zn6T0c^-2J+o;acg-Q41XO?hlCi%FW9<6h}w+dN^1tIhgi>tkj94w{>W+^x&xO=&U7 zqy))_*p!~cZ8$`6$_U+i_C z8{9qTu(Y#DWjc2+eE>c6Q_ANQL;o&nI2-}e*&qCli-y#qn$FD1(?tva?kaSxe$OK| z1cFW`+DESRWv@!LPU}ONcfmW`uewkM^LXEm%#uka@D&zCdJtT2c+aC-PGW(A1{R*0 zd49OLI~00ND8h8*QK?T`nE9>7l z?g<`@RapUP@i4Co&#TT?RD-4`wfLj~GkY@f#~u0GT;v*g+8AjZmG^-^J^XKf%NZ~B zdqR_FwQ)$hMWkGkoAy3aWE0rY_9MRd}M8RQ}6omj>lf>!zK$d5URfwmx= zciYRiWVv9c#&U7r`AA!pU#g!zRD}$rQkZO3R8$_DHxS^+ zom%8p&xMka8-MAX2xW>^=8oa(Oo+jekD{ZZ2kA89;8NHa+Op7~4I{DZ5W1|aHpd8d zn$6;v>c!E0YRTcX_(oWN=f-v24z5ab`f)(?hFrWD(`s+L{%H^vBT-dZkaW%gn%7!4 z^BW^vWFK;MZ}sP%9X?%}6CURyH`PBor+=4n7t$L_a3mjf$G?{27vx6O8@NyaZ0kL$ zj`x#L9pQ6)f>&s#LS4uSIIetTO7$Q>xD_S+jMFy{hkO|dLhWu1J>MzWB54*RXphxm zvFCUuRy38fF?;4hUbMk&csa!2j@>&1kzY&B4ks!_Ctu$K!bXZdT1d^6fY+%pce-ri z8(nt=zRyg08*i`?n5r?16>!C0ThZuf{@zgcrb#anU(}w~N@(OQyKG;Um(-a}6IYF( zLxnGo6q|eW+o*+fM}l^}6=H&pq?j(tgNMFQh7*onkvX&>!^-Xxz@F4n#;w`c4L0E4 z4}L6uvn5=%>>9VXE8M?F)(gS*_K7-Ce>DG!NbTi1`f?kR!>GH8j2JTt*%X|(pHipC z_}2Ek^D+z3Cp9=5I}|p06=ono!=C6~G{Qh2fRV?${*OfhzYP3nTF2eu9^po4S{GUPYU*n-`g*7YKkC}S1e6Ram-6#hp9^wf4Z2^q7`@Lw6 zFrjA0X><~D35cERH2rZ2vtN96fK4Hp#eR?EcTBra@s#xZ?j!PRR}|h9jOkjmt|2su zLMHMjBL|)ajNWR50I9;>4%WMHXg-GkzG zKZKluK#cXXwPiQvRf(5JjFlrV=Ct5hTjA)-v%Sw(@3>?>=ay2 z1KH_B?u)Fc&i`c%_|$HN!@Xrs>j%2G$ZehPE-2DAn11W-l$vQE8wk|0_acjxZdG z-<=LSIb^!tn4RX~q0|<6tVr?mPKIj>QxXv_GnWf14-mQ@q1I92Hz)mA^)p@SrR}E{ zvbJltpcYxDFas4yLjR#2C>-$5I}~`Sy{<$_Wd53mGJ$4(Q3)2Wa5=YoPX=50P^4E* zho79l#KYfI)OMquGs>=(hjZnQeRCc(FNSy3AVaf9!>Upg(P*XxJjE*}C^P{RdbyDzJwL)ez04c&jrP*F#}Kw1Va;Brg%nF+ zHSuy!{EYghx67b4$Gi}_uqEfvo^!=J=GZ+kju5*&RLQl!vRJWlcsz{7hMxVkWWr`l zr>VU#iZfyU)0Fzz*u?ERd$ks^9RC|}q0;diynao$LwieDPzHhgl z9+i+Oy_1{P^X3@@>V`H7tH+HxMdVwVQYE$mjd_p-)o)M98S2{|&(rn`QBWW2u*{RssEy~PM{rzZNMlmwP;n&BcS6%E{Y~m*|yy7;_!F(+$ z(CdisD8JUSvIhh#aa+8^A4D4}cCHZ-0rxDzeAMYidp+ZKg51O=Etmmn9yJnyp)^I! z+Y{-NgN?J?Zvlc=-nkq(HF=J-z{Dgwsuj&Q_CwMsaHhs|yg!C7`q3jkha@p@(Aa^W z9l=@(F9r~kSh^5ooTw%3%6m)&1B+a? zPuP12G-FSV<;m}wT8ZqI`6~+p95P*l{Yt{@zVhB1g;Bye*63J=kkrn9awI|=q1bb& zygXPeKtdrkQ=_2druHu*UuxSu74QI?3yt3&I}Ix4i|!m%t38F6GB-|08{!)WzuimV zk-wNK{wI#)Ur}yF_xAzpM}9q8zIGsm@dT`g2Qb){HKN*)#xN$#48yd!oFP#^ZQVlZ zeQ>W%n1och+gapfNDtRHKTjSaD+!*MoQW0F2RB;&0{QbO3~e*@F0K-Tmxx4hA!vMh z_fJ>>G8~_3ozg*p_g8jKL-cxaXok?*bWLeI#i4{e(q^ zJ^nbMlhOMH9JidHJ|O|kgW8=L<(Q6c@YH;)q{&AxH3i>(0sqKrVg7oSaJh3u-{z;b zhe|C%i_-9G1yLXG^%2s3;Gyy@Ctc9SBMxI0TGl&#g0w$ks&RtIJiSh%tlB`_Q=IYR ztFx@OM6{MrJyDCn;l&jFt}b#(sN|PdfsB$8Y}zNfxP*}l0q0gkH)mwxs(L$r!!L2{ z$8WX%Rm;J^{p49!g2f%vf5(>zq-d1Ak9rk-_~PVST6e{c9t#6^!J`xFWh{|A{f7V> z&ai1qIJk(_ytO&bBe4%Ff;$OqogSSnA=Df`Q}-!+h7vKZ?PmMNn;^F`-7HAqbIs;! zkMYsz;*cbz72Ntj>ESe*XAduVS>g?iw|IrKe$cUhNY)k|1-Sl^W1EE;n>Oaoaf!}f z%1%SAs^r5qkkuShD7KW{q29cwW&Ln$AlKLWOo4j zg0$$7rXQ8xD3rNY1AZA92RSIV1A z0~SnENUMVB_aXCF!a9NJwOaPyVkOY(nojgNNEflOG3~iW= zWUojme85|^A|!Ot?L;0%>jh*qHy!XD8gguAAwGNb2?R(6bcF<;+4)vF}>p77ns-7-EXn$eQ88g~H#;p3T=T0tyM)x=T+n)LKtZ##*3J%ISjgJvW7dI<8``CXH|{+4df5H)0IN()H<-z6lbkpz#A%}K(A2a!26#t) z28veXHH_p1->-ox3$_vGWQTiB)+-mvU|=$lpRbpSC5F=f#EWUweB93b%K=X%dZW8b z2dX2+C$Bo;UuV>m24OF+PMWWH5|+u)X=FY!Kz5{3jN<##`nuTmD$QjzXK6i|J=uHs zz^{Bc3xnJCxN$!KZv(g@WccukroL#de3l2`#{ud~G%ysUC&8#ZK0nVpb@Bz1Fixj# z6cQ8YTkX^62qaX06O_=kJY5hE!5WM}Z|e9+;Tq-QU$y@rMyAz{7Qf!Qo*wqpLWh=~ z0Wg*ZjP`>&jeSGeURE#zo^N8vbVWocIG1}5s% z7IS|xUlvEkk70E6)BIUl2PP*<$Re0!$Q!Kp>_@6SkT6^_oTu;~?LGz)XF}_WEEIKSF=zCV8mPGF(+D_B<&b}&+1JnhQVWAY^d}P zWvH%Zcygm45T~RhXSJ%ZfqG>vI=#g|pqT@gR!9B^qVU?5`&S-X(lJo%XX4kR*YRaB zYm-AWvfN8{xVNi5j=l=-0=4gqntI(E_fw~2)HkaWG(0*)KCC^+&9A;#dI%OS*ZLwx zTS#)~t!i+&IZLw33=K$h+)R3W9>Cw+&l5}8IBdk zm>lcHH%2-$hb3G)c;pJ|pO9hS`PV}^wCO!ZOz5)e=W;^5ZxRB~nK~9Oxd|j_r1>Oh zo5I8*v7yk1eDAN%@E;I9h-Eqvi#Y2EW~$t-y>tnZ!|=hJ2S{r>^(SB<57WjsDru|9 z1*DelF~}CGp_l+zfbe(_ny?J<8NK+a-W9fY>TC>`p;&OSWjPx;x*h2f@M#*g{PC&#Lj?QSO)S)~lc~!|NUL;_qi3U)R&OWs&Oj zXE*^~r}T)F6IC-dH*B0wquA^>V0z>5nXX3{R|5L&qiJv7yb@%EbqVEyGxJF=C?rEwCROU@*HceikC!M)Q;IONN`sr{+6?%zIevr=k7Y`&td{N`+1%cJ>#*^9h|F9V8%5*O69zBo zEZd%7Xrm2M&lZQ(F#o>gKE8W`wQSm+Gq0Bmnb^-YL4#3%z6GqBl`CE#2|mmK@))dMnNG}{U5k7x>BilNKx()>0bwRY&a%lzM_!Wk7rK4{4+A^Rm0iCA#Nv2$ z!a^Fy2Z2-}K6)o>J3dR`V%d)JD&s}GoV;oV&E%p8_wJqB=1b26W2X_eW?(XjH?(P!Y-JRf0CqQs_m*5`U>Bl~M?|a^T zuYW*&>szyHuBuU^#&B~gq34OCa%2)L`oD3xPvF-kIx}TBllt(wdN^haF@zRQfbWJ+ zes%VijalztUj#pHIkCZl4Wf$LMVB3?K&(8)9VRht8~%fmEv&xXZD*qMWadI%c7@N6 zljeFQ62b`wL|PYWp0qq~X0ie&n;ccJha3>rouRXq zt4Dxsn}V%@nEmHo9nTmTzrn>(8Z+#yx0e%Df3_Yo=GV_mweBOC2~F&;TN^bDd*VBu zPp;@r!%ANR9JcNbOxcmr(995H2-OIZRYvwUD-^4v0tex~LAmY$dJPL^vC2350T_`4 zf9&mCx;lFggn^6(+p$>(D67d&mq@82sss>+XRb|J$Yi!LqhCzjHN}9S(y3WV9U`mr z{F|5SG5^KvYVFbKT^)Y+yCUyj**e25mBtpsZSMCKUyqFh@S|C%hiWs{gF|c zfMN44RXVxdgg!igMBX*(v@~B|qrM0Y8-y{Zz;rz-eDU%o@FIfxJB_D@B`IVv3J`Kv zvzx;*O4XhWx*hEszj=KfBbz|jacm?|9%#^)mJJPfU>k|Y8E0M_CQb@OcN($ZU=jx? ztGhwm%}y0K_c#Lp}ofR`qo!jYCEwt?G~! zu(gTvsz|h{0aGo!P=wA*+}X}rtWsx+^>RE5wYyJ`&c~Flb$FsqZ;DDJF%z9onaA); z1$j@zC`DEHC4hWZYV)FhJB&xY57nah-BB%e3M!u2|6TPmaddjFrj&l9zA4>Ygs&rG zyZ?*0^4hZE_-O3j>U@ln&z2sYDcv#YY=pM+hz2 zdh-Q9o*Rz=&ON(T@6-Q@JZfDbQ_f&x&Jb>3E2$_H$(Wpx?wz$Bpn@X!PY#``uTPJl zx9V4|6B3)*k9FAjh$3id`FwEKjSz1HzW}g4WO39H0EWO^#dqf4?@IWjLkP{zvZKZsw;3m(tpm zLd6e*l-cysL&_@fl|^fjs1(U|2NhI^7`=5>MsUTG%2X6V^va}vWT!Dd% zJs18PSy6%@xK3(xO1Lv2)U^~tZapTUWO;J1Ij?%o;$x zn|4tk0AJK5e`AGgU>Wu!!;M2L*n|sh%62_{*?>Qq~yFfvscawOpqrvR}WG9_(7WFq&ulHn| zcdsWLG0is{g{tD+m>tiU-cR29=+6t3h@0CN!s@Q`wMY%~3A`I5BHXwnv>GEoCSLPu z$9fl~zcK3GM>Wlrb)tV_9tU7)+lnkK2!1di|C)jSTg&~?*jDVPebqbtAl91&MDGNJ z35RO01k%@2CBtbiI)q{*QH#U$L7D5XcdRgIT=+%acd$Sz9z$>X3lRt=9(D~J^Q&%F zc<`niyBD4b3ZYHcqx<$xB>BDdQpwc9X}GsYj@B<h#lvNkL!pWok>ae}#jI;8A4OCO{$cxSrYxSj3rKtC5xNidoRJsnl09 zPSsRf@%+w|P%LY|*}Ei0)fXLwY+=kXoh$Gju4i5?Nltgi62~cdr>sB_K3729Mlo#W z@;wuEA+fo-m`X7Fp0(JW(F~J_dq!9In{8iIyTMdWwou}R2f8_i>MboScZO$;SPLGV*(mq-9{-{;PPx4UB#ok#%$1l?v^N+~HdJ7wuZILn8@|9K5WNEZZ?E8AK_ zz{Gu<-}i2zarM(%9XO-bA?$B-V$5&iKG10PZlWa^2Sec5Z5G*}O-|9sEC<0(#h&TI z>b$!G-z;g?-K)sJPTp+V3cqxpLBp`d@4~A|jCDIf;>(pc>q`fHFYeg3Fv`e86%8OL^I$R3Pxu12{HR$p_#*(obPTAmgH0yDy6DR%9vLYMxSV% zpD{7wP(JCxkdxujaH##$u>PAvqe8kfq=bvQ)jDrDk~!mgHV)!2?upK|4s3~d&tPQ$ zK$5cH%O-O8iniHwrIqju^ul{X30V|-Z~h-?|34=qzkeEel9Fb~4(cp)H_?vXLF{o3 zX2gceS5-e@KWkH{8#_bxwy!Bt_7op#-0{L;5AAEZvRqGjG}VnLuw6~E!Nj1-?t|*pyVD6H!bl;H(1h~Qmjz@i2EyBQ*?s+K!j=*#air$v!49mc<&WZCes?XYBVoH@ zp_W&ZV8=Nc16o;@Xq$b#Bmqts#}WSMV*=fgNG(@zeJg$~A^zn?-^m;~UePPl)^R39 z2}Oru-$VU@D3qBEQT}~GVBl9e+eiJ_1iE86A8V}NVx*jcNK#y%JZl+rgVOPdTkuVT zi>E>8OSnnHD8%5&ZfgzkHztFZf&Pc;PQ1}pa^v(fF7}5Tkk#4w{30oY^K6lP2 zxD158Dh1QCe(hytrs)er$t9+hQgJ8iKbc72+R1pquRzeQKn^gV?P>Kz`Eu?!RiS5$ zHkxJ=M>&r^EciM;IxyL8L_CKm#86CM8|`=3BBuiwNzs+{J+{dQ>0qZ)%vJkz@{hhv zd`clC;qc_0aBLf5ma+v_Ic&nT2{j8$59pTlR?pAdLl`sr&OLc?ar`H1qS)cwQLE8pYkw}BY*M=!ga8m%;4Lyku%p$HFjPN4Ht1q*?zvbxkH9IG#Z|1 z#@(O*%Nw8@uajdO4&|&cV~_jg*sMSQw#bcxQ)^7;_!#o%&x? z;UE3KUD3_y5ge$G6M9A<-Hll>auFeRK@G0I_^7s_in0dC$h*7=Xo$F3dNLR|p?c)Q zF%r*q<46Lzh<*}*9>2UCq%>+LnavLFBvBh15t5J(hybpq&)y9#>KkY1=Td;*aecU0 z3Orm=UlcbcuK6G9J~Q}MgFsuSg$B>zzomI#tD$i%ze~c-4B+Z;!@!cPT(AW%b2C3< zPrag>cAF~CGGUchav};#Wg$p2Td8WS&36P>BrLe9H&#KKyK6;J>u%V;=>S)zD3{l~ z!YLR6wlSta5ieb4Bw5($Anb<8PbV6nn`i+u(A~t@)_)kOhPYPXW zYh{KJmgtVjWa60R$Mo2k@8u}ZczvgfpTY`&4Rznx*q79tybM5RRnfAu~0Ox^g@uc-P3U$ zzN>`6zhHd`S@0j!$yOLg(qxz>btdQB?uu9P@Re9;bx;>S1=g-6rYY>Q3k!(ruEjg#A zusJrMe0xtjsTCJc6=|eiR@6O<2F>Wa_DD1L2Z0?mYgIX6p#MF3_#fc(@&okwgq5dt zh7Zjo-iv@~W4agVkr`HNQ*o8r4vw1vn5Care2*lGM5 zpBe(uQ_?AH;EeWDhH1g6gVaH^Fi^~+r^iD)D==23; z83MX;w{kPi`l*`kH{*#xaeu%`-O{DLW!7 z%lNeS=?)!4AV3(SZsNtrGNMMTUoNgG*DHCi-i>x;HmX7rXufPbc@CT93f3n5o5QdST*gT-0Bp0|JfL#c25U z+UbQM!N{DcG{veULbg&?9% z6FVn)r-G|YDmZnrzKI;{Djqb3IS>e*H!1-$akFVV>4rzI*pFB$bH|X z&E_|*teL&XR>0uN!@^RBhD>3^Ftu3_;D;db;9DVyFaqa}2o3^&T~(+d=oA(~G6UUa z%>CfQO76E6XQDI&RuuuGivETs3ldi)ZLEb8Gc!eQPW7~-SBqH(o0^g_b1Fj4?0mWL zAi?ZK+hUY*6@gN!zyoiEIooRUWHW2(P^Q%R?MwN|pkm}>g%hfLX9D*X`gH*S02Txw z4u*w*ik4sr3nch)qE9_V)Bs+Fu3{!)&0C#JS3qgCMRYn%N9ut)dl7`0CCI?SRV|(H(w#X zu&leN2|iJMOoCynMU@Vp*{&Edt(JN&M%ceF2>9)y-h$FL?A?2ZCUh`)B0|n z+FwmYfG$+@**2g4H=5B_6o~FGOztlWyx?8pf4)Q4dioAH1#kxNc)N!M0GYkguo4Je zE{_^p-CwB%U_F_gTC{PU#E4?E`*F1jWb}{SH<5v4cLi147;;!`s#qpm40VyIA|r*C z>oG}_ZYnLX22GeV3rbPkdik53Rk)_&zI!5>Ea(2;mKr!j5<61U6DAWEGM)lLUsj|< zQw}g@V&yYc<+YONsSchJe@Y;ee%zwLvS-!pH->%VgnCn7IsJ1+$+}6sT{P6H?|#Xs z(ylmm^^Adzr`wySXTUNA9_7gDXWnQ*2k7rHA12j*{jy-737GWz8%5`w+7qc`6R`q0 zGvYim!$eBtd>k{H$FUkkqG&sByZ&M3F-Qr@@yd`1Muv%i zxmd1J!M9$jYOO*jHS(_*X)Q&&euMm_hMEg0G5%8QeSx96wy4L4%}6>ZSX zzxL3y=)E2^hr>DI(MOQzA(Qo0-$X5tH8XF92jZ)ya8OZ_k;NN>DvD|5awo;D7T#C&Zt3ab ztHqm&ClZd@Ce&G}**%Mv`Zm}}l8adV{M5rXy84V<%41q40=S_ZdJC_?v%iq9rRtCK zQFKaA+%Zy$e}%NaJMm`tE+P%{jQAEI%qo9p;$?8t3A6TvH#eb;gWIPUK`YNuH9@c; zZ$Q16q}9fBVdiX$RE;5vUBF>NI57fAq66ArX4MrMVo%kILzFGb$9n-+y}hfD--mSr zrFEz>7Zam|0z0_c`2aj)c14F}<*q#fB1Y4gte8Lj4Bs{XwELxoj3x93(?mq++t-Wd zV?_8H2YAFX0^wv_T+47gQv;~>8WxgQh#*C9fV|3fd*KlN(~dDkp}lE#Jyz(_Vl&0) zU0GQXRD8;}@l5Zu#OIcz;{LS;?ZTn3cX<%b8EGJ=Z?QC<@_v-vPVJ0FO^evKte&^G zlWO=OPd|05C8Ts4^3LEAi3ESf>EsaP<11YAkMh-dp0tT%Q9$@EH@~pzXUI>3 zHt`#e_~^Sv*)e72A8K$rnZ2kI{cZ<8L>7?gxj0j-{8UF{FOA|9GYoQ8VZF%P@Ae5z(k0w%Y{8wTL}3vyShR< zxkOlC^X+I;V?Tcx8hp6bHE2}TY7)J|mtP$};2WZhHI`t3)pHT1u7=OXAanddkzo2O zp{$WNX;*_~OQ;^I<_8;X+twWc2}Txk**x#eG21J1!`BuvWRYz)AnupOFLgsq(Rf$M zt_tc2;7`Bs%Cc-)W~M}{-m5Jhrf}~U(Z{d`C6Po( zIasFZ!yPW?r}Cuq5a`czMsu?gRn@^-LSE_5@GfcPN3AXDMD^BI*Ry(!>Fsc3RV5YY zR*O?nQ&($O=KiJ){zQz$jw)iZs}dMyG-Kg9;q#uem3dE=^+)0T)QYw0W&x zRm(3bs8B4R^Ma(1b7ogY<@PY&*{6M}xB{5PGCn)yCVy zSv)lxMmry?lUU-+j|~PRSG{Wp;sYH8=y$mi^`H4TUzVfI{o}ZD=iaij7||#PpzN&$ z>_S!8$6wymG4YwUb>U&4Wf)a?XNW!6Q5MXrOu1yl9zbvSH$5b# z?AW06|GmX}qPeQ{iQZ68#>b9C1PK4+XCqo7MD15|aTHh$1sITR!Iz%qJfYAccDyCn zkDp9_jDs&V4uF0Rgy?#+44Z%tUMBkK4#f_U>2udTztCCvP!8s&?$rF-!XNe7CDYq- zO_qv&NDNc@8nDp{Ctj7)$ep`OR0TF+<`W13D5}%JZmJN}r6X4>m06&N1o*~f4ey=HT$lF z3x+i@iNvT{y{*pk;HHk9gmNKT4Yppq;m)dBf>*LqSXH$n^%s0Udr8r0G|#!uF!Qy; zaKKSg$Nwe>4pJ92mPh2l^HFQ09{9uGpD)_TlcISrlt&zHCV}_an?&1z1`C(F&b_|& znfv(76-`2@Sr^g?jW(=cUF;hoiinV+lj@wuL9TZ3h0nqpgSF0@9+&#o(>N`95To+n z8+iY*kmmB(R8Ub5I_YbVEpJc`>g7R7P< ztUc4J;n9|yroh*6LD6Ex9RN$k_Img{>#a~J{JK;42|p5b1eugE{t(k)1g0yU>j~w{ zA5pXzYtJ*z6`#U)V@p_YFch9>07Nvrl=$xxINbJvQ1-7A&11xlH@?^}iF%cMp+B=9 z6r`;~U7D7ss#xVOS@TY_#TQJ_6&-`S4kOBK{WIrm*P}Ui7Aw*@atQI|AkmnV3Vflq< zdj(Lwoh?|dojc+ufSuLP|C_Iw=%oKD$lNTo!V#gN{KS8l9Q25o^YUkz07<=NL|Y7` zeuqJ3X^l*lv7rP!aw20F$+73xLtt)y+&EpW^AL}gIU23_279Zjlgx`Vom~4bR=&o)zJxs+Pb^DbrU zF$;H3NhRO4GQP4?obK9$SZiDdDE(URX-YDGM!UE{X3m)+zGl@*HBiBJHE<@p(@#BX zJMVIih2FgU|{zO@XE-v}`S<@gic~v@*ORih0&(=f3_k zA?_7>Hq?``CosO-#RV1smjCWnIe#0VG08W@7~?;+741S1ialZyup8nA2$I~0PiMpD zxg!s1vol*AVa%@Bw)i1Vi!56MFOuG@Qs%F4B+zNG_RxW=a}OGHm`rBGe&uU(4w-bg z@ShHSfT%iTOVZvQHkiO0|Q$4P6|klu~LVqVi-#&JGu+gt5o|yKvA?bqkRRwqIPhf`)>y3Uu-nUU&7WP z2GRKW{c^_3sdamho)Z^;iK|bUn;IXB%9XOZiNNW44NGvNLVoyW(0?jPX)INXRKi-6 zc*{gCZLx8w5IQOF#_aOmTmTxvx(d}lE@G9oZY`H+=qvh5~M$17B;tEtz_@eUYuo=IFy(kp&Y zK!RPVA2;aFY_(2DbLpfFuW#@Xts~QEVquvJ(?1fwtja*w`2!QyBM^Jyxt5cQNfPuFaQtaLdx zEyx@YkfNp2z);bCN^9YJ z2fMv}=dO$hHDiq74$Knh8rDODs@h0j`h-Cp*66#=1rx-sVf-W)u97*p+j2zqno23l z%`d-=q^*&;hzqY!3MQ*{EE~nak&iwFx~VXbn-Zo1h=Kh20KW2riq;xBqGgCDeU#x%B(2|Mh;nPc(;<&Xzt5_nnOee**Z|Cq(RxXcc21AXQ z^oSH@oQ_-8lp^2A;GoK4mk8xf@aSPY|4hjD<57>JpTk2GWlugX36glq4{C}4ByQZ4 zKc~A!9IPWlD$g6yzCDx2+%9am*RW&rItMM8C)-%$=W<1}|E9*M_Pud3vcLPx2EPOl z*!YV5DKWE9+yLUMFN1~ih84DZ*{OYkwi_j;aI|SNs#yYfW)hZy+k2Ci%;|_pinQxI z4kdHAu)*mw7H$h)NpA%6I0Vpv9C73d^c+#`;p& z*+7T3yunLJVCm5H#rh|v8nnuhFk#2YA3ILte~70){=pPB%(jn7u$J|!W#!2G9AepH z93%>Ae+JOk+`oVXeg3realVDlAS1ah5_p_NH|@&Br?>CR3Owz4heVW4E=vVpla=`O2cJxpD`U zb-Pohevxw(>Sq-hy@`>`_OXlokG@4@`1!MZwqHO>iwCpdl^`waL-z>)4HZBhou&|( zaJz{P2SS9sbxs_0?j41k5sC2=En?cJYvaBpVWjq7X;o9LKi-t^ieb?EaJnV8#yUT~ zs8w&SJY)n_R3cQA+7T@)nLq+hMY$0X(UCY*qMPiMp@%$F0YTJQ^VvS+>Vz-!s&?@p z^QFp&uu7J`lzA%h9#4ZJ*qX)?kqK;+_2}4mk*sf`)dgQQ#7L95Q4^y-=DT-xD{wZM zS}5MpY>fuPtL4wbCB2~_kj6|f4Aj*+aU{a5G0Z>Tp%abWqY>(LofsWbBMNO<>KHp& za+#m5^yif!gdN|YN*dYr;yM*9OM>2z`V#Tldi@|4r-CE~l5{>*;@z45DE_SKWfoay zut69fK`7;A&_otPXgoioX)xHPo@wxLk<8B}WX&gmZoPqHS7yYT{fptBgfXE_2!!wg z0mh2gL&UV~8-nl|HAc6x#umuY+nq4)P3*Z4&lRcO@mr|`N2+OKRXu#N-JO!s?Sm$m zGhqU9+WV{ovYZA>&cI9{hzDBNP8J9{2`6wP(e!lWh89DsyZnJd3;<6ZI%;S_DFy1f zI>Y5?5wBvvv9ESbq0I5+q-u#A_i9g_?GJm=-@W$}x!I_pj&$Vllr1?U^Pu$a5~NsV z&W&!aq*le>EmW;nDL(<<0-j<=15cbWq|-_jwu`ERg*^k$vewUSdd5wiq*Is1k>f;= zSLL}v-7UVjq?(m1fjlQ#z2A~*8e$inL3SeVF5Fp8^E{we$INi%584I@R3-2^fa!*v zXHrFuPAwW@Kn9aDaR_E2xa;`S|L%v5b@XOFG4yIw`*`r0*~3q-m|K+C2n8_EX@#a1 z08mrFqbNkCvo*<~!b(2+v$~NXU7w&Hjn~;g)l!(UDE2U9pHg$ zAt>E2`<6u$Rl*|noAq;Xc8iXLf zETzsz9D>0nqFY4Pr}DKg!yqyT(( zN!JFd&U9n$&DH-=Z)BD(o^L*~yK?>oJbm(<1F*?Fh0GrGBqYu@eUu zHQ5|t2-Oa>cH52a`Nb`W!a}6NcXO4AK#I`FM{#nA35I8$LE=FB{Ul3AOl69>EOJQ- z63YeSz-YAY!r#KI=At-7Xa0cdCnm+zs9BnNQgKdZ%5LbmG8|TF!Q;MCQt(mQF4dv%?Ddu}#-* zt-4c(>TU%w1I31&W*HwT<}o<&!n_@Q0}0GrKY$WR8MR@{BjZ5JKbISaDoDBf9@Bqf zi3N!;Cl1}@VC%IeAuE3&T(OIpCjfLk8|y5bn4q;ugBFPJ%bLBee}0VyYC`RE3Vl1r z{epq}SRU&n2k*44Wm!TvPfyW>NtOgAuY5`{@SCc!6@Qq&Mg&kzSFrp_Kx(dV%=hn zx_j?gC2zQWE>a6hgG}@95R#a{uPo3|1Kr18eDQj0K^wVTPf;-?1u6}$H5VT?h1{vZsYx8%Q;+EoD}GC-v@0kRDdo`lRi- z|2cvpzyNf|z1*)asw!2cNi;D03yy9N2k`N<*CYf(eyBoErfsGipy!0bkdClMI5Kw2 zL3x(SK(Lf@eC0J8)Gt6DDKd7Ou-qx=wI2@Kr46hp04_6L(}O6S@yta?6=gw#W8|j= zdbtl>UL%&nhbCS@!w%qGly8Lu^Oi8xrjepBnf9;)=uVnC7LG(Hi0Wr{+kf`E{-*i> zg0HmKxQ@_W^<>7LiOYa7D+U3@#0^|_-(~qo1g8^ogrjG8w+XP3S5sN z>WR;+Fh~2FW*zTrN#$%_&DZQ~Ctf;ld>lhV;2~Dfy9(bBXsUE?%ku-2zWabA_F7tD&YJ%o zTT^G2M!ZX|p`6-STA`(Dr4@);r<~^c9+NYu!u}#4xCtO)UL}h4+++l;=ySZQHqnpgw<&m)FEV zSA`G?4p&Ly`i5#xH>mjK(+R!a3Soj<00^XfhO`F`hC5DY79t({FSGt%s?UY)hg~jh zt4=j7E5&ar1VWpL(pVj?AjUtpLFxGrBTU_MyZ5j%Q3QzmUxft7EgZ#9+Iq$ zz^(UZnJk1Tr0?CAI#VpEU4(1rDovU-rRK;Ei&Oj9y=6(^Zs>;A+*GuYK)~fDEYJpQ zRTf1Ev0*kLC9O{Vvg9(>IJS-sOZXzc&4{)yY!(>O zBmJq|ItNd_%?-#Ai!I%NY_oplGBAfMXNpqeqTuS7JLZGl;+PaA&+O2rw&)Bg$m`_D zk_xBUcSHOoenpUQR0+gw2CGZ)I*nLeTrSs&>1nKx!Z>=<(Q`B*S9aXy1?MpybDgFxzFVst{meLQmH#-all)BjZ4i#o`bd?-K&dxZho>R-oHI-&uQ;17q3#N5 zBn~5X1R$+O`(nT&$YE_XlMsA8bG%5LV)YGpTEXOBuyVY3IRtZ^YW5A9McZ*Fa z%ZS2r{^5D{97S$Xb=!JBe2?)c>zq{if+~#{RN#A?7inAqa;_e{ZMut41EYMwhXq=q zJSMg+W-B)avpsRt>8Mze($PYv;iF#QAW z7S8!z4L4*319{K5A&T2? zGsivRBc=;VD|I@d2>cdPi_r`3XGuAVlZBzQfK+QpZ_@v;PX9Tfb9n8WfnmL)OUKgj)B?SbdlVM@_xsm>NC3!dPNJTG#f0FHtKHw>N2 zFKiRwi{iw14bh};_9@dTpJ8VWk!=0m&Are~wc3D)i6lOm)L50$v8Fzhewe_T!x?0| zx9Xf$(CvD`ClW4Hsx z0d?^#GS|4+6j;Nh{4>j+#UH+%KCkI0=1fiCjXUP*@0ydzGI#dmq$i!l9*Mcy`K;v* zkNNl!M8Cm;s!)~bf2{93Na|sF<^=wNB0r^~oE2okq56%lW!?=y1!s`pIBNX#9hLc9 z=3I2WiraS6`^?PNyE|Nz7((5|9K%e7N9i>xQH|03`~@R*J*E+_l$Lq;Qk=}d{)yiC ztHyDn0BHyAXl(R-?>%p{cfRXqB1helum~-#+W)<*zo5H{dxS2iM{Aq=L6;lb`1Uac z_ht^Kv$sq`n1lEt-EkFpfiK`ow-fpkO(m?;r9YI2@A{MV$su`ARZ@)Al|yf<1+Dcr zF%yg~HNt!m=|ShE@{KBG-0aKVR4%oo8avd_?@{Enrp~3&4)^EkQlpYn34S}5Zr^dv zTlLP<9?O2ex3Z%nXo3-j4`QRO#4;;=aUg-s(BGA^&7~3yn= z(CI%sT1m{JMOMb;O6;6A48+-K+BrI#W--Q9G=+ek-REu6);I}`4GT%D$#@f$8vJ3U zh0&_HUsANmOEy6caW*krn5}Rfku-$jKlR5yLuh8q%#3==cd@^G=jPgW;e-}m31wm2 z#79+_DM8kx+nM*&!<4?+8+A>fxcR|^v@igq#gYTyD#XJ|?EO)Jkw_upU{%x#86>Ao zim&%M={O(EKA~nzY-sFit*lhsq51tipcA3|gv*jx4@l)s2ilum(?&oX3)jz9pwPYc zIod}|Rsl(IOWy5!2#kR)JSBxRRCvaeS;rqh4FE7jIdbL5ExH_KcI$Ikq%`V0Q`Sso zH;F0gA+zv(S`3{fAUCrC?H&f7rBER&+RJdHoaiR!_4xJdU4sk}^_VkZ;y4NQMY(*f zN9m;hR%KWa3=x~HR4i&(%!R>!W<&oL+c3e$a(YT-xZV0PHmpYA_VB-0?I<&)rH_u{+&-V^P{_uv zg>uZTCHBNHPdPF8;f-2Bf z`4-&(j5C!>hd28F$J*ZJTw{g7eb@WgVkI^Q#@uS2?3d*5@YHNs z2_}UZFP4;qyI;W7Uh_YIv6z}&`BsNRL3U+YJ~p*z*J`UJSxh!njLV_0@P~5DCw~Wi z_D{%l>}2Kn-B$0{ur|MZO^#e`1|P4Z7tUFvOVCT!L=;6UPjmb_v17XD4sO|B!TXD8 z)Yl%0F8tHRecBD-Bz}*`mLA^QP32EWeU^_koy}Re5BO~xQ|R@c@K%jEs%1L{G}4^u z2IW5~u%s{1O7i~T*jX1CY zOHcll*W=|6k_#pA>vYFnPm#n4^la2por;mh3K(xZ?jt2AyxG`6bt&hsZ|fiy@X5Jj z^PL!K+2~~To_(YV#4H?M>+H=t_N>VBvJ9}SmD26|Y3MQ>$p4y3@|5+%Z12i~QQrVK zX9QzlpBwf-p&>k3<18@xWbyji=@=P7<$HDZvthE+FK_eY1HU0|!eMfiZ5ZI__;>9A za!~M}c1ZYu&FIJ+Z&OExR@%_aUMABftPDY}!IQzxDm3yjE_}0*$JSmKah;A>LOn-u zhx?a_z}Up)J@|-JnydbFBZ=;{wu+?LZD+{niT`o|n(-FLPAQ%rRvqbY;2*X3GaK|N zT@Ku|$3WSX@3p?~V(W*u;?MOUpzDP}IRGih&g!z>q_d4vkiyTy=bVBql9ov{E7hRm zr*SI5Wiwr*27`>W6+%pDB_X5l5~{_N|DL*>Udfci$=JP&=FP^WmiqZHbro)@jrB7_ z6n}aFj3+?1t|9*=GK?a%(#BpcJMH<)`8^SG%#@Mg#%&wvIf4w?NKp#Ga81Vs=C`_( zdk@u=K-QzJ4b2&2MO=s3n|GZP;~EqZu9P8hF^^=fMGpb~MRR@6FJ?S2#Jhu{wzf8H zG=Pwfk+vmk6_r64F=)}}$blie1*^!-=Z71<6)f?J5Z!MBK*#ax_#r4lWP9}^JnUx88F3wPsD~-Ma}Xx@Xz#UeR_zkfU#T-K7}d%Pf@kDAEaQ#3W)i{RAakNUss=yVs4#DBNf}o z8}^MFQ+o)Y2o!CbgF)rU)Z?p283P{pw8S;LhqO^8tL*WFC}lp&3%43#Ongx zW7i-+f(v-TcGuf**p$)B zzrFN^N=l7rxszwNjZ-nx;fBTIOymv*MYXw%x>EZaifr9kPPgAElRky8eZ6pLK^EZ} zOK>l(51Gzro_sT>Bie1tC7t>=a{6( zYAD!An`$@;8MhU_D=!Ywh(f2?4WBf@6@HLqiH-xZ5?x?m!vc50d8xh${|jw{uV}4~ zkfHnPkI8(foGQTA^4O4JST}go*18&Hy$WJhR;cY79sDp)GQ!p}l`LaZdO5V3jSD#t z6b|jwlNtlIWhv}_YRdGOju(_b?~tiw(Sk9dg-RgpVUXj~HnrG1??_y&n_AwJ;TB*l zOx85VV^Ewn#f-lnEr1akD_dFdzm#e~SMAqDXEhNc>UEn;u_Yqj{wucTxxU?SE&{vC zU$Ke%e)*(y&QVk_6^Dri8=ty@UWX?)*E*$ziYIwFT}Xyw2PI}rb1M~(Y%!p)TsJ%x z0c1Bi>}%0V$4ZsdP)R=FgT2Z<4k|ekslGO`=wlSJ4=F_t3nMNNe8#@oHU7;+so$oyZ;CfZz@13sx||{MwLe(+a0mvLQP(Z#8*admjP50W zDzvVNbnUZ7K@8K?wwl9RZClxJSI$J~a;zG6>%cCOs?kYxK_pdl7jnrdJ;oCTc<-!J z^Ex;Uqb4@SA2RfA#9&bUmdh6^wx>UiDZt2GXjaVGdt~QlZxw0T$TfoKsUyGWkoZqA zN^794rfz)YGun**!`NGP#no+FqlE+y!QI`RghGP57Vhru1b3In4!&NbYY}?1FYa3u5SlTp z7ow-!DO<^LVxf%Z=5@G8(3Cx8k{MGNmd-ywjmScs!kD=$VR`<4SLjAsYm^56LSL4T zfXYliI>JER^%el-OLBe^qXZAYKI_N?+r}@f;yb}2Wu&Qc5O{U1uawm+k_+#Uu!Gc7 zEKc53ATx3u2V$yH@9QK%j1$tZ4_CM$iW^u`)9tR&V1 zlL(lr+^!{Y5|+a_rMf5i_hi5|r53<8YP&_7(&Y z!mS#Mo8#FbMtv(lH0^F$zdcJa)xx$SZtNsQwVq}G8q)=uFg;}cMeh&?0HA!QRln?D z?eLMr8UoOZwXDR7+y!b^or!{}c{EKU2BY)m`gM^(@9l zi%x^^$Uj8HicGJM{^l6-p-|``#`halBKWsd|36*sP=8&6>K8yi`qXPL8z9T<=0O#s z;pAS&>S&aE0YK^lB+ASwX#)kk$w#>w31daJ%J@Q&Nz_|-ny~l^!b)O^T&*d(*P3Q0 zRg^dNr!2Y^zMNKWS0H)4D%P3ct64^Xt;%!goblf>POL4}u%FQd(3LCIc7GImlK?*c zVWycn{up|_>>Y$*9q~KQ_$VCM50{q>w#qq5ttew!Llxje8&6}$8@9tcXs9*jB#3Ra zjBN?P#W8JtYti?=cW8L0S1R}!TNN)GDr%ZW)f01$~EzARRDL)-471szehH( z=1hw4;;)(b`ES2z+ZVd+J@dx(#nWn>eG>xRcEvCk;4~tkzgtVMb}hk1m-*f z(2`Q6gz@dJMGzHd{e0|)MuJgF9e_cn-A}aERBOx4`VAh+Tp=+j{{rM0|HRW6 zk@Gb(oig>!CzjslbvMhjvmIOgC~xLx|3H+GkL%^_-+0XvB1{y)7tb@NB@uF9j zoml+Zl*l7sbOB|NS+95GH2)u(!mh9m=m_IVmr;jO;9WNG+re8rrs*dXf4?;@Z7WA%u-5B2I>rdZ3cc zh+;cAjqTY&_nI*)^Xr&d5oVLB!^rF6>7rTj{0EIMua#6fIT z3@;D)yF3k}26>TD@et^SJdWAXW5Vo$wdv~ttWwMvs-c$k@ngPnvk>4w?v3R)q%xDB z4+u!l@9*h>N8EW|>%`0gJSr$RLjL32`!XUWw9M4rq~;0E`F3$-7Qg8+)ygXM-dlrv za$@eB8*K4l$ywOY?__U!Zvg@D=q%${%rKT3goPs#6`H!JT~_<&+?NEoPgkUEj43xJDXCmmQ+$N=UJvDehwWW&#XyQt)5%NQ2Yeo zzR>N{5-AK*eV6F;8QuEi#N?+cD_IKp;emd`2l1hXW^)nQ=HxOp&bB9Z zXsl3JJhTcaKq73U;*3gg;Mb2BsAlv8iiD{Y*grZp4>ta8+Xw1Oep$)L(*fEm?S5*z zto&8Q+CM&VL_4H8=jFt#XUD(7m;iaxE*Iy(*aqwSC)`3aLLR_R{&kQUA8XAWY9hD) zQG)+_QaIPr2f^U<=tjQ-r!slbk(|NBMD9+0rA$XZ85#gc#W(@fa)E$vh~ZapCsru# zjfqVwvfG2qdg6GS2EUkX`>|g%Am1z?0$cV%Z7Nb_{fdXjU&V|>EX^&a6&4O|m>06_ zQW5mQ(P13D%o%=<=|QYAEFLE%j1bl}^5ne=J`4pFC={(HvPlnd`Cb;ko>lPI2=y~^ z2xn6eCnPuS6`}G_dIf9W8Liedsl@hsq=#`ZXHT2fWqgJ-nj9L~=InkGg)}#eg0aZq zzHZx;_$>0XX%5vB>7#`DjTqhdOPsE6(RH_Lhzz)pSb#1L=M|8PnESq}|s z=}L!U_2?rZ!x+Kaqu@Kah#`19`mnr*;8hAj!POH%tsAO38_MZaG1yhv02SlfdUYkV z&KQF4$qvka?HBNB3e|^OmVLSAN@|?*Ft;ju)vLUeReS5nE6T9a4|~1=);hz8iFp@i z39xHhr)agOeT?Z;3(jYQtfO|z zTJW~@__&rg;|$X0X&Vo7&n9{OpL35!3S1WbAt&TwkZb$tDVJK$P>`7NKw3lyW*_@P zSvi2U85tInYG)vxYVU+Nv-Y~uTMzTsX%>UwPXH3Gmbx{E5|qbjZttz{;z$B9L!tlfz(1spvR5xPvNG!&PKaJD-BJkAE7m!?q0 zQf^(WwBFs(b!UHL_hKHlYD}EPko`L-rjqOryHD8LVJc<-L9Gxp)Bx?bm2uyg3$(D3 zG(#XZAffmsVwnc-`oB?ntt&R*rF%C=V+S~fRmEYFS7+1J`qGR_YkDVtK6sbd{Y{NfbLkr_}=fvW$JdWjQGbh~FMSaRwA`du@`> z)^|Y=rA;OWVc^$1b*(K0=zZ;f zXW-8BgYjKe0AuzOHBHR4I@(z$-{C`UDf;P2vMrkl~bw+u24Xv$F z5S^?_$w0?mER6KQ#GbIqN177zMHUqRC4?*t$yuc;{d zmw1E#qWBrK_oU|Nq4m@FdA&t`m5*>Sv>&h7z62zw!A<_eZq@bLZ1Ov8xCnmwfFaVrD5tVSs%_aU*PVpOJN2UHE?35V&Sq^{Qe&(qLdJL8Vu9M1oF+EDmjK7Ejkw$G3AaoJWu2 zU^}zie?2VF8|ZJ}Lw8nMOd>A|k-uiBJK%aB%$FMrdOR;lnN$ZEqCBc7-(2$JjT`;9 z@5(WO9lcA{7VmT{f^Sce*$-qw?h7Ab{sk%o{P!OUy4P9adl#qZGs+V1kKo8Q_}YoG z{Qx?%R=W-|*aF0`#(Fy#P|-b%&Yg{$e<-Wg-t1-*lPz1%u<68RbkQK`mR(W4eBdin zB-EABqZ^m85G^{zQI=Hg&RTyf7N)@Z{zm1a3RW+ydy{-h>3zeQ$G=X_XDo>4w~VS+ z1yFn27;dA?k`mj3BgHjCEWe1RRHl)6mZ)j=)!P~nRK#g=Pl~5de4SqWu{)7%g>_m< z^8PssOFY&f`nNoOJ0S!X4;7uMiV}$=+03D?x-oj<%L;Uv*vNhYn|m@9WjidDLNo-z z_q$AU2D*)Xs(owJcqaplS9+1OU)+^XE9Fa(mlG9fVJy2Q`P@;T>n@_@tE0@9H>1Nnuy@i--4h#(*drhf(eAzj!52gS0*QbCDO&QgeV=QJ}?JXp2b zGu~t5w1)??zwNX1w>{uAVnH5yxcD@RWZfUNn{u0I6Ctmqi5Zkgr4Yz;fcEJ{L!3j$bju%BuU^W(q$%l=y-=mR}15Dor{zD?9Fzl9%iL%2&3f_p_U+q-8B ziaY=|KSY{FE#W&HhLV%mQ5Pb_ZG2z9kJ%-&J}AQ%JsVI$?<5G>i@V$()VJvH92ChL zRGjOv4>+~jzeE4xF&;^~ELMB?rmFW9i@tXs0{L_Z4Z!w?4Q3Fn<1&OrVE@UBh_}my ztB?>A#dCF_bc+7+Whxtav~Bh#*n9ers{`F1GOBl$Eq>s;C@1D1N|;{Ok!$OD{w&9J zGcAH(1<G|!L^7g2v*Q+P&EFh>_2-Cq6O!EekPS>kkQ0ABo# zhen<%F8FrfDoe$CaBr;p>5UZGdW6A!6$77?G<4%QMt@;Sr8`HpCVAAV)uF=xlH*XK zr74SFB|5+WM0;Ut4Got5myq?JNnuCN(6XQV<=r%94aK}?f?UT<3`HX$pvtj1J~kK7 zLKOj>NzL$Nahqd7cf~lQ)+y&-v;axaCOSd&_YEE^c4W9HD0m^%_a55Hh z(43VXX=Q9)fY8R8q*7NIrmAD#*4E|WIdc$yTX9_~Uy@q3b3^sj6(bIBbfha9Ia=Zm z;NxaPc4NxgGZn_@EYej{N1sKbIYz@mOYgi3(7W}8QK}_N2eAJtd#2b2 zneB6nmLR3wj33w9&4^|kC-u(--T9uso^BIDRS99OJF6zSBsBY);K@AOL=&^34ZU~en7 zal^^KE`T;~vmZtrq?B%d*Z34_8T-Z56l>S2!wd{h`Q_|SHD?FS8g+Ps$+P(2glZR(*2b-?8n3o(#A?;`!hPpmLz!H z7oy8{EF|~EdDT~>`5l=H_@_eK>RU5bSgD$_j3@XX>|?OsRhH?74Usihw?-*%;+X-o zgsJyfhyW?qq@n~fD$%<_jtWJ0#m;#kY(SGILP|Z`85$>A`QT-@0Cpg^o(LoP?7gbr z0{5y$ZX11knX7zfhrHbfork+icljCP4nHQZpmBDHb&U->qc1=K$oxwzRG3KDRLeVK zK_cyx>~9eJ#ftyurLZKmw@9KX27UGdiRQAN+oyOs*IEiRb(BEFF6`q=Yt_uwn+xK}#Wxr-OdJW~{k@a&t=pr7-=O z7Rtai9wChSYn$YK4PS)X0w?**q4pb=Vy?&`1|_nFXoBF|FP0eX9%c8>zd{!I$tdz- zc2k-7!I3cHsd!A6C6rWd@v3pa&*RcGqzP(>f}_lnNu9#-bVxz5Ffs_^d(6^_&8|>& zy)9$TRh!7Q6wvkT@k3~I%cPv#($3^`>gpoInLrImV7#!xV%16KOqFB;&Gf3E>nci& zI0l|VtKRKD7twzzB(w$kK+L6!ShYsh|0jB%-CGo8aW$Z(;npbi0#q4*O_=(KVn_C%n7isHZHKu-t<{`Dd=~>{_(9X$`KSd_QD^>f3oYIwn888||Di z=R27jEoSkEmHZCP*6JOl!?YHg0bNmy=C2sD3@ilDC#wW&!49*XHSdkC=3OpW<)e-y zeMV zfTkN7j+Vf4aNa;I41JcoAhHl3-_G(T^y^i_XH}3p>uU>S;K&si2zHt!hZJL3C90HUy5RUt_;-B+kUeK8 zR<&9UZ%u33joKN}GbI{e`rN%IIMD2iTWtHk&OH7i#lFGvgb&ZVG5vuK6``B)TfZo` z=+%`Fw#zwdZzyFfzu9VEDP3>)`XNp2)r(zIYY;2yolp7X&x=S2D~wi{|EE2L$(p_8 z{RjHjsPIpPHl*LB57?$URsV9A>lt6P@fL%1ZwO{~ur&Qx3Uvd(B}hCEi{-xo!PUI` z&-)V~iY7sw4lG*eMoCaSwI@ha7vN{ZR%!4=>#S2~nU>sV__FT6V^OCrGp!AZ&0@58 zctC9QFVMd6lSuWOD$Oc1T61LXJ3O$=5RgI1(=us;xs3yZM>DyJeqx-d zj6{|2l)V>-k4-2!cOSHAa&3_!s_pNbnv7eKD?5)B+lEmDkXk3rm*G9IZB&4>`{dX1 zahuZ^$&{C4HV!$T1_}tBVdA zc_mU0K!>X26NR>^8_jqYdXpF{+_G=zI8l5kw$69_k)Fe*z5@c&wD3IXJBc2pn~q3x z_ctuDNliMYSpR*dr2@f|2uGThjlIWn3|I*`oa_fk9^_F5KLxNs)){ej%TfG)zK4!v z^=6@nn{`k5iODEiq93h1iz6H!-I;4G12dmQ9E7mu5_c>)b|wUNm_wRd!~ggU|7!Ti z`b|fMla2PJ$TJ&$1r1yB244mU)n}eA*qa%|*-{%~ep|2O+Tq$h;6MJ3IpYZrG5 zGsF{(K^u>Q4X@{LtGlbXq?V^L#n_SV(ellYA1YoI;Lxc37A9^+@2cXv*_paY0m)>;GN`!?mmh>Ld*wsO(<&1IQ zexNlyV+2@(!5U3W@MG_6lKso~1HnrR9{rGA^&k4Qvw{J2;p6eL>E>a|8Kd#ZAE zR85$Tye=v2Rc6PEy@l;OnNx(se;+qtT96R_9EJB(tMZdRp$6NPR2YzwfnWXH!$Gq(v0VASpBr?VPIe2?azDJ#%2i-zleosohZ4LO5%QmS(_ko_=ji;M#*>6dl46PkniI_(ip`g)=H8tNllvfk*%6!{nT6v4YAQ z?l?gm)8UP;@wAQ@a&~CQmdQJ05*dknLLK&vdb;Jaq36=0Z(R4b|Fb{Oi*+Cp?cmhL+_&^7hsk6pN3mjYU^Edr zDiKMBhxOpp^0V(+gb=cJW5>3$Hal^g(zV#v*ZcfQ6PL~FX^usd= z0S;L6mwmaSESJAN37u|FUgl%2u@ulz9{?<8G-V$RdY}IV{QT48PWV?r;dpEM$kCN# zqO%j|CT61PMitJ?OqNDzW>AcMofyj2Jt(Rne?mp}c3COdoB6!(iY;B~iozftW%4(T z^sNMUQiLjUiraSG(J2+De4g>OeTpSaeFP`mAU00A8~ssw;{MN&UV@>*%E$=VVvq%) zXZyqJCHBnPlR|T}yo=RU*(MkQ+B7kl2NJMI+eG_EYj3#8LKmza_*XzD@ku)jpHWEU zWk23?vDEyB{a={>7R54;c$%TW>jo2CYMf@tto^5iV!u zVpW7-O&`d5PG^ML1%>ubPwtC1RpJ3L;=a;=$!U~a}dze(~gvwk@25aLfQ z9>9k-CHuxiHQ{1Vg-si7Lf(oBZm^b=Jf$&IpvW)6TQ%4lk}R#ca_x@1<9s&xYqXfi z`u2VWo271W>*CjYzeEQ2wVq0|#fkFiixB5*l+T8dl1!E3ew2b<02nlCT97=WIpAC= zmDHl|O^LH2jWTqe9MKx-i`lq7HZro{8@}NzN*1C^2Kp~31>JETw2C|t^Fl=9Tpbs? zo9&F(hp?gb{ZnMhlY{sc@Ka7_DHq2v8mRmwMW{HUYx)&{(V8tO4^>(!!@AB2iE*1c zNDMN&lSLV8P;kLnEMh2yNLq5Bk6DU$XypR1XYH4TVrm~*(O}ETAgZhBa}k)iQf+(q-vcl( zMQDn5bMcTUxiZc1Kkj4?R&XDdPelUPPvG__1SvKJibekXDXBW~DOh5Te)J@nFimmz z&J!Y;rFhxlU+{24b^J(t*Z_9-ccFDL!AA)lp!8u6ma7fPa`T2X0uajF$$X5vi=c}6 zc`4TJ3o6rG@Uok@dq_0?d=$TEm=uQP7=*z&V}jhi7mpr^@xp(A2X3RZlv&Nrs&zj1 zkUwvmI_toOnRW1cf2MAE*H>S9cUd}LGA;-;`=HSAzUlqCq{x4Mp@Gaj9yinAsDArZ$cRbwfh&Di+^k0h;Y-j@$@)?g6k z`HRdVVxTdVJybwIk-A`lhRN`66|RQ96+7&|yBq@ay@BrRZ(?J8c*b^o%B1McBxlnQ z9VqXr%Oke$%K!iwK-t+x1}u%dyDrycak-}|8u;mCZL3NCfb!MU5cv?9IxB-P(JN`YuYV`r3ROw)5nSu$g02^L4l;v9Z!Guog&6FsJ|w{sE@@dA6L>UX=mj#EBe((u zk{t(`1(7%O$XDf~G&>+6Z$=gcL~ zA_j2*)p11P(B0!{N^rr!>MBa{=F zb=p%ppHF%@a=f1^rt~8;Wn85RM?j|sxEYLMFNLBNyyD)M{YYC0zCq+pn zsw*dQ2Mh74{Owzl`M+Z8e%Bi;Upu=-Wmy`FcXaX;3nw6{k;4J^cPg7mm47T&5^tm` zUsEsn%tWFpvOb!R9QMChj{DD3p1d+aSmBhx7>+?%s&6D1ID;BQyiY+3mZwO~Tiwq-X z2O!;IBGOMap^9hzp3d47q1=wZ%yJRfh2J>e4Yg>LfcVeMCklRB>iw18Z={yUz#o~0 z=(`u;;ux+aAZ=`sD9U>|l187*oNB2;;fEF>hXjK;#+Alj4}A{K z1EXiH7ey8CTai5EjeF|r@#i$3!zwZ4_d|>x}aua7&S=Lg(HAkb;Zf2;ni}~$G?$*D7@Lg6My!p>V=XP^1E;nM^k-Q3vdbJ9^VRe^ z<%R?x{aDzyNZ45Gp9kg6DEsiZFnq3N(@mACQikbNSiQ#5fq_&d$TJq}G;iy)x#L~w zsN0ugf9Pb$MNmx&K4*^1%=@#iT;9lw#JReX(~5of_iB#|jj%O`lwHmWs&Ye$upA)Q zbR7Kr-r4(;J~zgjm6`m=se>r740$d2ditDbY%R}82eOQ~tjmel9U?X# z?X-BE@?Qo&H_NPjU&y9nd33!dm%uaR0iBVFp>00^09PapJ-5dzRj>iq7(^^|P)aSm z*qKXtV^(ft%8W$jS}yrDIwG4)EzFyrHZiG`4oKWU`BUI1hpJe{-H{TUJlfQ~g1PT4 zN@XymGH_m=aaLqsXqeh*Z^>oF@IV~?&~J^NF(PfzF7p(WqgYO%O$jDBY^ zqldg{Sbh|b4IrU`>xufnz_Hb1E6OW|7o@K;>G_ih*8Ch{?uFL_0}VmGPh3hG2rpo8 z!@;~#YV}YMRV#|ETTZ|gw9g2w`Hi(v==n@7s%1yR>RDWkNcM%uied|`?Z)O8z`agphc!$QQS!NnA8PNV9s$~Ka- zsd+gwJJu?g8fPbE$R^wt2CpO(beb#6v_b$Yz>oFL*1Yo}iun496<4=bhA@v{Y0upX zwO{${61IEPPn7eoxD%$JqsSZu&Ir(#08WZz`YHYDIwc8=*j~u;E3ujuLCHhk&=<&y zPyvz?9D*cAL1|%J0JQk@9MaDKdJ3Z{y8S@(4}(KUyj|JBT|!7KPBZhv?h2jNn-xi| zrhI-5uNBv0L15J)Q#zHdbaq-%uKsTHRn5B$<>@pBP1zZwNr1o~WD*?1LSZ@xQ*OJ-`b8~qo>IbcO}>S8CI&+*+uYZ^i#bDF&@wqD zj>1%{Vo?TqGx_#Xtd-l&UQOSW08lNMEYL;eVht4qI!+^!IH%KpB2;K7t$kzg9C1^l z2M3qaqS*aC9`rgatBYc;RYM3uIGO#55{SYDm%92p9_@r+9ma5$OY+8kkUSuzmn2h_@*AqezGo!0kyYb8z*`<#K6D zF~%^i`}Cvn~FuqqV?Mi zi6M0{*uzw{BzTdkX5@6Hq@Dk(m240Jyu(yG}Ijax~3UJq&)K=a)bW;m{&Ltp`P#oQE+tH{#_`Am1bJ?3*Lf8Ob zxuC43i;yI0_lOtcfy6%X?aQy8`=)EHRiTy~{hF7H%jNU4VJ9Xugdh;AB@G&Sy^6h7 zHqrn^omORkB24B+;hWXIFH>t!<`@n`8rLwjbNlae;+VEIfs-P59HTT-N$P4G1`wa0 z$YKPWoT|5K&#lh(?Pkq|BsvG{0y+e8!^?puJ`paXB(#%4^#2VXdi<;jJQnKLJ7d%) zlWaqNG;$+Pcm3nd#7sAUr3oN|-OK7R#~%igmmZ+#lrOrIGgvxQFvpKa!umIC=11yb ztHl~X{z~?=-KMt0T~vFIwIGVzF6;SYB4e|Qr4Sp!spNIxbGlSOUY$5&ipi7ChuUKf zEAjjC6?8?Cp$Q%^?J~aMK?RY!;s|nn#^APYmwY`k92U+m#uWHvrr}erUasEsgznz? zE_aXd#^?~K^mur)_511#S$K>owJ*clz9SQ#VxDnC&68&q-*}!j9;2ieZEJ`bWjg+# zeOIe?hrq`*c$J}N|CNMSY_Q4!T7Yb8on@#w zk&nzQUr?e+Dz&CF3Sp~4KkZICe;u~tluG8A6(yG%O;h(PcYKW@c5BP?xtkCul{McC z$t^6=P8PsoZsceL((Rw1TktKN$X5~F;W~2ok!?s;D;NLAy9|0)>-P~2{)Tom-z$o7 zUW~A?cX7JSZ18*dkYU^$d8erzHHF=nsa>;lt|HoZRaO56M<(r$`y?1omb{&&UU4qDJ*Oh@K$oq$^0tmtO>IFMoJV2 zt?4WBfYLMDkSuy?I1r0)c>->(P@JmGK<%x)DQ(PF3h>-IZ|^t1D(J?RW3 zm@2-2&|-9vc9GOIwhU|_b>k*-X`PHp;IUTOpE@1$WrcAJXaT0$u^}@_G@pf#B=*;k z(~xofRGxw9OL5Mo<_-=wr? zGzT#W))RV?bSL?sXE<(?TZAy|+ko?@gJzwAbERV~J4$6JH<00|gg&(Hw@*8w(SIB7 z#>86-DIE2_vQQJLtshk$i&g~U0zfqZCDy@K-tA$HzaWl=24(+3~Vr-P3a8lYJr}?e$ z0N-m}VO1M(Y%eYS1B}vfhjz&J;r2$j2RkpP6t;4_X{h_dN{HzPAeDre!JQ;uLias= z1}_%;D;zGy9m?dkKa~iBW1N5L=<3VO&~GFpv;lQZE_Oky?QXj6{VM+gg>~_E6F?b; z^f^}*&2AZ|8O#j5>fdN-HiD<>vKT*?C-W%11x;E{Cb$7VbA5My?k#by`D@R+RT45M zqoESPUcu53w7hr7w*4*AnE$t}zLv^^h+|=5`|3|9{b<2zM^m(HD*%QS)mg*9tPEK= zOESHb9Mu5SaL1yYMo5*`Ni^6zPQfKiCZ zX3-Fkdr_W@@&F(JP*SBmT7kaxML82XgqAixyAYGagc4z!=&Ts)-J@KJaHMumk$mI1 zp`5tpW+;lwSp(ZxRiYL^OhRAIxKBNvJekIj#&V)^e-;dguBKrSU~(%6MXd#_m1x&Kvv(sbv>fvRNwp62EuK=yO$t~R3liEZQLzNo z;%NLc#{6Yc%Mzy(=?{_oFF%b5DXp|vw>v#nPz5LR3V-;;(6JJ!eI#N>wHXp61*_e? zjWKI?uyGRu54%(kntoaE{Bsh~$QBCnlMv_hSI%#|zWtfQ85ngop@sX}%}QHgwGXrC zcxFZp7iv?1DVL&2q5&EIgWh;f!$HwYo}vaP_t_1A2>?h_rDrWza%Ht&qB9eEZKnpZ zp?qYoS3;TSy2)d%Fpp3*KxQ$20YQn1T_45Z&y&CrETP~vvf5XdoIGi}Io(>+m?~@d za)${#oDO;=`__Tw>q<QpT*)nE(3X=pt!!wnrO2N<9u z_5E^zB*xxX>XfuT@~eBB(wVWyOXP7dF4nQ6bL+7F9=^m&&;l)_`wen1 zb!USX4dm3%R>Smc-~-*~i10bs0h*$0-W(PfQ}Yc~3WXTDCI8vjIe-0SUbU!Q?6#+= z8B15+*-OZsB6$%pwswWWy}Lgj{YJDbpKe{zW^(cYhp@4bj9A1+@cCw_1qw)3m6IOf zaqD-%LNGkTQIoo9hukKlO=DNRc;TYfX^y=^A)3FHV@8|a#f#}2RkWb`$ot04+d37D zKbV86o=m>V55tl1c;CPR-Sfy)UzjRnF9oI_&dO{dv;ItDqudn}Uvk{EaF1HFX-;7< zelxYVN@Qa8eN%@zPCnxfrIC*)S$SFh;o8fbGsd1s@V4C-GWHf@w7D>pKV;yU*6_fR z_~uAvNukTuI6htZq!jEAU@lB5N#Vj*F;c7EIUx#Vl@EPCzRc|p#*?39C;n$i%}J97 z^-+@~b6?Tx|3AkYh5$lDe}|^(`)bU+V{-qSa=NE(WcibXNI#nJ9FKA!I>W?UIN8(5 ztLCEID5{mJ^*jWZ%3l8BN~Or5VUTl;_$2=A-rApq_Rwxoe#&S@R=@O-RVb*n{mg$O zHkw<4b1mZK-hd{|o1IO$tTFHFW2Uqdk11orv!4RD4^5laJgLw2TBm zzB#GZ_lj0x+a$tb4(m?J-?s8H6bf|AU|R9jMFDAUuNyF0pk3bX%TPQn(}7V zClmi{2)Atd@XaUjG)$zEv?X*Y*CGquI4s^BHduH+`cAubi5RIjzKlS6l^Mo1Hl*U? z<$>Y?Ei{g*)S{0Kencx*@49mWhM5ha8ddG+iTdZTl=uN5BR5I%I>v?S{Vy-urWO^( z^Krjbvnmm~9?Td&R(SGL!KG*tT21zW5g7BSYXLf9DJWPrNqh%$z>Jl*b=)nE{-9Ym zQ3HYlQ|;ES%TX_7&$-bG?VK_HMVi0EB?Mu(=8_*5p2V!TpL`Q?tFYr7OH5SrJEzRe zBsp5AjHxWt41Y>CAN(>C)_dPPl;{5!mxI32)RyWeoOlmr(xWnNm)&&mErNAq_hG5F zyg|`|CK2{a8OmhiEu4!`2+7)*VBqXpTzY9hb|_tGxeOomkuD(NlxE$ zukYANxiYvG`lXQDe(B~8V)J{X>}b#7%CUm~{O~D`zz+ z*0My+0=gbZd7;|FtY&>6icNNfTQfqvy6y7o2&Q;K7y4mH=av*M;xdbea^r%mf;+Fe zMe}}y(wKa8pExg%72Y5=rc5puxJ2~!CjdmPPc}81F{z)9b`zyjLZu!8_>3m&xs~ep zbxV(l2DpxTT;|V)Y{zA0q@UhYH;rjZN1mKt57CtBb0CoE``4GcYNq3^&0++tu@awY z$Ym~hA9TJWdNx@xRxV%tzj?v`+(QqB>(Vs%Z#vP@NCMP!DEQ$9V)cf??}SEvqm&mY zgZ&P*c?o8)gWVI0cnw#}6Un0&E9u{a#a~}RDRtdNkE%e%srStBR>yX=82h3NCXd~)Oo8=fJ7+_l+8Y%!a0Q7mk6b!-1 z!C5u%2s0sAj%+c_t;IB3p*e_G0K1QMv?-RDs?4Sy)qTl6+VkI9J2CzcjlX?&ZN06k ze37E6(lVPen|ha^aG15p)Gs^>hXER5xGHwv$rl1(jmnR);W_2g={Zi(x$Di6k;h3O z{NlR}$;d@0O=Cz(YJ*H=WtgSxXn0v_MbJ^53mkrdOj#Nfq(PpikSCGI%cf}O5egqJ z#;h)Uaaa3CQNRQE)AaLI9>EBtV^FXR6$x2AQfH6wKjWS<$c`1ehC`>w10a_3{OIy5 zs$%riy>G6^wV&06kuK%PITI3cG+c`xms}Lj{O@=fkSoB0l!@hFdX19VC#F1=*J=rN zR5VoB4eim66brm!(wX$2e=2k$xBfnDpXf!)+L1~0BEP4}h~hZ_J((FpZX=$As45+} zM-wKv)`V-Uze*+u!bA;qhbco*;YOukw9VcD+L;d(|iCUm-3lsJP z)JeOZR0r2a^eA;-bzuCE*6q;mR9pa-f-g+1v@I=^#&WlLA1Y5)q_L@UNWeyuXZ+`EUJ z)}o99eu{o7GorNqYStAtmz@zUD&1B8Z3#hd3k5yK9r5~)p&fkspGHfi{qO1+&TZ#m z^VdPTTca@oiji%I#mq?a&S`%hda}qLZLAVk_e=ce%g*PUn|s>7>Y0RM?Y%iq5q=R- z1`Ci!jE~qwk}jz1HEZs56fuY!0<%Y4Pq|dWf8mHme=zu7lrx{%?#S194JV3P7?Y1h zf%ho&{nPp5c!OP;WT1_eLL`i5YLi>VA3E@}ZZ3Ol?$w-u#X5OzIiNga4E>tF9SAD* zcuqxMIBOY2{&(c`Us;`F7;J0ZsApWZ0e4wX0k`~O!vbF>mfOH69{>lqJS{PnUq0VH zO!@mSFomp~`kEahoyBI!dXK>gS_WGD<-qdFq~6L#ad9{jknPA%hlfMq$)5P3H0rFZ z!~iIl+H%{dSh(V&8KWKCTTRTaeSvA5Vvx5{tM#i3EwE2pKHMx=Xj0fELsHrWL$}t* z#Md{Jtw2Ndmp}6rkEESa2sk9%kECbV`eJyWnu-TB8ZLUh`ZLkvPmEe!2D91Y_Jewc zS>8k`ghhU_T-l27E!qBvZ6(fx0$OTpJWp=_Mw2F)G{_8A(+n!cUROPqyb#|;9^4CV z(g`h*=8AHEfNP6=(Z!Qv7Bn%&W@J4at-xf+%uBd}Tz<-vTba&SLOWpp8Ig_|NJK*R zdscL0J2m$S{ISJ{1LB&NWJ`z_4yvHWPqwVY@^tHOwn7QOYbhm)e(72|m6j5dDszy+ zQ`?n2wUl=_Z{Vu#-9yhNB9|$u*ejEKyS=!$l${{^lLKeY!I$L4sYg?u7$);6vaIJ{ zUZ?*{oHEDz`^cCyPG{Wa98cmQ2HhsGh|B>PS!K6!`>{?e^4*eIYJ<}sc!99yXxknKTG+~GyU}IQ%n&_Q|5Mho z%fK*4P#zR1WY1Q0vr|p$hp5}rRy-6G0W~;5#^x?b!2i>J=+wI%*yrtuCx$i(KAzmp z<>{Trluw--``er6Xft=81o<|DW7zQn2oF8CHc`$x=r4V}Dhp}H4rbj75NU!ma}Y-S zCu68zbsHj)PQ;+cV`(X*yJc7?;-8XWv2VkSn*{~V6%$$6RgqK#hbA9|VW7ImmWR_O zh7A!ops#diSy4mTxuSVHyYv^1W$XrSHe0@uh1(zsHJ3WX8V4VjKwb_hMaY)l7G~Iw zHAOR2CaxjC=Z0i*S=7G%q~jEUH{XdhQC%rz9oOWDG8Th8vZ599pKW^@7u)s||6UON z)8#HSwq{}8Y1>FIc6g#TF;F`GMOcYS{i_<9zKQ78OPe*LoEe^;f)+n?t^OabzBxJ$uIqQAHnz>i zwr$(a#As|awrx9U8Z}8{+g4*+4d>>0zdrYS@16f=uUTu)K6{^iesIi`#&A%BKzwMw zyW;Ruq_yclG7r&P5(Awhvl~iDCC||TbldY#Tur^6Rdil5vLT%XQuRP#w}0F-99d0f zvxzIgmjb7-7?3LTlmbWmRO(-UZ3`B*e!vT#wM1yqKz=0t$J&IdUY2@v9n^>2zk9mtd$+G5 z1NQs!$^lRTMbaC~_1e082(%JrWo6bfFn9NLYv6r$!}jGZQd|%?cfSlwT4hasvoH>3wFCayM-qH;0G*h? zTK>(@Z$@LOK2|@2aXNWy(X6N%{jV13vcgVjUmK0_6ooX7ty6DJzijF+KqejL z%OgJ6TlsIu6zEae2H!vs-fllvvV~Ap9g|3<$D{_agjWjLvGzfigeN7IgXX>ipiuMy z9BtUz+YY;)_O5-40$b5?@L|;?PkZfT!INy!vWJ4uP+$5l>zu5iEuS1=Q=DkesYUhU zN^0E{*~S>)BEOVpgJ-$jABgo8jHF;x?i5CZ*TdR*mWemr`UPq@n0^|EPZ8EYT1XA0 z3b`ePH7vwIo^k_nufPcMtr6U@w$Knn)4azn)6guX#@0w^s(CSPZKCMW;L@18%Hcz% zjwV7=bB!mkWqDwPx@7HWCl2~ML>n>+7=Ekd9SP4vVBM(S_znZBGv<^gD*WjUc|=^> ztHFYfmF;sO(=FehSGq7SkRPf~`oq_EfrV1j&dhJq;T@dTi0UXnI3`G5B`J2>MI5#LPDU%!h5eg2Yfg*O>%lGRX;76yQaO|LJWZ zkB1;AW=xX_+e- z-zrM8Uzqfm#GLXU=RP6yXeV}Js^X5OMDjpiZXt&6gs+PHn}Y9ipOkrWAaDsDe$z{U z-azG~)Iz_xa6H%OcIsBjp$X@&xr8RO5#j_$JItQp?e8Dcjmfvp6T*p3Uj1`p2SQfF`08s zQu1b$2IV#@7Vyh0zZDX=tJ_hspbqbsHdtY@bt^{VV>G`ETm8S+p#$BWqXGP1`c=9z zd?tQyPo`Fq=@k(MwC66@Ie&yS?h{H+W98e{3`kq))luLyG_8T?GpnOZ1<_uizj-mx z@&^NFF(z}kA7_mNzq^T*DtD?0E`oD8k|aFX`ZEsfj9y1wMDn`co{BzhyCO2ySv+m) z(S1U8s#zBU=*1ApfWcyAcpH>`zuTDO4?vi4<#r_wR7-w$K(%a!bF zk~_9N^5Im56!-1|g@RVuxGHV?#e++;t{X>}+z1W%Z__@wxD9&<<*=8WO1mlLru^`EO%)hOFw?$* z4>POZOm@yfnWG!{%UlW>*)bRD5(r8Yma7k~t;<~#z2n5lb1pl-1puOp(K1PI9r!-G zj9qK}xW-(=6fCMaR{Z3_!Akn6;PV?UuXU zcq?a<18kQF4SHM4-poJX0gy>f@{U@?yLM~jHQY^49FG1nVnqs!6$;ave}tCBdLDd7 z8@VI(<)>2g2FUVJRH^;RMCefCx!e}Y?`cw78sEHH_JNw-u?^TKhE5eK0kz1Rc!*b4 zoKmSmj#(sb8N|gDz!pWJGelbZq87(gmQZfYZeakv(w&AVJrYe39KBze)#gw~6Ki#` zMtySb)(Hv*u~K|H2vqkTVkJ-PV&WpI3VN}PBnXt}owp45wBD5l2k16;^KnqST20M@ z5*%tgy`jq$?ou;J-hS`!;YKh5`V&3i7Iv7@*j9JlJ@OM@$Fec9+2flN-G_Xpa6DxF^LU`i2;4v*T6n`gQNcN?_EcyWnbWy$Y znN()UKxFAN7r1oQb{*+Zj(Hi^LEUS>nM{;Eab}(2)JE;IQ$7|#hQM=7a1el8k-J3r z?zY@&?RvH7`xH0P%KAH`m>Ysif~!w%9-}q4MP!9w!CHCH`bS}QD4mvC7w9HV7)T=c z@dvztsYlDJ0=*81qLMRUQV}`+G${XifKr|uKT0iKFvK1^eT2`r_hvAwGTdEb>$ziG z(Jgt;gY?LlAFnH&NP-{wbYgLh49kf8(?wnIM~-A$3@z$e#;@QRoH#Q+#hFYO!n4O& zF~i4N{&C_`G$Sc-Ciq!~vlrO_fS3@e6@yb3}n;#&B;fs5K;RLkS3R!5^99u>ycdKD%&OZoh@4I*|Q7i zeJZ0rG#K;7LP5E^`QKO8e@8j(4P^+rdHpKce=-EOukTodZ&%>LKz|gNMu%McGYsGU z*tliEoK&c}7gaTG&(dn-vp2%W&e|swYg;b7qBlA|!^{8GzD)yyL^;!Sjts?(l2)^I za?}f%O9U>D1P@fjK2s}E550z*RT{!gCiihWL8db`7g1aD^$x$W9Fa0T&~Ct8&L&5uy?A?7Sg-shzw*Rp3%mBGA^=}?TR_s+ zv&lKvHVG0H4et(cXJ_LGfZB0UX39kt`u@k0$>B>)#?Q2upTJy?VSI#H#JFPmJkDo} zoSvG-F$aUZs~1yg41=pyzch7U)>7S%_(R*$+rvG@f>EHH6#J^&M~D6CBI%zl$7(pe>bOpGqfzeIunlLq-SH3fn5X^wQuMt3hBn|TjS7ZoO%E-17MJ)d1-M)uzl{U z6#4>QO!v*kq!7|mg5oc9)djh&j2H^s=x_?kW( ztG}4g?cg+Yc9Ou~U?ek}dUk_3?45z{tpl)Aq81(p2O};TbyAKd(H-)rHR&0RpiX%0 zN>91j+uF9|tdFmh)bWpIuI#>^P&|_i@6Qi&X2~@$H++)oG}JLPI26EhLnCzch@V7J ztaXIyh45g3{LS=2a4Xazg}OpsKB*G0!RR)oYbogE`+gTMspsx&K_56HfG>59l3uEB zB0Vd($C0J+v=x)Q7qhKI-Gu@P(+0C`JU->!%c>XIB2ZD$AD6{uY12eemW@ zE4s)~Bx3M_#lT5+8wd!7gI&716qCcvZ}d5+H!>yI5tx_iG~4-PNb7}-XkV)SY~1W5(GFBjXz$$-^Sq zEGlM*U;`1nFnKK!>ajNM#Y$Zg{K%YoOKtA=!nnFcxekJSIkEK4rPtMW8NH9Q!Dl6?)sP#+?sn~M<>u-z(>i)L&XhUfyJ^A zI$i5ob66W~PsEk+P%McW_`u=}F9x9J zs66f9dk+0&v&;`LVyw+=xtTbEnQ8*=dkjb=pUtTs5nZH}p}55g#YCt9u|rO5Th+_} z?Ax;t=_s{&KnxAC*k{b&OVRQ(#@v0v(zBe~M^?A%WfPLlvNVJ#(Z&0hpz_xHborFQ z_K4W9^WV>1`FAo|wK4t@pb8~iZj;ZjBzkEox{cxAEisLkD#EjAY@@oVKSsGy;1K2i zFz_J3kF|}C!LWX5N6`_G7x72Mg97u5%{=`n9N3H_>wuhiLgYKrzu2pfp{i_J~=a={?vhK&k6#Tk8ty5Hn>uzf$4-D55 zjKL|UlE>%cq`(GMtWYZwjU<)f%O}?sDbSZl6x>=UoS|{!XT;0Eb{Gk$bMIi)MK+kn31Te>akgDh1Q*H)i;qh=W z$Y4_OY9TUa%vw5`G{tT1!#>{z;k70_7P)_wib>+2kA1Q~rcMCmnefAb)-MT}SgXrI zOn6qrS34uir*x9aWPIp-uo+jBo0#{KNl(}&hwd@U;vFu5Rgp>P=6QoAZ3ZJx} zhQ{~~g#swjir6R)n}l?)C=_~Hgtl^JG5*qS8c{}Q|)!B4a|r+Wyq z^~bAW;foH(lrvn#AX`v8${48v3RfXkgi1%K$Cr|3ad=_8&vD*6$IbJTeUQk{H>QT# zpT0kY_Fsa-kAIn25q@E0n@#GgJF=t`BBApXjc@nAO}ZsJ@$)fF)7kjkrUX6ymMG5L zb(GaClzuT2yf@8jr7JRFOM;B*IeXi}t+c568xmcj5knFmr*~Jzj>}2}26eu7bBE-Jq=y{}J!SI=dBiNZck&FyX zZj5l`&DElTmBKbuz3OFS$x43+f}&}(-Cc}ACyW_Kdj{@-lpmMoyVnYMLaTiV9f`2W zRD)b&qTS1h`XDoA7u4Mq^?0Op0GIujv0%5HTsPe(lB=cqt6^oAxgp7+mckQ9znC2kl zYKsqdXi}MQ(uCWdNM)hO+WXaTmm@KrAKI;|bxklpLT=;HQnwpz9vlSqsAUiG$|$d# zncY>=&tOK$`*I0XwkBnd<_&V0bWNw9Or1t#^3D|KZJX%AO=app53(5@^ab)P z_j4?fB2^u3vpLXV8nT>>Z$)Ss9jV}R^h?kFuWT&Uhi81K>K6ZrZHCw$pG97#9n!6a zddBmMRj-wRjGoN?lgmn5V}|76V(q};OEcW-QwIx$!WyBDcjq5%2}iQNTQYZ&NTZA7 zt)#kJ5Zxs0;Khj(;o;NyT#NdbUQB8OeB2H17x&|xPc8UX+^7oXsPASfgh>}`4Yv($ z);hYz5Ih$5RxI_3HSJixp4UMFZW$Q=3IEnJ${ImPwBMe9zF=EdXfb#Gt5Q^5Jpj$X z{h&l&L#4hDDpIo+!T#mN{k;F*yV38z8G6v!I)*@hH>lFBMDM*BQ`UDCg;&q8pk-_f zjPxcS+_fu?2ULdBOazl9hRe2d@aEEo67T48ErytI-;E)!-L1W`#Qcs@aDpZs=UtW} zNjwlgVEn{NO+^k#!VkkaXL1p}WeA$_)qO01Sx05c0xRe*oxE@v%JT2@iT~7WmH@>a z+%0q*{jHc3UbdZLk$Iejo?QaFl5PCBs!^G;D(j&%#zEqqcTfZa>b^?g{ANKlQ4O7i zmn8mix87aCq3(^b@LXuC?LW~|jM%u6R~8TDJX>D+_QD(1io>B~5>3nH$kv#rt##|; z7$0ZM4o57ciW_&oGs8Ixw_~<_IevViJX`2tP#S3TX1G62%vny0>(>u+Coky%8sWFPs{)2hnLm)^^&*}jW zY|Y<@(noW70a0eLd$fvTk$}9=lQ|qx*oq?$vF_XxFfva;_g;+Ic+@qbV;zVTdKf(; zVNjMyoU{L1L4S7&V5q;PHD>$ zA3Y3u!&vH(vhGUqaM#`tn@}yU!{h&8AqZ8bUCifDZZ-8v5M!+>wBn_ zjD;T_jDM9XL--sMf~|r1NpMs=ifTz~z)kHFIoib%Bvn;c^;U-9*+oo~NIMmQniv`w zbX0JN2Bh3YZ)*Pp-z~CJZP{a;6UET#$8coOBMlqQyr%iz z9Q`|O%dbtF<70l4&>8`nwt4OxwBSY{gzJ9Yc8MP)MUfMUFbj(ohri2b!I1ST~tNrCGnMv^VHO zYAp{e%X{|8FAja2U-V^MaboU$1&UOMW6iR#Bw^Z$bQ@j0mcgbw&J~W+GD*4PvxHq< zXp_@V`XC%kU2B7hRG@STSsD+9R|?vv{#h*R9f|lX>t6zJye9^WOYf#U?&X-`H5do1 zGnBe)XHuCOapmYyR)bk)$*0Gk@GAUaYdph`>lcvgNpLk@M$m1pudE~iGM$aUL(~;UL|Y_higF+ALRULd^>owyV@00eD;Jk z0Z@fjZ3J`z;Klks7V|CQByIrgdD_BXHB84D>-~t&T?=f*nw}}Yqy`cWyzoAeg)Etv zDVx>WD<;7cLNKMYU{8>jwWgYRr3UmOD$Z^_=G482m;eV}T(+~OGF8s^Sb$D%poe@| z3Z4j|0HS>esccbcb@_clF1AoVprNL~22D-uieZw;@GU<=5X#g>L}3PPM$%sY70!^| zAglD;`s?rw9Whg^#GB`&N~zUtwn?mnwV#_lCrblbPA&9|@Mkib`=}35l7PQ8v@f@1 zIsDEmC6u_Y~>Dp2+7m!Qz5Y~N49F1>eCra2#h8vhv|9P%U3h* z3MQU?a`&2>Q>=A)B+xb#1&&y80F(@BSP@2pYKc6FpxsDFv%O&BGK^;Ple})=dL}Nt zoSsI5v_((OS%=|5wSw(}E`bx`2(Z ze%Q#bbwW6yZf5_TbzZiO=IN1f474hzLaQ$GV~GR;4vS+ZK0n&=lXtMJJY4ImY$_Ca z@ggpAN1t({W9yjr32p%J97VwfSkJa77Qqu!%&?6QBC1HD;4c4mqoDA- zvC2$G`jY9;lO!6$Dtjn}On2h*_`2T6$Tr2;Fu5c-KkZ)GYt^QK>FDF}5e&nF)0$i8!9I428XV4)VAf@wxp6 zU^{}WAaU=anhChj`JBC*9^)LYpt50IBg5Zj!#dTt6RcYgJz8Z(D`>u=Jf(tsjDhmK zRRZ_*2LMoxA-0z&Yq#_!(-eRNWU-!?D|b)`YuDDw>20-dLDBx8so1}in#sz>J_B@} zw+6TtXZfNlT^a-}{umat9+84T%Uh|6k5eNE)UTo-ZvQ_!GYq>`ASF}RVi@#D>E^ve z)@N6E0Ey?S7}q)vbp|E0_ISOIhXA;V+NVA#x)XQY`?g85hPIzUsBe51ISX|2L(g(k z-Y?uqte?NpqtXxlUJs$ejnj$@Cc=oKi`pWi+x-4xz_7cZ-u=H|+rO2KHL&v`4b7|C z28jVtBMzQ=2?5k{8Fq2G-@yR@WKp#!X-N$%Xv8N0(vXz*a;A8DkemL714Jj<$Y1QLN>EY2N4Ri@{ zYt#)A=jq3e9YP~hni4NShrL?etBPm@n7>zPz;WSXpI99uqI64@hKY{S9sk|O`l){A za~#jK-y&CEUtO2y0aop%MoxyRuKJ&Sy>D=ps^&4OPo(WlTxv9z?}b9x<Q;bC zQdBGcy&u(8ToL)DBY#*h^MR^vtwW#4`DLICsYU3>LO;+bIh77}(F5#r{H!B#mDmz{ zZy3D`x}0rxEFQ{=qdvbZwcmYP{XoO+0up&!$0(Y`GxB6x)w)s~in z9@V)X*RZI2%LWZr9)7b16Exwb)S7+OHJGn*JWpYD3Qlyu)~(kK z|M|-wA|u~_^XZ3tQ=t4<)xZCT)b-cZ=6~KF{?^cyiILI(-necVZ4tRtbJUxm(=NVC zf*VO)Icrwzo{`eGND7f-oT%Qg3bsz^rr;j}3cZ0QgFFvE(jfABbbiuJrz`f60S_5@ zz0lJ&5FFW9aoh#l^}UL%i=m??d=;M%y@}4x)4qe|$*f+f6YC@>*SInBu!?#|B(k8` zN;Yi@%sGtkDf#&?C}3k)E}^}D0__QDn+{8a^Hz||yxJ0Ma|0JHLe>@|!fmq-n!TXR zBgcuPXsm^Q_LzqI^n7*ts`a5riiuP$^OTJo%Hk}Xw0{Um`70k1P@0{F9yYoIE}e~O zPR>M5p1XcwEHRIcNH|$)j>qqb`XqVKz^BB6_8ZswYyc(aHq;`Sk@HSp6NFc85O`b~ z)FLmtoAPdOwZId`7~*hPkTCnc-AEr61T4IxoDKn(2A9X&{KN`F{SEbuFPdBmdbjN? z!X=h!iWG+|4`Did>Ri;+N93A=|I80qCwT|F57ELvhGwK8EjT+vRYA-{H&jr2obqX* z#p=H~XhIOg;^jA{l8TsJM!!t?f2iQ#51PM~1_*rgWL}=(cdw&HfG&H`t}|{_HPPLv zh00V)=yM7hg{pN)UObsG?j|=Y?fOeca47prG1F25!e88k%jesXn5<^*2 zQo<#n+ex{-xzjV7GK7VLYwRO)=Eon&er99uB9g>F>oQ|AE4;Zi{4RObf;1LVl`bm+ zS5?u(*P#BkU}SdV{p%XMAkFr%Q|(tpDqYmdj%~$L2J>mPLYRJrcKTKMFKb2hP+AF7 zD4@sjj(E6|8Nu#yA>ofXs!N(t{(75qaNR7fb(ZK-p57jgQ8RVX4wx%slj-O5Xk9JdOMR#m47%3dyAp_F#FMczcVg$Ag9EmK;N~O zySv}JmB4g2)v4rRIh!i3b!tf+tPyS@2x)BeTF5cz(~z72-D`(~^vg}FDcQsJx^50( zTq~?CwqB6PSQxl1j4#(44y;^Qn4^(<0Qdr58JM)#@4!_wr1TKetAvtA>v45WXOq#u zr4@<`?Lu-xW?j!X^y%(ub+{MXI*~qt-&8O7*G{8Rg!Pu-gHu2_j}Wj`hBM~q58AIh zzOTs!Ub&rkKDw_^jH}~LGk%$=9HEw2a|>p+(c+nu5DyQ!4CUfhL7;fYkQ{Ja*Z%w! zZ3)A1XOKqXpi*48PF(f$wvC;;PMSS@3YV+tW|QKaZa%tm!td$cf1Bg$<$Q_k3x$j= z-3AzUK!_z62EZ3EL>5v;-z-abDx&L_nTMC>-=ti=LkmhcK&XZuK`76%V8m{1wSwad zOUO`v5^4R|( z$KkdJkT2#kqz~>Xv|?xPQ$Kb=OI6I`olC zV^?Cy)AA44t0s7XI{QU;cuEG}tZ;f*er>5K{-pz~(0B}V+*246#>5OCAG7YOoOJXT! zX0B+(z+VM5JTmQ1{_2ffPYmbr%S5i0apFjEg~Px!#aRA|sD!RR_$!Ps=WuQ&>0|{v z`UmqQ=uc2qD_;rmwK)8d9~j5}&)W#3@&@+Apm}i&DX(2N&2MNIwM0K(tFD!azM)<5 zF{15CMP!p$`&mejrnG41rLcTz{WV-y^Sm#Z#ls;trkwPJv2(KX!KRnefY z&=JM+W#^r|Ab{Y@%$a1SgJ3JoDayXZkCPdGU0L~jVzBP! z$F+8Jb}5_wGB>4E)s8(Uylo=Ht;isYj6DIrU!qFzUHLus7T$QfE$of= zpF@t7ft%}ZA9~>1JSHWm)`#=frw7lIy|*#4NUs?2tF@zQfOjD&tdcLxvX^ztE#76G z2!gUQ_I#akS=DD=KJjvG>+GLLHO{SEM?N>zX)#X4^19S<+Qi+|8#WK#-sx7bwtVE| zLq|*{7s6+N35ZJpsO9U#-)BMwV748|R=52UumwjG6GOAt#`&4TK5v}b)MOnq^!yYa zCJdJ($UXS%>pOq_Rzo?o@a6vg>e5-1A@`3JR=IvPH&U_?pR72GR65(2R%R2B#A2Ir zlZDsJ1WOX=**9(=B?K8;`0NNE>~ue>mswt7qSkNL49Up{L8Ll|FQVnQ11DM{`u(A< zgjO3Sr1P6N-|Rx_%KD=S+tU<}RnFat-o>SxY|ikKO~uB0Oq~Q74Po8=Ljj`VQ8RA_ zER|`iF2OVJ$)j);17-%)Ptwrt!!Js+&}JlDp60F_@yM4)x-5C&5T*#sLvOH4UNEQG ztva6e4%x_AId!0sxhn}4ex-{=^wX7$5{xkZwbxE|F5->`3!5XCZ6N5qUbJR;r%x zb9H6HyV|9hqTTf4l_oY14;W|?7^?kwt89lANyl;y4vtB!Bb6-3XuZ78dPm-is~ zhTY4?hsrDq&?c_bmxg#d=SP^y$2TKzQ$X+xl;S)XTn@D>Kb!ahb8HleOhj|h zeh8}=gT?!U3+U8K?k7E_366rMS$6RKz%OJ4X3c7s&0iu|JRt9V5T@hRnt-`|f4M>~ z=xy65?3;$CT3+kg&NXBJ#5yaYsmXT4*U)Ji;oaK3?r$m#tjw9+`n$^p2D0xGo^L8j z{Zt%AGDoOL-y5)|m!7T3`(!)H6NeVW2D51lq06|5x|ZiB&70KH7X11|M|v=D`0_l{ zJRLX|G9UGl#3?O%jF5v1-l`YRsloYpX6tA76r$I7&YTW-Fov7D_J(rRWlhW{(gKP9 zY@5^Ez$xAhMxcvroK&HDP=EP3)>`FH#5s@IkvPD%E`PBwbEai4=uPnY>iLgc{a;YY zU%1?msSxaT@>AwIh3Am`6lKaAcPL%Bnm`r5`CJzkX;gq3a!9d z-gCtCvtSp5)Y!q|Fdz)tiVl(Pda7>vb;eo=+$6ePs~q>N@bo|B=#)`)sCw*Ut5U1q z{*GKZYk3--8x@3PpP81iC}Q=olkJVllB!B_Qhab!3|B-*&~?Cz+Zyl@Qzu2~ElG;C z9G1p6q>>ufWwGs@-+O&H2{oON9Rq1M-Kb>w8g}A7Z{_fm$}>8%=>7P*K>>@}dDHG0 z#QAyQ*$YzriMllF2NfZ-cF7xGyBGgw%IY&oG%VM7H=px%+G^7u&rp1AO$-|_?xyk^ z1~f3L>~|rlN-vP5;+ovYFwU59e3geXWBk#pBP`@ed1X`EOJs1eMCjJ3E7k{#Bv8Tn zm~3G+>C=9XY)}v&-Zfr|mFHn?ZGU^IE zz2IEor3Gr8XFmk`3C+}8eeq*g*r#=JHH>#OF*S(*=)b<6Vljlc3M+nbC-Oflt zm7QQ<8LuJnz%L<|0p4yWI*!HiX+HAHoJzjRo#IUykOEa$g-7APBm zgNY>;CV*=}OqSheJMe0~cq>jJTL#;;`1^T48OZ%SYVEsWCB1bbd%B7tSi2I}N$dR8 zrUZ4Tqn(sNy$^cY6TiJ@3v`AHtKM52l5@kXl7VkUMw)9Hy8-vXS`6`|MwJPMf?$Hu z)c7a-@t>3OaWmv{k=E=3RG-76f%@4dpzm`#$6>>95fApkvD)ow6lnmK$m;EK9mtzg zp;4#>4zZMfL3zYo(*g%47niAYkGc|>u2AV85Xt{7q5rX1Q(G5c%7-+deL3la21L!M zdTOP7nBY-6Ji;o01Hfja(N(R$>XVrKKcxItxNsHi0I#%Q3M)2F(D(xH+abxk9z!Q%ShPI(0G(9 zdrx06lwtg0rFNZU4i{LUO0{CfZ=bQx`WjZvod}(&94T_#kNLM|H>N0EDL0jjN?G>Z zC!_VDNK+$IXYOjGRvM^P_Mrno(-TkF_vn()gGR_A@IrDInhqtZ%81Ew`2b=tENNl{ z#LuGLNJ#nQJW;fiL@+L{MOtsr@S>zY`_or8v?FQHTO+q*9xRAK59+K<)0eMW$UAge zc+n!S41%C5a;yZXt7-9wVh9nGHh&$^jf8+F1R)p~U zRj5mC#`dRLkQ6%}pY+@n$c2tfJbBcgFm+NM<;~o*Vk4-Ma1p`{KRH5;p-zeJiKDEp ztI>h;<$c_(&C5#OzhZh5O3Yt=d=j;K9b8?7WL0 z-8^06Yc1nr`@phE_>-FNnXl$)DO!xVCpyf?g1F*W8#0@WAlx$j_A?Pjy{=|KZ!V1D zVrNfTeb`@*>n)6y8@PW(jmo2NIFB9~HinIvos-^ti$k1vPTt+P7+68S{sBe*$gOKl zg_a+}AtNIj9vUjkDH=z4LN>f;LsX+B+%7NZw2DVPyFCRuC%scsn9ArhMcn^SWG3D2 zr~wjXGz(5zrQ~Z>0iF28#DwcwvHW5C?E4M7OWi-5{W}iXmr42nG89P26$+XgPc43_ zpj}vM_Led_PdgLtL1HQn5HRP+>mqRnid4R6;NI@_VKH?Tt2nfm3%k|tV zCUNs7vDeO`(XwZ!x&TleochRg~sMw>S0z+iSu?o2Tik+4x`viJ@QLfGU zkqC=j|FXBwN2>HmKbo!WWpDlLW9L)&cX8S~!M!mPiesQ(lErEqBrrDN;4BKM)f$L* zD))eh48{%k5=kvV$YsDr7j)2{O7C=YZM>-iaH#mZbd zmdqZNsT^Gx=Wx{PR}qmW5UDw} zVHTT5B82p@iD<%KCDDx7m?nyFo4&ZH-gXotUIx7pQp^=7iU!>E&LgAm+BY2f>!&A}u{p1G*s=6EtkR?u?FU^#V22UOH+q~QCVQ%WD zIIH^ZzUmYs(VVgK3-VLr!epSw7&PwqEUJD>eX=ydz8$73iG-V*DvO~hsq*UL%lp}a z@5%6s@^dWz=0kQgN;OpAi-%gk})ozA8m*O6_{&oTX_&>lhR zm*+JD53bS^qh=;D`yb6`v-cqooH*R5+ZKE zJW-0F7S|hJ*`1ChOhf0D%sTdkiS~Pp<|C7*GGg*3Rp^>W*{L7B^mpi~{GQ1y4M+B^ zcoV-V_Lc83A5lrx~%Q~HfoMGGLwJ0cef4ZYLQi?X{Y*;dtaimw4BEu zn+$BKmC*Ug3i+kiA)U}M*`D3`Aa$0ijOi@PSOO~`eJ6S-Gqf`ZQXz+qN2pQ=3V}NF z$saY@PDCeGgmq=(=?Nb2NE(IgBI)G3qQ6FhNIyIOCcX*M?^MhlK9bmz!7R4b+uibSX!8ZsRM0f7B!#i^00rkK*qY zf<|b%yeXd(QhLyjT}D#na~2iG~9GL9Z}P=ftP? zhCI`J+?`{7E%!bWwqyEvyjbt;(H%mK_OfmEo<{8o5j_Q5&agLux(ox=L5ypj4b*sz zHK55o+DnEF6AT;ML={2%g9$U%c0frBHR2?+b}$~$?I&c4%avVT&y8isKOZG9^GQD8 zK;=X-rL}Fn!B#o%x%SG|!U|K>K94XlNcbe0+M|zQ3>%ZU5w+@6WrV+m7_Etl%tNeV z?_;1-`kxGegKvm!D1+fc8knz5!1vLNl|;A}L8@!p;?=sa#C$WiKW~(R8J@IO<=byq zgE93K*tBQB7Loyi;mM3OuauCM+%W(f8Mu)-OO>LiJ4B`=rkgwlE_@2f#aNQY(RTE5 zDNj?extbFMn3RXXyB@fPU+IQQSY=tXZG@yN=j}P9saMFTlyegCDlXApx!wepu;8go z2$&=v7^XF>q-ov^>B~mN74r6zH^WK!%;#u+XISy#7g7Om;OrzMVm>RaQ9j&&sN9=B zw)Zc%RbJbsM2!wQ3Eb{&Rv-Jl0DXfpFy%y`K?5ejlitwTTfm7dbdL zFqvF<8=(EcX%hqJx$@`7*F(ilV?&jq-u&TEl2s0`7w4N=YSVGN2wRVi_*p9994A}; z@H)QuZ8QTfnk0Bf2<$eY``YMg+ejqyS`~065e&kfNrGBO1Ei)_Q&BDcR|);CA(lt| zb)}IHfxoKuNO+Unv26FU*}w3BOR;X`q6 zHgoFbE_vOP87XFY7T-^X3p~Gl@{;r)CQ*8;J|8u30KFp-FwwK^nw4FhE`Um`PQtxJ zaL=rmV?tqK3gR0W@AXjXhf*WvY`%tj?3H;LNW z-54?ketoBPwuB5mmk$5U)!q@b4(62UhW7qX<@`5AVUFjt8j~dYVZt5gV=V z=af4I(2u&UQ*8% zC_lZ6>K|O;TPVa5o~u09PxSU-ME8cTC&g?I0}n48z=S2$tc~+nDg~fc9@m}> zWoGQwkGopAJ*QbO9k7Rda$6+uyMWZ~YE1p8Nm4fMf+9d`olo`ma5u;+-Kh~MvXpx6I?1YZ%-o$keF)3f2_CkDpCb9?%JWQaSE z{=$p{-cP(l?3=KHs%^Xo60$M#n!CGCd&lq;DRSXN-t%rXYs)y(Eo@Z<9|!C3nW5z* zd6Av^UD$MwlMObrnYQ!+HX@;MvJ#uo*J}kA8L&vIxy(T)F=3{pO}Z9~#sHRJWB@Vv zW5MrC(h8A5IHZn^8@qSX+(c#LDE}Q-IY;KqEvCM4n%d%{p6KBiZQo)?iiyh3_?rk! zO}arF_KKegGq=nMoRVtqIw?_w$}3ee{u-_5Y>xP;wReXXGV-K3m;{txt(((F5|!nX zVjAVTuo|eW9xvE*papYFz7K0>kcwt16p&=}wseLU(IfUuWX&E}bPl9B;ZKp}<_;!pwyE#*Gq;mmq{J<)u%QNOb1`tB*I|sM zlEfx9u2SH;L|z8d;%Dg8WlD+Ue;U!>8k*JI;3mNp`XHxt5Cf~C>9eAWA-%3cYtHqq zQ!A0eAy=~?4isUBrv@lJHllwHbM%x^Y@l~$Xk0M^5;1Zz!XqGA>z*EBB z{+ip`$p8wpIdQMOds_KiV^kCksLrZRZzp93YkuO9352NR@<|qS%7-D3ATO1Y0gryq zRyg8n)?wNwn!g8Xvn{G1GBJu!k#!QyPN5*$r4#nSqf9?btD{&q=@fSN zOx8E4Os!MLA+a6ay1th0MkyyiY2oTgeV(C{oUKGtatbexB`Y_Y7;AZA?zHf`2rY_B z7!20qc&SLM>k#+^AFNli7%5RIMq&*GK$lV3i!Wb*L$(6U|AJv`pTP7#trRlIMKTJ6 zCRReR7KD+6ym$6}KSePzOv%h^4PnV-Hj4cmmTBH&IwY)@simx()4BK2KJR@M%6!7h zki^56h14v4JnxaB)=J`e{tHNQr?Yi5Kv1q%wbly%p{78R5g3H7=;&HYU)-I#j1puk zOr9O9HwJ5Iz;>sG8i~W`yVYK}^8NiAZWi;%$FH++@pAGruIsMw%>o(Bu~V5@q|nlj zUB{A_T=!Rb-qZBGMn_<1yIJ}$R9LD1>Hrz;5Hp|ih|SvSF&j_!ErSOb!tQ`WV54qJ zP{1^?7EFCYG*6bw2Or@ZiGuB2PcH^%^8l4f#41*K;^4p^ISFdRmkv@#+Ln()*OqUV zGJ-%)Y(P)+qbGPFC_8U^Lg|9lGKVexfaBprWCdd73fr4&ss-!kKlRH3_CT#Fh| z=-#(HJH+bgEgJBlt~ZXOF-!;zs6s+PP%4X+bs8G!1u~M(O~_k!DMuEXXKJSWN}wP- z38u#rVhfEKtuQs_h^j12!+EG600IDWNy>y~APfn2nPvIp{AH)+`OYEuzK{aPu~XG| zd09ftm`Z~y(OiViHPtwr6{WEb3<`erM8%y1@#^Eu#xd<|_an0J+=X1~Vci z;@QKh4JWcGGdKt8(vL_ci}+AQfr1XJ&H&ozVcobp+0niV0Q@S939Ey52B5LHp< z$v+v-YIibkkzA;@4`uRu;YVk`uY@IJIG_&nF^XEy0uurZLc6l?#D#&ipTYtwoRKzS zHpYUEEVT+vtWd9AUk}oAp2SL}Z|#kra?Or%pHafqBsA<(fMwUlMGBzT=w#Q?oRhUV zxmaQ2L&UUWl>^GcL2NL@u)rOB~*MwqQlys47MtQVvV&dbO|M2H#`iWL%mKyUQ}(2_@;H7?Ud#?o-9zrN1TU z1Y_AHle+m&3N7diAp=k)WY>l-{=_Fk97W4!YclAYFp*HA1w#3GgF`~CSlRYV~@I`;Ykvx)Ti5^TuyHQ`)>}9FyQ4S>TpFyR4i&Y=1?yMzkFX z@RcV1XRq-0l-pomYo#EF*Nckkz&44K1sb}G!vDzdW^yny&h`I4?Y&i0T-)<4+z=8p z1b26Lm*DR1?(PuW-2%a##@!)!aCi5R;Lt#D@7w2h&iTtXzUTXNd-Ox^u}9a#uDxp2 zs;W8XI{?mJTbViVKqnWuC&0JL)My;OIt~=`8_(FuZLKjCRe0EkDNQ$B;c(~H!}Zz< zDRrekr9VsReDi}Kw(^_%ZlA_i<<~yrwKQtqQm#bnOLI0dro+@^7p8(AFmQ!{svOVl zn8-?p)QV|eR{I^DU0%d<7F_hT(}>SvFI&4fce%4ksR;}=74E#(2-ackNVYS}6^f{>)wpMmqTFV2IhjsF zvmW{APNhv?O#`g&&#k5Jt3(F?r#<|_w<@CQWvcq>2`iC?&0g+ct1}S=zEMz`QMPa9 zP$d3nRCXZB#W!S2XbcqsCekSFMEYeJ1vqiCaBv&=X?7)MM22#6t=}!@m9AOLEh}b( z#-383d41!X7W}{MRVKE7o8ZtFCOgXg#PSAm&+!zdiHMIj9%3+GbbM;-Iam@tMev7x zL!gx@S4}(XVf|CuP}US+;knuVnJ}+up7JE`b_61!jq2KIkm!JFbc~uo@U|SeWc#h)9g#Y-#E>_>0UARS4I9Y$t|65k#8%e^$7R=R%iUix>}g+rFd)a+(?& zY}V&5wHDmpP29F#AF{9O|KORUVyVQi=QB|;-LFvA(SdCrY4}{}1m@ID!iwT6*+feHRWY^Y0CS*pT7I5V-JiPK;9FN7;wa}|S=Iem z2Acp+IChO;b|t=_TO{@a z|Lm2UGN{9B{`BUBCiT_y_8?WBV-qv9nNiEFmbfnvt}q|x(dHv(T#NOpWM}sd>L*9m zg1dtDS)5#(R>ex?$Ubi5h&oHr{*m$7doL$@bvgvbl?UFnIJ-e*=qrkeInY#uGA1bd zfk;tY^sf5qBvTX>$agI#D5bbe_B4rgW6VZ5zBfnI-O-f}FC+_g zDrNJe8jS>?`$UsxC$c4iX9eDKIDCr zZ<+nov_^(JbsY!$fy)8ey#-P$uLz^%#B(i&Yf@$x__3`EYCUf>I57~MP_H|dFF(QD zBGgb7pw9%hyqkVIfESMyT4<>bGgVDbno7oZDS%3%*gO%Jo8hdl_1%!SN^6)KJj_^( z?bY?BEgbLKIMbao-cle5|j!j2-a?x6;B+iE0A=|Bb z(i~_SR1|tfMQ?%Lu;)8V^%Gfgzr$J|RTtNql<1+4Z^fRQZ;+!K4w-2%DD1PS^s`X; zkw2;{ukVnFhWa|;@Lh%_%-$1w!W!zkhTN!iWjMDATzE-}7Lc#@w~gENitgwX;H+^1 zZKeX(n}#q#GX#d`5c1uf4HG5AP2G7Q{S&7to<5FngC|8;07YWcQ$oJD7I}J?CZ>j> z*!S%Pq#rr?qO22hFz+SVL?3^UZWoI0QgzQT+>BXFymsh#dhdU_#b{EM{l$sa0{=H_ z%s*@BPrbP!tE=@W4+!{vH3^aB?P0A(0KD4uZMmj$SmpzFZ<}&yE3gdG1lJK4Z3+;i_d8n_#_99-8 z2iS8g|2GEK?E0W^_bYQPS)vIDg0g&p_jf&bIOZ+MSM^ zF9@k({r@~#ZT~uEzFpwo|8^Cs)gK| z7qw`jlJY1jD~{i)Nj`9NR}Q-`f$sFO%bv(Mc^*_kOxOBZ%p9RNb+{^10iw|bQ1;2W zE~++b1`HVfjuhWk{QNBl4-GyrnVk(eClQV2Ec2$ypmA8mEx?smWltAv$+8U5$LcZG z-0H!jT%Oj^=AU`)b>u#!`mjZ_O6#QjA$5LKM^f>&O~?vFOsiRk!p0YdUZdrk*2&JJk-Rf`FZqtLcwkA@=f z-lYquw5-+~$6{C(P~D9yUP5ZAHuBx?p1?HUeDTklmd{r4zY1PZ(0e*tvqJnCAYEXhw zASoPNok=`fw*~6AbW~eM5+A7f;ngm?h6+A}?S~W2DQogKZQp(*B>-oF)9Ndj<5(Gx z@X~!;@Rjn} zG+lNn2#$`_tG#D^PcT!*Lp3+!yUfN^yv1N_W)Q?kx^4+XIXQ<20>9( zL3J-C{&Ad=GSXX3Eg^`IE32oRae&Dk%AZ-L;CU0c{N7NL&837=i#q_!xY!A&Us8tjb)k_;yuw(#D9tP0Kq_(G@obNaeJliM?*-XZu(Cc$#P1j`+X>e3ONUzT}FJ8FG$ zTyc0at8ca*$H%9`uJHC^3+ZF&Z#bfddpIh?+$nan@NsWK@WT+s#hysA5-6W5c&s!z zOp*=!yzKC)=Pl2|5Bw&>I=QZ16ywZFdi`FLa^PI?8-fTnzBu%nL}y16Dn+j% zE6#29b<>^Vh?2DoqLjKT)#$0*ZS7%^M~n7kiV6@G4w)(vzaaR8R`aU&sTH6MLuxk^ zpJ~-~2C8%hzYz>fW!oVciyV2?wGg+{rb86M38lqCg)I^2ZI8k^)(JPOn%3W*L!6$qK=Fm|b&8TAJEr+s&c8tU~ ze#h)n-z%YGalAv2G1o$!Sf|&=?V|tJKD2INY;A%$Z9p#vA~DUMI5r9_LTYFAW?(E& zN;@TyVJr`)lbIqny$s1nRZrn5!o^`^7olv{L#NpF!(-3mNTI4bB!h;cii0wO6J>Xf zi?FL?XX_O7$|!@gQZRu4%q!`x0;}?586DK(RNT6^3;(3ym$f-{2S=fHnv!%RD~@yd ze|1x>R3XE$_a|rADu9azc1cT|zU67&Z=rIQw1K@*lD^KVXgya}Eod5$m2`>x|}V6iJ2s@WX;(5i8)UR z=c+iEZSvP<4@Rpio=fQ03mjJc#y9t_-=VBxY7&G|E413d8O{*>wVBGCi_Xf<&Od`C*iu?x;(wlDz&RRVm6e*FaC5&!$H&O3UXsu918Lmd)g*!lV&`02A1jX()T+q^Ii<|pa z2#Xcyg(iBTT4jilE0xI>D>1*;|BDsX4+`?I;z_t>IdUI+Byv^OLUYNM1oxnie(`m0 zEF!e#ZV|Dx;%#`sgVXc%J%IO zoWMo#in3?2t{;Q3c(v#7T$X1Ll9zfENOAS>C{2r38~DLhE?>X~_goo(4 z$-BPqg8jm@sU7#%Bmk^1K$WFa=4F&1%vt4QlKNGxPOK8Ut?chYtW$=7G;-!+-$`(J zw3^bLgm-W>7N@}`n*G#TR>GkfqJ{-Y2;Y;A{=R8aep4Ozb8V|pb3TV4!YQ-TH#AsG z95J+i-J@^*Pb#;fwW$({;cjThzx5Yk{i8)FFvHM0fZ^QQB&`U_7Q&{Wsz3WQso{0N z-Ew-jbT!PBIeO#WIT#rs8NmAzv((vyeSY47w(bc-TSYt>E#Ej< z0^cBop<(F3vy6&Cq2z_lE_<$Ss+Cp4rDZhXS1TeFso!x0l+>VWFh(9(CI$be zqVVr==*D2%h731MKi2mZsr-1N0UyFhvYccO*@jfIZ2^+Mh2PV=8OhW>SbsAkgBt4Z zA3MbOs1#$0aqKd2Wf@_y`U^TM*Tgdaup;1AZYuF1rK1g@crN{>D*v$@G>nSC5;59b zj_9wUz&pU-u%F@@7nL5bRKlvf=VR;9>J;bEQq!6Z$BOb39N$GjLKfRd`{ zvv~YqZI*7bRYJ5?2KPZ4j=JO)SNGdMz^&)F zgKvIx4;Yo`?)cHuI;QrHT8r4u;Lpu6nNh~(UbLo0)twQaHbA-Ba2sIW|=u<~z<^CEjfqKX~boU=bB! z0_ChBRa$ac^RF|S9QI%xF_aCRnTl^&rhW@rw}(iuvB(f21$uwWESokj{=iqGW2%yA z9``Hu$@X&vJ@1oKg@hg$TE=*aJBN)YXCDqaLAm*^LyRAvwUrPR+MiOb=L(m}>HadV zCbXQw*rt16gH|0Ar^U!wJrF8^L{PTW)7Y4D?x`+4jM zRI0r(+AoPtnXaE6$bQ)pMs90$C-b+Daia>-Q;7xqa@nuQF)Ma|$`AJuXk)qgc|4Yu z$IBjnLDUIyiVL7c>9C)6!1-_fktH+WefGe~6aG<43sjjA%AB^LnMw8_Dtmi?K1CVZ z4AO@&)`~&XCCj0S?@2lCWE$jg=}M&MnkV4;4mR=zThN-pTil_Shr;4MuV#rqY&lCm zdk3G2PS|^K1j#$_6T-*BVus^KrO)SHPRJk2NGHCXH7c(-{D%+ypC~t>qpuQ$>TYmq z&j=BHh<&y5Dv4|H4rOw@X-KPseS)YldY;KTVi9WS`?QlEEMd(>4NLzBEq9IsC7no~ zxN^#edE6B**zUa{=I zFdg#96fV?Ch73%69YT|I+NMcJH&TBEM|#N6X>6a3)Y>0;MK~*}P>3z*?)&_3;aMe> zol`uj6+x2S;?|-eS6% zf$C)co9cQu_*3w0)&DTB9A}nuBGp-bw+Y-W<0W0FY388oXys(sUJ==qWl=i@J6Yx3 zfTZSYyBSSNtlcq6RQflh1m|#_Ua>>|+Kc|Xv~9Y1Oi6fW5UUr%`krYb=Q*+xSBdr^|$KI#xDYvT-Ms?1k%9OXeB!(kUY z@o*AyX$%<7<+Xrm?`htqu)pjW|Xh1Q*Y^XF;T6}M^bMs&|=hl3LHXX zV@g56GJqf{3}Pf!+4lRWoBxai|Cfh$bxc7N#z^{;o#};fP_Z?3{@>k#;C+gn?9f== zA?xkW%P=Ni{H(-njt`BJLNa%w6dpTVrP-iHl%G>CDAzje1@bhQo{7?e*-l@>d$yfU z?+*OIPlr{x5Zw1bl5SMEw>^DP7fBRF;!MKv=Cj}HPB$40%OP1x#!mwWZc!CkNq96t z?5qZZN1H6sTx9n!SXwfY=lsAam2ZibWF| zE6RGe0rO`*xiX%2;>9#v4%oTG9Ea?M2bq~=e{`U(!}lYFz_VGYEO&_@Fqndt2oqCW zaPo66*u8DNx;T6wjLs1b6c7Xru&`;dpSKI>RMX|PXf1+OV{;^8`C5TS;~|5<@C02s z)-L)&q-$uY&)AcvRvfo&BL5c96Ig&}^~4OmyjOZH z&kE9n&$3v^c?(4)@@@bx)f$kI(NKzL_*o7}!ufy9e{&(pO#=;om_)zD3G(~oO6gEj z0fj{?&AUmIjQJs=Ha;p(l8DVSIx#KY3%uYp+qKJE(HV8Pvr9c^@dhuINwfn+;JG(N zaO0+GBJ=`9^tlea`4ji_VSL*X`N(%q;0rc8Oxl_v3>hs=K!S&w00&aWo<+;T(!HEA zY)%RmJq-2ttld>Mhu^RKNWsv@pX9B=Ni7p8rur3(v zaD2E)oBFnU_i0Hz_I}51m1xx(X{i-9!7I;^_jphm+)bFouDx%DGHO_ra%k13NOx|U z>Tjqqt!Hp#2P9K({??dQGHInBb;lCZz4?_PkX&JCFsLO=bS{c=0wgcYqB6PMn5}fz zvfO}m@@u3+oQBf=UF%Fr6rBPDaTK0lj%K1GU?5Avgp+bG?d%JCo z+ZesKwR`@8{+GV1nBlCdx|hdd{h(D@_%V9$0oX~=rmK86B8^oKBHcY(E{K&XAVVg; zNcL9;Lik?~L7&O4u}0zk(yhuy7Z|di6!fqhjIxDyVmRBphUW)R0HB4S3SY0YWi3?W zTv@;HI9zz%pu?q}K0yIlo!JgXfZPM3x6iP<&lg#KVyRXF*UWjJyuw|Xi}yCA9&))h zV|!h;IUz9k zPDHuhMf9tBp+v*bJk&ceVJw6Y5|hk~Y!EPzBLhxxgza3^;|i)xRAn`sI%5Ho~?0TU|r0i0^_?_~Xd z)(~9(p}|@MIcC2eJ>ok7i#WNKa2tvgRhiIw2Bbe}CV&JQ7<(vqUGjvcl1avKO3(jT*i2%ChW1y_>#xD|@7{?bRxTYa#O|248W? zmmy2Tpcxy4Nl40;Fr--EbkdIQw-Ybc{dTm;9kj8De2xEz%(|FRqH`nwVy#I_tQj5s zF{;t0GX-p|ckrZ~O^NQ1qr(D$j=LVnQ);H)9i9N2`3$GkWzS<;S><&CjMeb#2Fp<- zf(Q}-yBgn1O+{rS;TKcH9jG^P#<%u;3F{u+!_Z7k_^SN&W4<+HRvZoo9*A{DHAd3# z;)A1Glo9&F2_(T~+aS#;LBzm*51soYYNV8jjG|LTDM8|C0a zb~)B%-eCfDPVJxthJ561jm!r#%w&w27$CwaEC2w}nnu4di%`9T3{_Vv>s6^EnnG$} z%G}`O``i&^J~TCYWLhhSX|Hmyq@uYz1fv9K;Bo_;?*aIt}srV50z9i$4hW@lNmuo5)2Q+h)^S3&);`sP*x6w@O>*)t;i{=mLHt#JUQL+R8^&HiLPP(I9%$`iBIbE zc-u$}JV}WdHUtlDeYUh!YJVZ;GH8 z_%?p;X_g%k2p^?L_D+9_)mh{Ab?&++L)*feE@9zotaZ?8GB2TLZy(x1IY>7>S>*ak z<1%SR4u09u1g1*+w#W5?+ujQ2Fo{rUI%CR5@>TzvR}SKye?0_%e$d`fA*TZx+QmY8 zBusMq;dbJ2a?$<_H8g#xuYg;_v;~EQBDgi(KN1*Z#=v3R19b|?3=GJd9c@k)E%{Mo zz5Rl=2c*un)TT--)=@=`>(f2AT4q~xP`jYRaGO%anN=Omd}xYSUG12#g`h$%dnq!?{eHqTmLJ6e28!$T73ES(BxR)BlsJ7?WKl~%6_9r!9_@0>+Rhg(M@Iw%Ka;@W;2pH01= z1%NA>VlYg3`pCP{b&&ZxT1DZRBBlJ~D^I3Iw!5~SNSBb68xbQ1MyAI34naf+s*-#0 z!_iEXzb*Rs&sP1HbZ9v@h-$VsumaCJ?)YMoZGOIru*@u{W_9 zwKbQth!2IS$Y>UiHh->MUc&O5NHaCMBBaXv_A)*o3=IA?9778A$Nq!{07Iry3?#uK z3E7pvIBS~5m1M0PQmqgt&qlhDC;`$P>y^Gshr83@_HYgpmketlW&VRyxpSmzWJFJI zJ(U-hlH{z^4N*+FZ#ng8cZ@p-v1_fiymR*j)~`bMauF0bP-Qoa;mfoY3{K<<1*!%< z+4xbAiZZ)h)o*CpMk5@}Yf;U~O(s8gyhkyI|1^*5bcqvGTz?~cVy>NXYl=uC-FI|< zl?2}QP}q=L{0%qAz4hk$Ja>??1dVU;iRG_D(cc~l+0xOSJ-|UQlFOzNuy8_xGP4tp zvL^LpVbH#bV*oJHQp`h1p(G-YYf9k)GvS$JPn)l+QqbiJ8o#do4h_$G;FItr$CZzl zi>5Hnxljq)_fm}*_t8)2L{$?M;tBXJ4p!}5_z*F2lMUuHonfCLqa+m4A)sl}n#Iiu zZlT#%DLtqm=`S)+&+OKJ7jzsJi9Sjn2XEqo$J(R3>?3oagDcMPoU2icc3~uSbjlD; z785x-odB}UdR~8GbFZNrFR^q$NMSl_kCN=p(S9$|cj#7L0T=J34%eV-(E;B$YqD zOb$2SkSL%i>0P<;#mn8}3vt#3Ns(1v;y)U+C-KbT^q^|G^We@N6APKGJ%U7NJhza~ z<0O1pHdZv+X;iga=zxa`Y#XU<{^)9JvLN`EVZNhb?qO(@Vjt42?Q0yaEqoy_ND`IOxOD?u{yQ#UGzKI)#uwc>V}YEp)gr$BG5Qq=>cC17!wgo~h7 zk=PO2Q+xaA0?k~&z|$W+gb5`+n^qMz7rZYok##~PpODBXU6BR;m|)Cv0#NW6mHM;r zTIfSh898YaKF}%s;ZVHxwCsAnxK*jnLw;YmrZmksT0`!}cZ3U($zU9p9m&L6_UgvH z+2wR5Gm@6Bm?4&tCg&^YMp+j5d|7RzZnM-?qfN$iJ zf`w83Q1FHc#Qb+g_m78ebT^Osad`|+eGNz?HxQ3Gb)_u!!TvmnR^LUcyc?@ zGl8Jdi8=G9m!F=UhU@2E60=7=TR$ zvLUW`m4D*=W|lde&uaE8aUu{X)2|46C;NCic4ibB&vh8AJ{Fe0ImgK-C0J0rvPB+% zs-`0$!g^X4@$ICBx%td*_3*Lt4s!a6JOi8J9TbYQ4>KdMIxWQHmuUk*5x$e8_(#Ro zW(U=#Mvg1|8VPx;tTC+pI78%~TLQa5p-3O5^U7PS)C{(4!|p_jV0Dt@Yt%GXT5f%r zBw;YFn6Qmesbo9K$=BclKuAA&kSdIWJ0wY0Nk|nenaynKBme3-MqAR>e=RMRfC4{ z-r)ku2VsgoMxVF&M4HS48Dg$<6gScWP2hh2+A$QmIiX_AVWr$s4+JkQ@~&(P`!Yx~?+N6I{hhA$BnZN|Wlu7(x{14+bchk}xxZ~Bl@6lIZT3(sF&{s+ldX};Xk-l?p>=H$s!*MY z$zU-Kx9N33b^YoY5FM5vX{4S!7(X@H^zev2M&x)D-ak*9>J+D5-Z} zq{DpGdiSr(4+S*Ijwp?*M6v<&I;BiLssBKUt|v z7ELwhToJ@sKds3nqQ^wTM%Q4dBzjC`~Xv;g7g#1~TW?B`lBg6>*B@CP(Ws;P#`4(n(?ih!vRzjT{%D zxU0=APT@7xj-Rk?;bq(`Qw$buvhy~fHlicLO)<{0K!wi2IBsKGNoh*Xv6aNw6i!9T z^MCI{zm2srfB$tJ@}0tw?2Y~N7mU@KH>`%qoh3b;1{j+&AcrY&D^O=_qb#0B;I4n; zeSmRK);MczkF@JT<}t4HYC-;W8c(mxae6DhHbs@Ib$P0eQbZ7C%9FnOigIRY+RI|D zyxY3X)*5xSoIozp+?VJwn!L%im`YWZYty>y6H6K2*Ig@SU25Y~iOnNphnbZ{KIGQGd$XC{Z>-Q9>nFg+GoG z>@c&-WX_oH`tbnxU^dBd^;zX)3h5;Acp*)8T1m^wYM;u=T7RSSD$rY{Zrzta@JVGi z6BHDJlbVKxhLNSEr6cP}Wz|yLWMDnIOQxKL>T53q9ldNR^lFBe{tgfw9FiO=@&5fz z|0n<>P12zj<473=6AG=8GBHKkL?k_KO6yfaBd|ZHvT|2E#kM7j3q$^x1tsjw1YwAj z7fkw@6iy$ag-I$77Cm5%KQhBlZNj^1H4_vM9p=txA!&>Q9_cM$oqYv733IMY!h66`BIG2Hh+NM27yPGGH z!djqvAoDTD4BhpMF1ZF(CJ71(7Ekz*DF*?atFFjZk4TqoyC|+^)>M~f={1z6yBilytla{3TX;@}}b{2rq&kXCzb0}RZh)sSTVUtr{HaB0l{L=F92^7*&w^XU=*uz_5_0RSIK001b+ bw-|B>`N%Jc0iMU>h14 diff --git a/backend/tests/transTest.php b/backend/tests/transTest.php deleted file mode 100644 index edf04354c..000000000 --- a/backend/tests/transTest.php +++ /dev/null @@ -1,143 +0,0 @@ -\n"); -PEAR::setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); -$gb = new GreenBox(); -$tr = new Transport($gb); -$ls = new LocStor(); -@unlink($CC_CONFIG['transDir']."/activity.log"); -@unlink($CC_CONFIG['transDir']."/debug.log"); -$tr->_cleanUp(); - -$gunid = 'a23456789abcdefb'; -$mediaFile = '../tests/ex1.mp3'; -$mdataFile = '../tests/mdata1.xml'; - -// Test remote search -$result = $tr->remoteSearch(""); -if (PEAR::isError($result)) { - echo $result->message."\n"; -} else { - var_dump($result); -} - -// ========== STORE ========== - -echo"# Store: "; -//$parid = $gb->_getHomeDirIdFromSess($sessid); -$values = array( - "filename" => "xx1.mp3", - "filepath" => $mediaFile, - "metadata" => $mdataFile, - "gunid" => $gunid, - "filetype" => "audioclip" -); -$storedFile = StoredFile::Insert($values); -if (PEAR::isError($storedFile)) { - if ($storedFile->getCode()!=GBERR_GUNID) { - echo "ERROR: ".$storedFile->getMessage()."\n"; - exit(1); - } -} -$oid = $storedFile->getId(); -$comm = "ls -l ".$CC_CONFIG['storageDir']."/a23"; echo `$comm`; -echo "$oid\n"; - -// ========== DELETE FROM HUB ========== -echo"# loginToArchive: "; -$r = $tr->loginToArchive(); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; exit(1); } -echo "{$r['sessid']}\n"; -$asessid = $r['sessid']; -echo"# deleteAudioClip on Hub: "; -$r = $tr->xmlrpcCall( - 'archive.deleteAudioClip', - array( - 'sessid' => $asessid, - 'gunid' => $gunid, - 'forced' => TRUE, - ) -); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; if($r->getCode()!=800+GBERR_FILENEX) exit(1); } -else{ echo " {$r['status']}\n"; } -echo"# logoutFromArchive: "; -$r = $tr->logoutFromArchive($asessid); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; exit(1); } -var_export($r); echo"\n"; - - -// ========== UPLOAD ========== -echo "# UPLOAD test:\n"; -echo"# uploadAudioClip2Hub: "; -$r = $gb->upload2Hub($gunid); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); } -var_export($r); echo"\n"; -$trtok = $r; - -echo"# logout: "; $r = Alib::Logout($sessid); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); } -echo "$r\n"; -#$trtok='280a6f1c18389620'; - -for($state='', $nu=1; ($state!='closed' && $state!='failed' && $nu<=12); $nu++, sleep(2)){ - echo"# getTransportInfo: "; $r = $gb->getTransportInfo($trtok); - if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); } - $state = $r['state']; - echo "# state=$state, title={$r['title']}\n"; -} -if($state=='failed') exit(1); - -// === DELETE LOCAL === -echo "# Login: ".($sessid = Alib::Login('root', 'q'))."\n"; -echo "# Delete: "; $r = $ls->deleteAudioClip($sessid, $gunid, TRUE); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()."\n"; - exit(1); -} -echo "$r\n"; -echo "# logout: "; $r = Alib::Logout($sessid); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()."\n"; - exit(1); -} -echo "$r\n"; -$comm = "ls -l ".$CC_CONFIG['storageDir']."/a23"; -echo `$comm`; - -// === DOWNLOAD === -echo "# DOWNLOAD test:\n"; -echo"# Login: ".($sessid = Alib::Login('root', 'q'))."\n"; - -echo"# downloadAudioClipFromHub: "; -$r = $gb->downloadFromHub($sessid, $gunid); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); } -var_export($r); echo"\n"; -$trtok = $r; - -echo"# logout: "; $r = Alib::Logout($sessid); -if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); } -echo "$r\n"; - -for($state='', $nu=1; ($state!='closed' && $state!='failed' && $nu<=12); $nu++, sleep(2)){ - echo"# getTransportInfo: "; $r = $gb->getTransportInfo($trtok); - if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); } - $state = $r['state']; - echo "# state=$state, title={$r['title']}\n"; -} -if($state=='failed') exit(1); - -$comm = "ls -l ".$CC_CONFIG['storageDir']."/a23"; echo `$comm`; - -if(file_exists("../trans/log")) echo `tail -n 25 ../trans/log`; -echo "#Transport test: OK.\n\n"; -*/ -?> \ No newline at end of file diff --git a/backend/tests/webstreamTest.php b/backend/tests/webstreamTest.php deleted file mode 100644 index d8393867c..000000000 --- a/backend/tests/webstreamTest.php +++ /dev/null @@ -1,62 +0,0 @@ -\n"); -PEAR::setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); -$gb = new GreenBox(); - -#$gunid = "123456789abcdee0"; -$gunid = ""; -#$mdataFileLP = '../tests/mdata1.xml'; -$mdataFileLP = NULL; - -echo "# Login: ".($sessid = Alib::Login('root', 'q'))."\n"; -$parid = $gb->_getHomeDirId($sessid); - -echo "# storeWebstream: "; -$r = $gb->storeWebstream( - $parid, 'test stream', $mdataFileLP, $sessid, $gunid, 'http://localhost/y'); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; - exit(1); -} -echo ""; -var_dump($r); -//$id = BasicStor::IdFromGunid($gunid); -$id = $r; - -echo "# getMdata: "; -$r = $gb->getMetadata($id, $sessid); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; - exit(1); -} -echo "\n$r\n"; - -echo "# deleteFile: "; -$r = $gb->deleteFile($id, $sessid); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; - exit(1); -} -echo "\n$r\n"; - -echo "# logout: "; -$r = Alib::Logout($sessid); -if (PEAR::isError($r)) { - echo "ERROR: ".$r->getMessage()."\n"; - exit(1); -} -echo "$r\n"; - -echo "#storeWebstream test: OK.\n\n" -*/ -?> \ No newline at end of file diff --git a/backend/tests/wstream1.xml b/backend/tests/wstream1.xml deleted file mode 100644 index 57e228d8a..000000000 --- a/backend/tests/wstream1.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Webstream test 1 - 01:30:00.000000 - http://localhost/y - - diff --git a/backend/webstreamFormat.php b/backend/webstreamFormat.php deleted file mode 100644 index 219230779..000000000 --- a/backend/webstreamFormat.php +++ /dev/null @@ -1,345 +0,0 @@ -'audioClip', - 'audioClip'=>array( - 'childs'=>array( - 'required'=>array('metadata'), - ), - ), - 'metadata'=>array( - 'childs'=>array( - 'required'=>array( - 'dc:title', 'dcterms:extent', 'ls:url' - ), - 'optional'=>array( - 'dc:identifier', - 'dc:creator', 'dc:source', 'ls:genre', - 'ls:year', 'dc:type', 'dc:description', 'dc:format', - 'ls:bpm', 'ls:rating', 'ls:encoded_by', 'ls:track_num', - 'ls:disc_num', 'ls:disc_num', 'dc:publisher', 'ls:composer', - 'ls:bitrate', 'ls:channels', 'ls:samplerate', 'ls:encoder', - 'ls:crc', 'ls:lyrics', 'ls:orchestra', 'ls:conductor', - 'ls:lyricist', 'ls:originallyricist', 'ls:radiostationname', - 'ls:audiofileinfourl', 'ls:artisturl', 'ls:audiosourceurl', - 'ls:radiostationurl', 'ls:buycdurl', 'ls:isrcnumber', - 'ls:catalognumber', 'ls:originalartist', 'dc:rights', - 'ls:license', 'dc:title', 'dcterms:temporal', - 'dcterms:spatial', 'dcterms:entity', 'dc:description', - 'dc:creator', 'dc:subject', 'dc:type', 'dc:format', - 'dc:contributor', 'dc:language', 'dc:rights', - 'dcterms:isPartOf', 'dc:date', - 'dc:publisher', - // extra - 'dcterms:alternative', 'ls:filename', 'ls:mtime', - // added lately by sebastian - 'ls:mood', - ), - ), - 'namespaces'=>array( - 'dc'=>"http://purl.org/dc/elements/1.1/", - 'dcterms'=>"http://purl.org/dc/terms/", - 'xbmf'=>"http://www.streamonthefly.org/xbmf", - 'xsi'=>"http://www.w3.org/2001/XMLSchema-instance", - 'xml'=>"http://www.w3.org/XML/1998/namespace", - ), - ), - 'ls:url'=>array( - 'type'=>'URL', - ), - 'dc:identifier'=>array( - 'type'=>'Text', - 'auto'=>TRUE, - ), - 'dc:title'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:alternative'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:extent'=>array( - 'type'=>'Time', - 'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$', - ), - 'dc:creator'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:source'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:genre'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:year'=>array( - 'type'=>'Menu', - 'area'=>'Music', - ), - 'dc:type'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:description'=>array( - 'type'=>'Longtext', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:format'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:bpm'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:rating'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:encoded_by'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:track_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:disc_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:disc_num'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:publisher'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:composer'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:bitrate'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:channels'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:samplerate'=>array( - 'type'=>'Menu', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:encoder'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:crc'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:lyrics'=>array( - 'type'=>'Longtext', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:orchestra'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:conductor'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:lyricist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:originallyricist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:radiostationname'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:audiofileinfourl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:artisturl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:audiosourceurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:radiostationurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:buycdurl'=>array( - 'type'=>'URL', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:isrcnumber'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:catalognumber'=>array( - 'type'=>'Number', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:originalartist'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:rights'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:license'=>array( - 'type'=>'Text', - 'area'=>'Music', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:title'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:temporal'=>array( - 'type'=>'Time/Date', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:spatial'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:entity'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:description'=>array( - 'type'=>'Longtext', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:creator'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:subject'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:type'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:format'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:contributor'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:language'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:rights'=>array( - 'type'=>'Menu', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dcterms:isPartOf'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:date'=>array( - 'type'=>'Date', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'dc:publisher'=>array( - 'type'=>'Text', - 'area'=>'Talk', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:filename'=>array( - 'type'=>'Text', - 'attrs'=>array('implied'=>array('xml:lang')), - ), - 'ls:mtime'=>array( - 'type'=>'Int', -// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$', - ), -/* - ''=>array( - 'type'=>'', - 'area'=>'', - 'attrs'=>array(), - ), -*/ -); - -/* -? -ls:filename Text auto -*/ -?> \ No newline at end of file diff --git a/backend/xmlrpc/XR_LocStor.php b/backend/xmlrpc/XR_LocStor.php deleted file mode 100644 index f8df60978..000000000 --- a/backend/xmlrpc/XR_LocStor.php +++ /dev/null @@ -1,3833 +0,0 @@ - - *

  • version : string
  • - * - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_getVersion: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Subjects::getVersion - */ -// public function xr_getVersion($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// $res = $this->getVersion(); -// if (PEAR::isError($res)) { -// return new XML_RPC_Response(0, 805, -// "xr_getVersion: ".$res->getMessage(). -// " ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response( -// XML_RPC_encode(array('version'=>$res)) -// ); -// } - public function xr_getVersion() - { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } - $res = $this->getVersion(); -// if (PEAR::isError($res)) { -// return new XML_RPC_Response(0, 805, -// "xr_getVersion: ".$res->getMessage(). -// " ".$res->getUserInfo() -// ); -// } - return new XML_RPC_Response( - XML_RPC_encode(array('version'=>$res)) - ); - } - - - /* ------------------------------------------------------- authentication */ - /** - * Checks the login name and password of the user and return - * true if login data are correct, othervise return false. - * - * The XML-RPC name of this method is "locstor.authenticate". - * - * Input parameters: XML-RPC struct with the following fields: - *
      - *
    • login : string - login name
    • - *
    • pass : string - password
    • - *
    - * On success, returns a XML-RPC struct with single field: - *
      - *
    • authenticate : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 804 - xr_authenticate: database error
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Subjects::authenticate - */ - public function xr_authenticate($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->authenticate($r['login'], $r['pass']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 804, - "xr_authenticate: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - $retval = ($res !== FALSE); - return new XML_RPC_Response( - XML_RPC_encode(array('authenticate'=>$retval)) - ); - } - - - /** - * Checks the login name and password of the user. If the login is - * correct, a new session ID string is generated, to be used in all - * subsequent XML-RPC calls as the "sessid" field of the - * parameters. - * - * The XML-RPC name of this method is "locstor.login". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • login : string - login name
    • - *
    • pass : string - password
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • sessid : string - the newly generated session ID
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 802 - xr_login: login failed - - * incorrect username or password.
    • - *
    • 804 - xr_login:: database error
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Alib::login - */ - public function xr_login($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = Alib::Login($r['login'], $r['pass']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 804, - "xr_login: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - if ($res === FALSE) { - return new XML_RPC_Response(0, 802, - "xr_login: login failed - incorrect username or password." - ); - } else { - return new XML_RPC_Response(XML_RPC_encode(array('sessid'=>$res))); - } - } - - /** - * Logout, destroy session and return status. - * If session is not valid error message is returned. - * - * The XML-RPC name of this method is "locstor.logout". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean - TRUE
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 803 - xr_logout: logout failed - not logged.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - public function xr_logout($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = Alib::Logout($r['sessid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 803, - "xr_logout: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /* ---------------------------------------------------------------- store */ - /** - * Open writable URL for store new AudioClip or replace existing one. - * Writing to returned URL is possible using HTTP PUT method - * (as e.g. curl -T <filename> command does) - * - * The XML-RPC name of this method is "locstor.storeAudioClipOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip, - * if gunid is empty string, new one is generated - * (returned by subsequent storeAudioClipClose call) - *
    • - *
    • metadata : string - metadata XML string - * (as defined in Campcaster::Core::AudioClip Class Reference, - * examples are in storageServer/var/tests/*.xml) - *
    • - *
    • fname : string - human readable mnemonic file name - * with extension corresponding to filetype
    • - *
    • chsum : string - md5 checksum of media file
    • - *
    - * - * On success, returns a XML-RPC struct: - *
      - *
    • url : string - writable URL for HTTP PUT
    • - *
    • token : string - access token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_storeAudioClipOpen: - * <message from lower layer>
    • - *
    • 888 - If the file being uploaded is a duplicate of - * a file already in the system.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::storeAudioClipOpen - */ - public function xr_storeAudioClipOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->storeAudioClipOpen($r['sessid'], $r['gunid'], - $r['metadata'], $r['fname'], $r['chsum']); - if (PEAR::isError($res)) { - $code = 805; - if ($res->getCode() == 888) { - $code = 888; - } - return new XML_RPC_Response(0, $code, - "xr_storeAudioClipOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Close writable URL for store new AudioClip or replace existing one. - * - * The XML-RPC name of this method is "locstor.storeAudioClipClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - access token
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • gunid : string - gunid of stored file
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_storeAudioClipClose: - * <message from lower layer>
    • - *
    • 850 - wrong 1st parameter, struct expected.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::storeAudioClipClose - */ - public function xr_storeAudioClipClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->storeAudioClipClose($r['sessid'], $r['token']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_TOKEN ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_storeAudioClipClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('gunid'=>$res))); - } - - /** - * Store audio stream identified by URL - no raw audio data - * - * The XML-RPC name of this method is "locstor.storeWebstream". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip
    • - *
    • metadata : string - metadata XML string
    • - *
    • fname : string - human readable mnemonic file name - * with extension corresponding to filetype
    • - *
    • url : string - URL of the webstrea,
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • gunid : string - gunid of stored file
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_storeWebstream: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::storeWebstream - */ - public function xr_storeWebstream($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->storeWebstream( - $r['sessid'], $r['gunid'], $r['metadata'], $r['fname'], $r['url'] - ); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_storeWebstream: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('gunid'=>$res))); - } - - /* ------------------------------------------------ access raw audio data */ - /** - * Make access to audio clip. - * - * The XML-RPC name of this method is "locstor.accessRawAudioData". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioClip
    • - *
    - * - * On success, returns a XML-RPC struct: - *
      - *
    • url : string - local access url
    • - *
    • token : string - access token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_accessRawAudioData: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::accessRawAudioData - */ - public function xr_accessRawAudioData($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->accessRawAudioData($r['sessid'], $r['gunid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_accessRawAudioData: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Release access to audio clip - * - * The XML-RPC name of this method is "locstor.releaseRawAudioData". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - access token - * returned by locstor.accessRawAudioData
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_releaseRawAudioData: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::releaseRawAudioData - */ - public function xr_releaseRawAudioData($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->releaseRawAudioData(NULL, $r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_releaseRawAudioData: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /* ---------------------------------------------- download raw audio data */ - /** - * Create downlodable URL for stored file - * - * The XML-RPC name of this method is "locstor.downloadRawAudioDataOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioClip
    • - *
    - * - * On success, returns a XML-RPC struct: - *
      - *
    • url : string - downloadable url
    • - *
    • token : string - download token
    • - *
    • chsum : string - md5 checksum
    • - *
    • size : int - file size
    • - *
    • filename : string - human readable mnemonic file name
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_accessRawAudioDataOpen: - * <message from lower layer>
    • - *
    • 847 - invalid gunid.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::downloadRawAudioDataOpen - */ - public function xr_downloadRawAudioDataOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->downloadRawAudioDataOpen($r['sessid'], $r['gunid']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_NOTF ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_downloadRawAudioDataOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Delete downlodable URL with media file. - * - * The XML-RPC name of this method is "locstor.downloadRawAudioDataClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - download token - * returned by locstor.downloadRawAudioDataOpen
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • gunid : string - global unique ID
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_releaseRawAudioDataClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::downloadRawAudioDataClose - */ - public function xr_downloadRawAudioDataClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->downloadRawAudioDataClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_downloadRawAudioDataClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('gunid'=>$res))); - } - - /* ---------------------------------------------------- download metadata */ - /** - * Create downlodable URL for metadata part of stored file - * - * The XML-RPC name of this method is "locstor.downloadMetadataOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioClip
    • - *
    - * - * On success, returns a XML-RPC struct: - *
      - *
    • url : string - downloadable url
    • - *
    • token : string - download token
    • - *
    • chsum : string - md5 checksum
    • - *
    • filename : string - mnemonic filename
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_downloadMetadataOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::downloadRawAudioDataOpen - */ - public function xr_downloadMetadataOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - #$this->debugLog("{$r['sessid']}, {$r['gunid']}"); - $res = $this->downloadMetadataOpen($r['sessid'], $r['gunid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_downloadMetadataOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Delete downlodable URL with metadata. - * - * The XML-RPC name of this method is "locstor.downloadMetadataClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - download token - * returned by locstor.downloadRawAudioDataOpen
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • gunid : string - global unique ID
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_downloadMetadataClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::downloadRawAudioDataClose - */ - public function xr_downloadMetadataClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->downloadMetadataClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_downloadMetadataClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('gunid'=>$res))); - } - - /* --------------------------------------------------------------- delete */ - /** - * Delete existing audio clip - DISABLED now! - * - * The XML-RPC name of this method is "locstor.deleteAudioClip". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean - TRUE
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_deleteAudioClip: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::deleteAudioClip - */ - public function xr_deleteAudioClip($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - if (!isset($r['forced'])) { - $r['forced']=FALSE; - } - $res = $this->deleteAudioClip($r['sessid'], $r['gunid'], $r['forced']); - if (!$r['forced']) { - return new XML_RPC_Response(0, 805, "xr_deleteAudioClip: method disabled"); - } - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_deleteAudioClip: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /*====================================================== playlist methods */ - /** - * Create a new Playlist metafile. - * - * The XML-RPC name of this method is "locstor.createPlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    • fname : string - human readable menmonic file name
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • plid : string
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_createPlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::createPlaylist - */ - public function xr_createPlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->createPlaylist($r['sessid'], $r['plid'], $r['fname']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_createPlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('plid'=>$res))); - } - - /** - * Open a Playlist metafile for editing. - * Open readable URL and mark file as beeing edited. - * - * The XML-RPC name of this method is "locstor.editPlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • url : string - readable url
    • - *
    • token : string - playlist token
    • - *
    • chsum : string - md5 checksum
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_editPlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::editPlaylist - */ - public function xr_editPlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->editPlaylist($r['sessid'], $r['plid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_editPlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Store a new Playlist metafile in place of the old one. - * - * The XML-RPC name of this method is "locstor.savePlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - playlist token - * returned by locstor.editPlaylist
    • - *
    • newPlaylist : string - new Playlist in XML string
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • plid : string - playlistId
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_savePlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::savePlaylist - */ - public function xr_savePlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->savePlaylist($r['sessid'], $r['token'], $r['newPlaylist']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_savePlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('plid'=>$res))); - } - - /** - * RollBack playlist changes to the locked state - * - * The XML-RPC name of this method is "locstor.revertEditedPlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - playlist token - * returned by locstor.editPlaylist
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • plid : string - playlistId
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_revertEditedPlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::revertEditedPlaylist - */ - public function xr_revertEditedPlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->revertEditedPlaylist($r['token'], $r['sessid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_revertEditedPlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('plid'=>$res))); - } - - /* ------------------------------------------------------- delete playlist*/ - /** - * Delete a Playlist metafile - DISABLED now! - * - * The XML-RPC name of this method is "locstor.deletePlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean - TRUE
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_deletePlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::deletePlaylist - */ - public function xr_deletePlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - if (!isset($r['forced'])) { - $r['forced']=FALSE; - } - $res = $this->deletePlaylist($r['sessid'], $r['plid'], $r['forced']); - if (! $r['forced']) { - return new XML_RPC_Response(0, 805,"xr_deletePlaylist: method disabled"); - } - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_FILENEX ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_deletePlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /* ------------------------------------------------------- access playlist*/ - /** - * Access (read) a Playlist metafile. - * - * The XML-RPC name of this method is "locstor.accessPlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    • recursive : boolean - flag for recursive access content - * inside playlist (default: false)
    • - *
    - * - * On success, returns an XML-RPC struct with the following fields: - *
      - *
    • url : string - readable url of accessed playlist in - * XML format
    • - *
    • token : string - playlist token
    • - *
    • chsum : string - md5 checksum
    • - *
    • content: array of structs - recursive access (optional)
    • - *
    - * - * The content field contains a struct for each playlist - * element contained in the playlist. For audio clips, this struct is - * of type {url, token}; for sub-playlists, it is of type - * {url, token, chsum, content}. - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_accessPlaylist: - * <message from lower layer>
    • - *
    • 847 - invalid plid.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::accessPlaylist - */ - public function xr_accessPlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - if (!isset($r['recursive']) || is_null($r['recursive'])) { - $r['recursive']=FALSE; - } - $res = $this->accessPlaylist($r['sessid'], $r['plid'], (boolean)$r['recursive']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_NOTF ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_accessPlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Release the resources obtained earlier by accessPlaylist(). - * - * The XML-RPC name of this method is "locstor.releasePlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - playlist token - * returned by locstor.accessPlaylist
    • - *
    • recursive : boolean - flag for recursive release content - * accessed by recursive accessPlaylist - * (ignored now - true forced)
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • plid : string - playlist ID
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_releasePlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::releasePlaylist - */ - public function xr_releasePlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - //if (!isset($r['recursive']) || is_null($r['recursive'])) $r['recursive']=FALSE; - $res = $this->releasePlaylist(NULL, $r['token'], TRUE); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_releasePlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('plid'=>$res))); - } - - /* -------------------------------------------------------- playlist info */ - /** - * Check whether a Playlist metafile with the given playlist ID exists. - * - * The XML-RPC name of this method is "locstor.existsPlaylist". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • exists : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_existsPlaylist: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::existsPlaylist - */ - public function xr_existsPlaylist($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->existsPlaylist($r['sessid'], $r['plid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_existsPlaylist: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('exists'=>$res))); - } - - /** - * Check whether a Playlist metafile with the given playlist ID - * is available for editing, i.e., exists and is not marked as - * beeing edited. - * - * The XML-RPC name of this method is "locstor.playlistIsAvailable". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - global unique id of Playlist
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • available : boolean
    • - *
    • ownerid : int - local user id
    • - *
    • ownerlogin : string - local username
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_playlistIsAvailable: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::playlistIsAvailable - */ - public function xr_playlistIsAvailable($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->playlistIsAvailable($r['sessid'], $r['plid'], TRUE); - $ownerId = ($res === TRUE ? NULL : $res); - $ownerLogin = (is_null($ownerId) ? NULL : Subjects::GetSubjName($ownerId)); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_playlistIsAvailable: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'available' => ($res === TRUE), - 'ownerid' => $ownerId, - 'ownerlogin' => $ownerLogin, - ))); - } - - /* ------------------------------------------------------ export playlist */ - /** - * Create a tarfile with playlist export - playlist and all matching - * sub-playlists and media files (if desired) - * - * The XML-RPC name of this method is "locstor.exportPlaylistOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plids : array of strings - global unique IDs of Playlists
    • - *
    • type : string - playlist format, values: lspl | smil
    • - *
    • standalone : boolean - if only playlist should be exported or - * with all related files
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • url : string - readable url
    • - *
    • token : string - access token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_exportPlaylistOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::exportPlaylistOpen - */ - public function xr_exportPlaylistOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - if (!isset($r['standalone']) || empty($r['standalone'])) { - $r['standalone']=FALSE; - } - $res = $this->exportPlaylistOpen( - $r['sessid'], $r['plids'], $r['type'], $r['standalone'] - ); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_exportPlaylistOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'url' => $res['url'], - 'token' => $res['token'], - ))); - } - - /** - * Close playlist export previously opened by the exportPlaylistOpen method - * - * The XML-RPC name of this method is "locstor.exportPlaylistClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - access token
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean - status/li> - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_exportPlaylistClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::exportPlaylistClose - */ - public function xr_exportPlaylistClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->exportPlaylistClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_exportPlaylistClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>TRUE))); - } - - /* ------------------------------------------------------ import playlist */ - /** - * Open writable URL for import playlist in LS Archive format - * - * The XML-RPC name of this method is "locstor.importPlaylistOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • chsum : string - md5 checksum of imported file
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • url : string - writable url
    • - *
    • token : string - PUT token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_importPlaylistOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::importPlaylistOpen - */ - public function xr_importPlaylistOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->importPlaylistOpen($r['sessid'], $r['chsum']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_importPlaylistOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'url'=>$res['url'], - 'token'=>$res['token'], - ))); - } - - /** - * Open writable URL for import playlist in LS Archive format - * - * The XML-RPC name of this method is "locstor.importPlaylistClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - access token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • gunid : string - global id
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_importPlaylistClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::importPlaylistClose - */ - public function xr_importPlaylistClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->importPlaylistClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_importPlaylistClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'gunid'=>$res, - ))); - } - - /* ---------------------------------------------- render playlist to file */ - /** - * Render playlist to ogg file (open handle) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToFileOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - playlist gunid
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToFileOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToFileOpen - */ - public function xr_renderPlaylistToFileOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToFileOpen($r['sessid'], $r['plid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToFileOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'token'=>$res['token'], - ))); - } - - /** - * Render playlist to ogg file (check results) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToFileCheck". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • url : string - readable url
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToFileCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToFileCheck - */ - public function xr_renderPlaylistToFileCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToFileCheck($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToFileCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'url'=>$res['url'], - 'status'=>$res['status'], - ))); - } - - /** - * Render playlist to ogg file (close handle) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToFileClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToFileClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToFileClose - */ - public function xr_renderPlaylistToFileClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToFileClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToFileClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'status'=>$res['status'], - ))); - } - - /* ------------------------------------------- render playlist to storage */ - /** - * Render playlist to storage media clip (open handle) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToStorageOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - playlist gunid
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToStorageOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToStorageOpen - */ - public function xr_renderPlaylistToStorageOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToStorageOpen($r['sessid'], $r['plid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToStorageOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'token'=>$res['token'], - ))); - } - - /** - * Render playlist to storage media clip (check results) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToStorageCheck". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • gunid : string - gunid of result file
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToStorageCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToStorageCheck - */ - public function xr_renderPlaylistToStorageCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToStorageCheck($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToStorageCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'status'=>$res['status'], - 'gunid'=>$res['gunid'], - ))); - } - - /* ----------------------------------------------- render playlist to RSS */ - /** - * Render playlist to RSS file (open handle) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToRSSOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • plid : string - playlist gunid
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToRSSOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToRSSOpen - */ - public function xr_renderPlaylistToRSSOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToRSSOpen($r['sessid'], $r['plid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToRSSOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'token'=>$res['token'], - ))); - } - - /** - * Render playlist to RSS file (check results) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToRSSCheck". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • url : string - readable url
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToRSSCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToRSSCheck - */ - public function xr_renderPlaylistToRSSCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToRSSCheck($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToRSSCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'url'=>$res['url'], - 'status'=>$res['status'], - ))); - } - - /** - * Render playlist to RSS file (close handle) - * - * The XML-RPC name of this method is "locstor.renderPlaylistToRSSClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - render token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_renderPlaylistToRSSClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::renderPlaylistToRSSClose - */ - public function xr_renderPlaylistToRSSClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->renderPlaylistToRSSClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_renderPlaylistToRSSClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'status'=>$res['status'], - ))); - } - - /*==================================================storage admin methods */ - /* ------------------------------------------------------- backup methods */ - /** - * Create backup of storage (open handle) - * - * The XML-RPC name of this method is "locstor.createBackupOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • criteria : struct - see search criteria
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • token : string - backup token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_createBackupOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::createBackupOpen - */ - public function xr_createBackupOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - -# return new XML_RPC_Response(XML_RPC_encode(var_export($this, TRUE))); - - $res = $this->createBackupOpen($r['sessid'], $r['criteria']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_createBackupOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'token'=>$res['token'], - ))); - } - - /** - * Create backup of storage (check results) - * - * The XML-RPC name of this method is "locstor.createBackupCheck". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - backup token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • url : string - readable url
    • - *
    • metafile : string - archive metafile in XML format
    • - *
    • faultString : string - error message - * (use only if status==fault)
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_createBackupCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::createBackupCheck - */ - //
  • 854 - backup process fault
  • - public function xr_createBackupCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->createBackupCheck($r['token']); - - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_BGERR ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_createBackupCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Create backup of storage (list results) - * - * The XML-RPC name of this method is "locstor.createBackupList". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • stat : string - backup status
    • - *
    - * - * On success, returns a XML-RPC array of struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • url : string - readable url
    • - *
    • metafile : string - archive metafile in XML format
    • - *
    • faultString : string - error message - * (use only if status==fault)
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_createBackupCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::createBackupCheck - */ - //
  • 854 - backup process fault
  • - public function xr_createBackupList($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - if (!isset($r['stat']) || is_null($r['stat'])) { - $r['stat']=''; - } - $res = $this->createBackupList($r['stat']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_BGERR ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_createBackupCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Create backup of storage (close handle) - * - * The XML-RPC name of this method is "locstor.createBackupClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - backup token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_createBackupClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::createBackupClose - */ - public function xr_createBackupClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->createBackupClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_createBackupClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'status'=>$res['status'], - ))); - } - /* ------------------------------------------------------ restore methods */ - /** - * Open restore a backup file - * - * The XML-RPC name of this method is "locstor.restoreBackupOpen". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • chsum : string - md5 checksum of restore file
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • url : string - writable URL for HTTP PUT
    • - *
    • token : string - PUT token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_restoreBackupOpen: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::restoreBackupOpen - */ - public function xr_restoreBackupOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->restoreBackupOpen($r['sessid'], $r['chsum']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_restoreBackupOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - unset($res['fname']); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Close writable URL for restore a backup file and start the restore - * process - * - * The XML-RPC name of this method is "locstor.restoreBackupClosePut". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • token : string - PUT token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • token : string - restore token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_restoreBackupClosePut: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::restoreBackupClosePut - */ - public function xr_restoreBackupClosePut($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->restoreBackupClosePut($r['sessid'], $r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_restoreBackupClosePut: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Check the state of restore procedure - * - * The XML-RPC name of this method is "locstor.restoreBackupCheck". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - restore token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - success | working | fault
    • - *
    • faultString: string - description of fault
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_restoreBackupCheck: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::restoreBackupCheck - */ - public function xr_restoreBackupCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->restoreBackupCheck($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_restoreBackupCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } -# return new XML_RPC_Response(XML_RPC_encode(array( -# 'status'=>$res, -# ))); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Close the restore process - * - * The XML-RPC name of this method is "locstor.restoreBackupClose". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • token : string - restore token
    • - *
    - * - * On success, returns a XML-RPC struct with following fields: - *
      - *
    • status : string - status
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_restoreBackupClose: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::restoreBackupClose - */ - public function xr_restoreBackupClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->restoreBackupClose($r['token']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_restoreBackupClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } -# return new XML_RPC_Response(XML_RPC_encode(array( -# 'gunid'=>$res, -# ))); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /*========================================================== info methods */ - /** - * Check if audio clip exists and return TRUE/FALSE - * - * The XML-RPC name of this method is "locstor.existsAudioClip". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • exists : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_existsAudioClip: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::existsAudioClip - */ - public function xr_existsAudioClip($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - #$this->debugLog(join(', ', $r)); - $res = $this->existsAudioClip($r['sessid'], $r['gunid']); - #$this->debugLog($res); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 805, - "xr_existsAudioClip: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode(array('exists'=>$res))); - } - - /*====================================================== metadata methods */ - /** - * Return all file's metadata as XML string - * - * The XML-RPC name of this method is "locstor.getAudioClip". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • metadata : string - metadata as XML
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_getAudioClip: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::getAudioClip - */ - public function xr_getAudioClip($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->getAudioClip($r['sessid'], $r['gunid']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('metadata'=>$res))); - } - - /** - * Update existing audio clip metadata - * - * The XML-RPC name of this method is "locstor.updateAudioClipMetadata". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id of AudioCLip
    • - *
    • metadata : metadata XML string
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean - TRUE
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_updateAudioClipMetadata: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::updateAudioClipMetadata - */ - public function xr_updateAudioClipMetadata($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->updateAudioClipMetadata( - $r['sessid'], $r['gunid'], $r['metadata'] - ); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_updateAudioClip: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /** - * Search in local metadata database - * - * The XML-RPC name of this method is "locstor.searchMetadata". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • criteria : struct, with following fields:
      - *
        - *
      • filetype : string - type of searched files, - * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'
      • - *
      • operator : string - type of conditions join - * (any condition matches / all conditions match), - * meaningful values: 'and', 'or', '' - * (may be empty or ommited only with less then 2 items in - * "conditions" field) - *
      • - *
      • limit : int - limit for result arrays (0 means unlimited)
      • - *
      • offset : int - starting point (0 means without offset)
      • - *
      • orderby : string - metadata category for sorting (optional) - * or array of strings for multicolumn orderby - * [default: dc:creator, dc:source, dc:title] - *
      • - *
      • desc : boolean - flag for descending order (optional) - * or array of boolean for multicolumn orderby - * (it corresponds to elements of orderby field) - * [default: all ascending] - *
      • - *
      • conditions : array of struct with fields: - *
          - *
        • cat : string - metadata category name
        • - *
        • op : string - operator, meaningful values: - * 'full', 'partial', 'prefix', '=', '<', '<=', - * '>', '>='
        • - *
        • val : string - search value
        • - *
        - *
      • - *
      - *
    • - *
    - * - * On success, returns a XML-RPC array of structs with fields: - *
      - *
    • cnt : integer - number of matching gunids - * of files have been found
    • - *
    • results : array of hashes: - *
        - *
      • gunid: string
      • - *
      • type: string - audioclip | playlist | webstream
      • - *
      • title: string - dc:title from metadata
      • - *
      • creator: string - dc:creator from metadata
      • - *
      • source: string - dc:source from metadata
      • - *
      • length: string - dcterms:extent in extent format
      • - *
      - *
    • - *
    - * (cnt value may be greater than size of result array - see limit param) - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_searchMetadata: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::searchMetadata - * @see BasicStor::localSearch - */ - public function xr_searchMetadata($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->searchMetadata($r['sessid'], $r['criteria']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_searchAudioClip: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } -# return new XML_RPC_Response(XML_RPC_encode($res)); - $xv = new XML_RPC_Value; - $xv->addStruct(array( - 'cnt' => XML_RPC_encode($res['cnt']), - 'results' => - (count($res['results'])==0 - ? new XML_RPC_Value(array(), 'array') - : XML_RPC_encode($res['results']) - ), - )); - return new XML_RPC_Response($xv); - } - - /** - * Return values of specified metadata category - * - * The XML-RPC name of this method is "locstor.browseCategory". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • category : string - metadata category name - * with or without namespace prefix (dc:title, author)
    • - *
    • criteria : hash - see searchMetadata method
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • results : array with found values
    • - *
    • cnt : integer - number of matching values
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_browseCategory: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::browseCategory - */ - public function xr_browseCategory($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->browseCategory( - $r['category'], $r['criteria'], $r['sessid'] - ); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - - ); - } - $xv = new XML_RPC_Value; - $xv->addStruct(array( - 'cnt' => XML_RPC_encode($res['cnt']), - 'results' => - (count($res['results'])==0 - ? new XML_RPC_Value(array(), 'array') - : XML_RPC_encode($res['results']) - ), - )); - return new XML_RPC_Response($xv); - } - - /* ============================================== methods for preferences */ - /** - * Load user preference value - * - * The XML-RPC name of this method is "locstor.loadPref". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • key : string - preference key
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • value : string - preference value
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_loadPref: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 849 - invalid preference key.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Pref::loadPref - */ - public function xr_loadPref($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once(dirname(__FILE__).'/../Prefs.php'); - $pr = new Prefs($this); - $res = $pr->loadPref($r['sessid'], $r['key']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == GBERR_PREF ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('value'=>$res))); - } - - /** - * Save user preference value - * - * The XML-RPC name of this method is "locstor.savePref". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • key : string - preference key
    • - *
    • value : string - preference value
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_savePref: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Pref::savePref - */ - public function xr_savePref($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once(dirname(__FILE__).'/../Prefs.php'); - $pr = new Prefs($this); - $res = $pr->savePref($r['sessid'], $r['key'], $r['value']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /** - * Delete user preference record - * - * The XML-RPC name of this method is "locstor.delPref". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • key : string - preference key
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_delPref: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 849 - invalid preference key.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Pref::delPref - */ - public function xr_delPref($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once(dirname(__FILE__).'/../Prefs.php'); - $pr = new Prefs($this); - $res = $pr->delPref($r['sessid'], $r['key']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == GBERR_PREF ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /** - * Read group preference record - * - * The XML-RPC name of this method is "locstor.loadGroupPref". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • group : string - group name
    • - *
    • key : string - preference key
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • value : string - preference value
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_loadGroupPref: - * <message from lower layer>
    • - *
    • 820 - invalid group name.
    • - *
    • 848 - invalid session id.
    • - *
    • 849 - invalid preference key.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Pref::loadGroupPref - */ - public function xr_loadGroupPref($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once(dirname(__FILE__).'/../Prefs.php'); - $pr = new Prefs($this); - $res = $pr->loadGroupPref($r['group'], $r['key']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ( - $ec0 == GBERR_SESS || $ec0 == GBERR_PREF || $ec0==ALIBERR_NOTGR - ? 800+$ec0 : 805 - ); - return new XML_RPC_Response(0, $ec, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('value'=>$res))); - } - - /** - * Save group preference record - * - * The XML-RPC name of this method is "locstor.saveGroupPref". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • group : string - group name
    • - *
    • key : string - preference key
    • - *
    • value : string - preference value
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • status : boolean
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_saveGroupPref: - * <message from lower layer>
    • - *
    • 820 - invalid group name.
    • - *
    • 848 - invalid session id.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Pref::saveGroupPref - */ - public function xr_saveGroupPref($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once(dirname(__FILE__).'/../Prefs.php'); - $pr = new Prefs($this); - $res = $pr->saveGroupPref($r['sessid'], $r['group'], $r['key'], $r['value']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0==GBERR_SESS || $ec0==ALIBERR_NOTGR ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res))); - } - - /* =============================== remote repository (networking) methods */ - /* ------------------------------------------------------- common methods */ - /** - * Common "check" method for transports - * - * The XML-RPC name of this method is "locstor.getTransportInfo". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtype: string - audioclip | playlist | search | file
    • - *
    • direction: string - up | down
    • - *
    • state: string - transport state
    • - *
    • expectedsize: int - expected size
    • - *
    • realsize: int - size of transported file
    • - *
    • expectedchsum: string - expected checksum
    • - *
    • realchsum: string - checksum of transported file
    • - *
    • title: string - file title
    • - *
    • errmsg: string - error message from failed transports
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_getTransportInfo: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::getTransportInfo - */ - public function xr_getTransportInfo($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->getTransportInfo($r['trtok']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getTransportInfo: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Turn transports on/off, optionaly return current state. - * - * The XML-RPC name of this method is "locstor.turnOnOffTransports". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • onOff: boolean optional - * (if not used, current state is returned)
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • state : boolean - previous state
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_turnOnOffTransports: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::turnOnOffTransports - */ - public function xr_turnOnOffTransports($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->turnOnOffTransports($r['onOff']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_turnOnOffTransports: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('state'=>$res))); - } - - /** - * Pause, resume or cancel transport - * - * The XML-RPC name of this method is "locstor.doTransportAction". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • trtok : string - transport token
    • - *
    • action: string - pause | resume | cancel - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • state : string - resulting transport state
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_doTransportAction: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::doTransportAction - */ - public function xr_doTransportAction($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->doTransportAction($r['trtok'], $r['action']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_doTransportAction: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('state'=>$res))); - } - - /* ------------------------ methods for ls-archive-format file transports */ - /** - * Open async file transfer from local storageServer to network hub, - * file should be ls-archive-format file. - * - * The XML-RPC name of this method is "locstor.uploadFile2Hub". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • filePath string - local path to uploaded file
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_uploadFile2Hub: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::uploadFile2Hub - */ - public function xr_uploadFile2Hub($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->uploadFile2Hub($r['filePath']); // local files on XML-RPC :( - // there should be something as uploadFile2storageServer - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_uploadFile2Hub: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); - } - - /** - * Get list of prepared transfers initiated by hub - * - * The XML-RPC name of this method is "locstor.getHubInitiatedTransfers". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • results : array of structs with fields: - *
        - *
      • trtok : string - transport token
      • - *
      • ... ?
      • - *
      - *
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_getHubInitiatedTransfers: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::getHubInitiatedTransfers - */ - public function xr_getHubInitiatedTransfers($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->getHubInitiatedTransfers(); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_getHubInitiatedTransfers: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /** - * Start of download initiated by hub - * - * The XML-RPC name of this method is "locstor.startHubInitiatedTransfer". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • trtok : string - transport token obtained from - * the getHubInitiatedTransfers method
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_startHubInitiatedTransfer: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::startHubInitiatedTransfer - */ - public function xr_startHubInitiatedTransfer($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->startHubInitiatedTransfer($r['trtok']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_startHubInitiatedTransfer: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); - } - - /* ------------- special methods for audioClip/webstream object transport */ - - /** - * Start upload of audioclip or playlist from local storageServer to hub - * - * The XML-RPC name of this method is "locstor.upload2Hub". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid: string - global unique id of object being transported - *
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_upload2Hub: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::upload2Hub - */ - public function xr_upload2Hub($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $res = $tr->upload2Hub($r['gunid']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_upload2Hub: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); - } - - /** - * Start download of audioclip or playlist from hub to local storageServer - * - * The XML-RPC name of this method is "locstor.downloadFromHub". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid: string - global unique id of object being transported - *
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_downloadFromHub: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::downloadFromHub - */ - public function xr_downloadFromHub($input) - { - list($ok, $par) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $par; - } - require_once('../Transport.php'); - $tr = new Transport($this); - $uid = Alib::GetSessUserId($par['sessid']); - $res = $tr->downloadFromHub($uid, $par['gunid']); - if (PEAR::isError($res)) { - $ec0 = intval($res->getCode()); - $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); - return new XML_RPC_Response(0, $ec, - "xr_downloadFromHub: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); - } - - /* ------------------------------------------------ global-search methods */ - /** - * Start search job on network hub - * - * The XML-RPC name of this method is "locstor.globalSearch". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • criteria : hash, LS criteria format - see searchMetadata method - *
    • - *
    - * - * On success, returns a XML-RPC struct with the following fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_globalSearch: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 874 - invalid hub connection configuration.
    • - *
    • 872 - invalid tranport token.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::globalSearch - */ -// public function xr_globalSearch($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// require_once('../Transport.php'); -// $tr = new Transport($this); -// $res = $tr->globalSearch($r['criteria']); -// if (PEAR::isError($res)) { -// $ec0 = intval($res->getCode()); -// $ec = ($ec0 == GBERR_SESS || $ec0 == TRERR_TOK ? 800+$ec0 : 805 ); -// return new XML_RPC_Response(0, $ec, -// "xr_globalSearch: ".$res->getMessage()." ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); -// } - - /** - * Get results from search job on network hub. - * (returns error if not finished) - * - * The XML-RPC name of this method is "locstor.getSearchResults". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On success, returns a XML-RPC array of structs with fields: - *
      - *
    • cnt : integer - number of matching gunids - * of files have been found
    • - *
    • results : array of hashes: - *
        - *
      • gunid: string
      • - *
      • type: string - audioclip | playlist | webstream
      • - *
      • title: string - dc:title from metadata
      • - *
      • creator: string - dc:creator from metadata
      • - *
      • source: string - dc:source from metadata
      • - *
      • length: string - dcterms:extent in extent format
      • - *
      - *
    • - *
    - * (cnt value may be greater than size of result array - see limit param) - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_getSearchResults: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    • 872 - invalid tranport token.
    • - *
    • 873 - not finished.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::getSearchResults - */ -// public function xr_getSearchResults($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// require_once('../Transport.php'); -// $tr = new Transport($this); -// $res = $tr->getSearchResults($r['trtok']); -// if (PEAR::isError($res)) { -// $ec0 = intval($res->getCode()); -// $ec = ( -// $ec0 == GBERR_SESS || $ec0 == TRERR_TOK || $ec0 == TRERR_NOTFIN -// ? 800+$ec0 : 805 ); -// return new XML_RPC_Response(0, $ec, -// "xr_getSearchResults: ".$res->getMessage()." ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response(XML_RPC_encode($res)); -// } - - /** - * OBSOLETE - * Starts upload audioclip to remote archive - * - * The XML-RPC name of this method is "locstor.uploadToArchive". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_uploadToArchive: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::uploadToArchive - */ -// public function xr_uploadToArchive($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// require_once(dirname(__FILE__).'/../Transport.php'); -// $tr = new Transport($this); -// $res = $tr->uploadToArchive($r['gunid'], $r['sessid']); -// if (PEAR::isError($res)) { -// $ec0 = intval($res->getCode()); -// $ec = ($ec0 == GBERR_SESS ? 800+$ec0 : 805 ); -// return new XML_RPC_Response(0, $ec, -// "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); -// } - - /** - * OBSOLETE - * Starts download audioclip from remote archive - * - * The XML-RPC name of this method is "locstor.downloadFromArchive". - * - * The input parameters are an XML-RPC struct with the following - * fields: - *
      - *
    • sessid : string - session id
    • - *
    • gunid : string - global unique id
    • - *
    - * - * On success, returns a XML-RPC struct with single field: - *
      - *
    • trtok : string - transport token
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_downloadFromArchive: - * <message from lower layer>
    • - *
    • 848 - invalid session id.
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see Transport::downloadFromArchive - */ -// public function xr_downloadFromArchive($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// require_once(dirname(__FILE__).'/../Transport.php'); -// $tr = new Transport($this); -// $res = $tr->downloadFromArchive($r['gunid'], $r['sessid']); -// if (PEAR::isError($res)) { -// $ec0 = intval($res->getCode()); -// $ec = ($ec0 == GBERR_SESS ? 800+$ec0 : 805 ); -// return new XML_RPC_Response(0, $ec, -// "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response(XML_RPC_encode(array('trtok'=>$res))); -// } - - /* ================================================ methods for debugging */ - /** - * Reset storageServer for debugging. - * - * The XML-RPC name of this method is "locstor.resetStorage". - * - * The input parameters are an empty XML-RPC struct, - * or struct with the following optional fields: - *
      - *
    • loadSampleData : boolean - load sample data? (default: true) - *
    • - *
    • invalidateSessionIds : boolean - invalidate active session IDs? - * (default: false) - *
    • - *
    - * - * On success, returns the same result as searchMetadata with filetype - * 'all' and no conditions, ordered by filetype and dc:title - * i.e. XML-RPC array of structs with fields: - *
      - *
    • cnt : integer - number of inserted files
    • - *
    • results : array of hashes: - *
        - *
      • gunid: string
      • - *
      • type: string - audioclip | playlist | webstream
      • - *
      • title: string - dc:title from metadata
      • - *
      • creator: string - dc:creator from metadata
      • - *
      • source: string - dc:source from metadata
      • - *
      • length: string - dcterms:extent in extent format
      • - *
      - *
    • - *
    - * - * On errors, returns an XML-RPC error response. - * The possible error codes and error message are: - *
      - *
    • 3 - Incorrect parameters passed to method: - * Wanted ... , got ... at param
    • - *
    • 801 - wrong 1st parameter, struct expected.
    • - *
    • 805 - xr_resetStorage: - * <message from lower layer>
    • - *
    - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - * @see LocStor::getAudioClip - */ -// public function xr_resetStorage($input) -// { -// list($ok, $r) = XR_LocStor::xr_getParams($input); -// if (!$ok) { -// return $r; -// } -// $res = $this->resetStorage( -// isset($r['loadSampleData']) ? $r['loadSampleData'] : TRUE, -// !(isset($r['invalidateSessionIds']) ? $r['invalidateSessionIds'] : FALSE) -// ); -// if (PEAR::isError($res)) { -// return new XML_RPC_Response(0, 805, -// "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() -// ); -// } -// return new XML_RPC_Response(XML_RPC_encode($res)); -// } - - /** - * Test XMLRPC - strupper and return given string, - * also return loginname of logged user - * - debug method only - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - public function xr_test($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'str'=>strtoupper($r['teststring']), - 'login' => Alib::GetSessLogin($r['sessid']), - 'sessid'=>$r['sessid'] - ))); - } - - /** - * Open writable URL for put method - debug method only - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - public function xr_openPut($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->bsOpenPut(); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * Close writable URL - debug method only - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - public function xr_closePut($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->bsClosePut($r['token'], $r['chsum']); - if (PEAR::isError($res)) { - return new XML_RPC_Response(0, 805, - "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode(array( - 'fname'=>$res['fname'], - 'owner'=>$res['owner'], - ))); - } - - /** - * Simple ping method - return string - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_ping($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = date("Ymd-H:i:s")." -- reply from remote node: {$r['par']}"; - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_uploadOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->uploadOpen($r['sessid'], $r['chsum']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_uploadOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * Check state of file upload - * - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_uploadCheck($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->uploadCheck($r['token']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_uploadCheck: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_uploadClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->uploadClose($r['token'], $r['trtype'], $r['pars']); - if (PEAR::isError($res)) { - $code = 803; - // Special case for duplicate file - give back - // different error code so we can display nice user message. - if ($res->getCode() == GBERR_GUNID) { - $code = 888; - } - return new XML_RPC_Response(0, $code, - "xr_uploadClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - } - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_downloadOpen($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->downloadOpen($r['sessid'], $r['trtype'], $r['pars']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_downloadOpen: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_downloadClose($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->downloadClose($r['token'], $r['trtype']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_downloadClose: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_prepareHubInitiatedTransfer($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - foreach (array('trtype'=>NULL, 'direction'=>'up', 'pars'=>array()) as $k => $dv) { - if (!isset($r[$k])) { - $r[$k] = $dv; - } - } - $res = $this->prepareHubInitiatedTransfer( - $r['target'], $r['trtype'], $r['direction'], $r['pars']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_prepareHubInitiatedTransfer: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_listHubInitiatedTransfers($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - foreach (array('target'=>NULL, 'direction'=>NULL, 'trtok'=>NULL) as $k=>$dv) { - if (!isset($r[$k])) { - $r[$k] = $dv; - } - } - $res = $this->listHubInitiatedTransfers( - $r['target'], $r['direction'], $r['trtok']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_listHubInitiatedTransfers: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - - /** - * @param XML_RPC_Message $input - * @return XML_RPC_Response - */ - function xr_setHubInitiatedTransfer($input) - { - list($ok, $r) = XR_LocStor::xr_getParams($input); - if (!$ok) { - return $r; - } - $res = $this->setHubInitiatedTransfer( - $r['target'], $r['trtok'], $r['state']); - if (PEAR::isError($res)) - return new XML_RPC_Response(0, 803, - "xr_setHubInitiatedTransfer: ".$res->getMessage(). - " ".$res->getUserInfo() - ); - return new XML_RPC_Response(XML_RPC_encode($res)); - } - - /* ==================================================== "private" methods */ - /** - * Check and convert struct of parameters - * - * @param XML_RPC_Message $input - * @return array - * Array of two items: first item is boolean, indicating - * successful decode. - * On success, the second param is an array of values. - * On failure, the second param is an XML_RPC_Response object. - */ - protected static function xr_getParams($input) - { - $p = $input->getParam(0); - if (isset($p) && ($p->scalartyp()=="struct")) { - $r = XML_RPC_decode($p); - return array(TRUE, $r); - } else { - return array(FALSE, new XML_RPC_Response(0, 801, "wrong 1st parameter, struct expected." )); - } - } - -} // class XR_LocStor - -?> \ No newline at end of file diff --git a/backend/xmlrpc/index.php b/backend/xmlrpc/index.php deleted file mode 100644 index e1ee867a4..000000000 --- a/backend/xmlrpc/index.php +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/backend/xmlrpc/put.php b/backend/xmlrpc/put.php deleted file mode 100644 index 650a5880a..000000000 --- a/backend/xmlrpc/put.php +++ /dev/null @@ -1,99 +0,0 @@ - - *
  • token : string, put token returned by appropriate - * XMLRPC call
  • - * - * - * On success, returns HTTP return code 200. - * - * On errors, returns HTTP return code >200 - * The possible error codes are: - *
      - *
    • 400 - Incorrect parameters passed to method
    • - *
    • 403 - Access denied
    • - *
    • 500 - Application error
    • - *
    - * - * @see XR_LocStor - * @package Campcaster - * @subpackage storageServer - */ - -define('USE_FLOCK', TRUE); - -require_once(dirname(__FILE__).'/../../conf.php'); -require_once('DB.php'); -require_once(dirname(__FILE__).'/../LocStor.php'); - -PEAR::setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); -$gb = new LocStor(); - -function http_error($code, $err) -{ - header("HTTP/1.1 $code"); - header("Content-type: text/plain; charset=UTF-8"); - echo "$err\r\n"; - flush(); - exit; -} - -if (preg_match("|^[0-9a-fA-F]{16}$|", $_REQUEST['token'])) { - $token = $_REQUEST['token']; -} else { - http_error(400, "Error on token parameter. ({$_REQUEST['token']})"); -} - -$tc = BasicStor::bsCheckToken($token, 'put'); -if (PEAR::isError($tc)) { - http_error(500, $ex->getMessage()); -} -if (!$tc) { - http_error(403, "put.php: Token not valid ($token)."); -} - -header("Content-type: text/plain"); - -$destfile = $CC_CONFIG['accessDir']."/{$token}"; - -/* PUT data comes in on the input stream */ -$putdata = @fopen("php://input", "r") or - http_error(500, "put.php: Can't read input"); - -/* Open a file for writing */ -$fp = @fopen($destfile, "ab") or - http_error(500, "put.php: Can't write to destination file (token=$token)"); - -if ( USE_FLOCK ) { - // lock the file - $lockres = flock($fp,LOCK_EX+LOCK_NB); - if ($lockres !== TRUE) { - http_error(409, "put.php: file locked (token=$token)"); - } -} - -/* Read the data 1 KB at a time and write to the file */ -while ($data = fread($putdata, 1024)){ - fwrite($fp, $data); -} - -if ( USE_FLOCK ) { - // unlock the file - flock($fp,LOCK_UN); -} - -/* Close the streams */ -fclose($fp); -fclose($putdata); - -header("HTTP/1.1 200"); -?> \ No newline at end of file diff --git a/backend/xmlrpc/schedulerPhpClient.php b/backend/xmlrpc/schedulerPhpClient.php deleted file mode 100644 index d3fce621a..000000000 --- a/backend/xmlrpc/schedulerPhpClient.php +++ /dev/null @@ -1,511 +0,0 @@ - - *
  • m
  • full method name (include optional prefix) - *
  • p
  • array of input parameter names - *
  • t
  • array of input parameter types - *
  • r
  • array of result element names (not used there at present) - *
  • e
  • array of error codes/messages (not used there at present) - * - */ -$mdefs = array( - "listMethods" => array('m'=>"system.listMethods", 'p'=>NULL, 't'=>NULL), - "AddAudioClipToPlaylistMethod" => array( - 'm'=>'addAudioClipToPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/, 'clipStart'/*int*/, 'clipEnd'/*int*/, 'clipLength'/*int*/), - 't'=>array('string', 'string', 'string', 'int', 'int', 'int', 'int'), - 'r'=>array('playlistElementId'/*string*/), - 'e'=>array( - '301'=>'invalid argument format', - '302'=>'missing playlist ID argument', - '303'=>'missing audio clip ID argument', - '304'=>'missing relative offset argument', - '305'=>'playlist not found', - '306'=>'playlist has not been opened for editing', - '307'=>'audio clip does not exist', - '308'=>'two audio clips at the same relative offset', - '320'=>'missing session ID argument', - ) - ), - "CreatePlaylistMethod" => array( - 'm'=>'createPlaylist', - 'p'=>array('sessionId'/*string*/), - 't'=>array('string'), - 'r'=>array('playlist'/*string*/), - 'e'=>array( - '201'=>'invalid argument format', - '202'=>'could not create playlist', - '220'=>'missing session ID argument', - ) - ), - "DeletePlaylistMethod" => array( - 'm'=>'deletePlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array(), - 'e'=>array( - '901'=>'invalid argument format', - '902'=>'missing playlist ID argument', - '903'=>'playlist not found', - '904'=>'playlist is locked', - '905'=>'playlist could not be deleted', - '920'=>'missing session ID argument', - ) - ), - "DisplayAudioClipMethod" => array( - 'm'=>'displayAudioClip', - 'p'=>array('sessionId'/*string*/, 'audioClipId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('audioClip'/*string*/), - 'e'=>array( - '601'=>'invalid argument format', - '602'=>'argument is not an audio clip ID', - '603'=>'audio clip not found', - '620'=>'missing session ID argument', - ) - ), - "DisplayAudioClipsMethod" => array( - 'm'=>'displayAudioClips', - 'p'=>array('sessionId'/*string*/), - 't'=>array('string'), - 'r'=>array(array('audioClip'/*string*/)), - 'e'=>array( - '1801'=>'invalid argument format', - '1802'=>'XML-RPC error', - '1820'=>'missing session ID argument', - ) - ), - "DisplayPlaylistMethod" => array( - 'm'=>'displayPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('playlist'/*string*/), - 'e'=>array( - '1001'=>'invalid argument format', - '1002'=>'argument is not a playlist ID', - '1003'=>'playlist not found', - '1020'=>'missing session ID argument', - ) - ), - "DisplayPlaylistsMethod" => array( - 'm'=>'displayPlaylists', - 'p'=>array('sessionId'/*string*/), - 't'=>array('string'), - 'r'=>array(array('playlist'/*string*/)), - 'e'=>array( - '1701'=>'invalid argument format', - '1702'=>'XML-RPC error', - '1720'=>'missing session ID argument', - ) - ), - "DisplayScheduleMethod" => array( - 'm'=>'displaySchedule', - 'p'=>array('sessionId'/*string*/, 'from'/*datetime*/, 'to'/*datetime*/), - 't'=>array('string', 'dateTime.iso8601', 'dateTime.iso8601'), - 'r'=>array(array('id'/*int*/, 'playlistId'/*string*/, 'start'/*datetime*/, 'end'/*datetime*/)), - 'e'=>array( - '1101'=>'invalid argument format', - '1102'=>"missing or invalid 'from' argument", - '1103'=>"missing or invalid 'to' argument", - '1120'=>'missing session ID argument', - ) - ), - "GeneratePlayReportMethod" => array( - 'm'=>'generatePlayReport', - 'p'=>array('sessionId'/*string*/, 'from'/*datetime*/, 'to'/*datetime*/), - 't'=>array('string', 'dateTime.iso8601', 'dateTime.iso8601'), - 'r'=>array(array('audioClipId'/*string*/, 'timestamp'/*datetime*/)), - 'e'=>array( - '1501'=>'invalid argument format', - '1502'=>"missing or invalid 'from' argument", - '1503'=>"missing or invalid 'to' argument", - '1520'=>'missing session ID argument', - ) - ), - "GetSchedulerTimeMethod" => array( - 'm'=>'getSchedulerTime', - 'p'=>array(), - 't'=>array(), - 'r'=>array('schedulerTime'/*datetime*/), - 'e'=>array( -) - ), - "GetVersionMethod" => array( - 'm'=>'getVersion', - 'p'=>array(), - 't'=>array(), - 'r'=>array('version'/*string*/), - 'e'=>array() - ), - "LoginMethod" => array( - 'm'=>'login', - 'p'=>array('login'/*string*/, 'password'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('sessionId'/*string*/), - 'e'=>array( - '2001'=>'invalid argument format', - '2002'=>'missing login argument', - '2003'=>'missing password argument', - '2004'=>'the authentication server reported an error', - ) - ), - "LogoutMethod" => array( - 'm'=>'logout', - 'p'=>array('sessionId'/*string*/), - 't'=>array('string'), - 'r'=>array(), - 'e'=>array( - '2101'=>'invalid argument format', - '2120'=>'missing session ID argument', - '2104'=>'the authentication server reported an error', - ) - ), - "OpenPlaylistForEditingMethod" => array( - 'm'=>'openPlaylistForEditing', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('playlist'/*string*/), - 'e'=>array( - '101'=>'invalid argument format', - '102'=>'argument is not a playlist ID', - '104'=>'could not open playlist for editing', - '120'=>'missing session ID argument', - ) - ), - "RemoveAudioClipFromPlaylistMethod" => array( - 'm'=>'removeAudioClipFromPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playlistElementId'/*string*/), - 't'=>array('string', 'string', 'string'), - 'r'=>array(), - 'e'=>array( - '401'=>'invalid argument format', - '402'=>'missing playlist ID argument', - '403'=>'missing relative offset argument', - '404'=>'playlist does not exist', - '405'=>'playlist has not been opened for editing', - '406'=>'no audio clip at the specified relative offset', - '420'=>'missing session ID argument', - ) - ), - "RemoveFromScheduleMethod" => array( - 'm'=>'removeFromSchedule', - 'p'=>array('sessionId'/*string*/, 'scheduleEntryId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array(), - 'e'=>array( - '1201'=>'invalid argument format', - '1202'=>'missing schedule entry ID argument', - '1203'=>'schedule entry not found', - '1220'=>'missing session ID argument', - ) - ), - "RescheduleMethod" => array( - 'm'=>'reschedule', - 'p'=>array('sessionId'/*string*/, 'scheduleEntryId'/*string*/, 'playtime'/*datetime*/), - 't'=>array('string', 'string', 'dateTime.iso8601'), - 'r'=>array(), - 'e'=>array( - '1301'=>'invalid argument format', - '1302'=>'missing schedule entry ID argument', - '1303'=>'missing playtime argument', - '1304'=>'schedule entry not found', - '1305'=>'could not reschedule entry', - '1320'=>'missing session ID argument', - ) - ), -// "ResetStorageMethod" => array( -// 'm'=>'resetStorage', -// 'p'=>array(), -// 't'=>array(), -// 'r'=>array(), -// 'e'=>array('3001'=>'storage client reported an error'), -// ), - "RevertEditedPlaylistMethod" => array( - 'm'=>'revertEditedPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array(), - 'e'=>array( - '801'=>'invalid argument format', - '802'=>'argument is not a playlist ID', - '803'=>'playlist not found', - '804'=>'could not revert playlist', - '820'=>'missing session ID argument', - ) - ), - "SavePlaylistMethod" => array( - 'm'=>'savePlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array(), - 'e'=>array( - '701'=>'invalid argument format', - '702'=>'argument is not a playlist ID', - '703'=>'playlist not found', - '705'=>'could not save playlist', - '720'=>'missing session ID argument', - ) - ), - "UpdateFadeInFadeOutMethod" => array( - 'm'=>'updateFadeInFadeOut', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playlistElementId'/*string*/, 'fadeIn'/*int*/, 'fadeOut'/*int*/), - 't'=>array('string', 'string', 'string', 'int', 'int'), - 'r'=>array(), - 'e'=>array( - '1601'=>'invalid argument format', - '1602'=>'missing playlist ID argument', - '1603'=>'missing playlist element ID argument', - '1604'=>'missing fade in argument', - '1605'=>'missing fade out argument', - '1606'=>'playlist does not exist', - '1607'=>'playlist has not been opened for editing', - '1608'=>'error executing setFadeInfo() method', - '1620'=>'missing session ID argument', - ) - ), - "UploadPlaylistMethod" => array( - 'm'=>'uploadPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playtime'/*datetime*/), - 't'=>array('string', 'string', 'dateTime.iso8601'), - 'r'=>array('scheduleEntryId'/*string*/), - 'e'=>array( - '1401'=>'invalid argument format', - '1402'=>'missing playlist ID argument', - '1403'=>'missing playtime argument', - '1404'=>'playlist not found', - '1405'=>'timeframe not available', - '1406'=>'could not schedule playlist', - '1420'=>'missing session ID argument', - ) - ), - "ValidatePlaylistMethod" => array( - 'm'=>'validatePlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('valid'/*bool*/), - 'e'=>array( - '501'=>'invalid argument format', - '502'=>'missing playlist ID argument', - '503'=>'playlist does not exist', - '504'=>'playlist has not been opened for editing', - '520'=>'missing session ID argument', - ) - ), - "LoginGB" => array( - 'm'=>'locstor.login', - 'p'=>array('login'/*string*/, 'pass'/*string*/), - 't'=>array('string', 'string'), - 'r'=>array('sessid'/*string*/), - 'e'=>array( - '2001'=>'invalid argument format', - '2002'=>'missing login argument', - '2003'=>'missing password argument', - '2004'=>'the authentication server reported an error', - ) - ), - "LogoutGB" => array( - 'm'=>'locstor.logout', - 'p'=>array('sessid'/*string*/), - 't'=>array('string'), - 'r'=>array('status'/*boolean*/), - 'e'=>array( - '2001'=>'invalid argument format', - '2002'=>'missing login argument', - '2003'=>'missing password argument', - '2004'=>'the authentication server reported an error', - ) - ), -); - -/* ======================================================== class definitions */ - -class SchedulerPhpClient { - /** - * Array with methods description - * @var array - */ - private $mdefs = array(); - - /** - * XMLRPC client object reference - */ - private $client = NULL; - - /** - * Verbosity flag - */ - private $verbose = FALSE; - - /** - * XMLRPC debug flag - */ - private $debug = 0; - - /** - * Constructor - please DON'T CALL IT, use factory method instead - * - * @param DB $dbc - * @param array $mdefs - * hash array with methods description - * @param array $config - * hash array with configuration - * @param int $debug - * XMLRPC debug flag - * @param boolean $verbose - * verbosity flag - */ - public function __construct($mdefs, $debug=0, $verbose=FALSE) - { - global $CC_DBC, $CC_CONFIG; - $this->mdefs = $mdefs; - $this->debug = $debug; - $this->verbose = $verbose; - $confPrefix = "scheduler"; - //$confPrefix = "storage"; - $serverPath = - "http://{$CC_CONFIG["{$confPrefix}UrlHost"]}:{$CC_CONFIG["{$confPrefix}UrlPort"]}". - "{$CC_CONFIG["{$confPrefix}UrlPath"]}/{$CC_CONFIG["{$confPrefix}XMLRPC"]}"; - //$serverPath = "http://localhost:80/campcasterStorageServerCVS/xmlrpc/xrLocStor.php"; - if ($this->verbose) { - echo "serverPath: $serverPath\n"; - } - $url = parse_url($serverPath); - $this->client = new XML_RPC_Client($url['path'], $url['host'], $url['port']); - } - - - /** - * Factory, create object instance - * - * In fact it doesn't create instance of SchedulerPhpClient, but - * dynamically extend this class with set of methods based on $mdefs array - * (using eval function) and instantiate resulting class - * SchedulerPhpClientCore instead. - * Each new method in this subclass accepts parameters according to $mdefs - * array, call wrapper callMethod(methodname, parameters) and return its - * result. - * - * @param array $mdefs - * hash array with methods description - * @param int $debug - * XMLRPC debug flag - * @param boolean $verbose - * verbosity flag - * @return SchedulerPhpClientCore - */ - function &factory($mdefs, $debug=0, $verbose=FALSE) - { - global $CC_DBC, $CC_CONFIG; - $f = ''; - foreach ($mdefs as $fn => $farr) { - $f .= - ' function '.$fn.'(){'."\n". - ' $pars = func_get_args();'."\n". - ' $r = $this->callMethod("'.$fn.'", $pars);'."\n". - ' return $r;'."\n". - ' }'."\n"; - } - $e = - "class SchedulerPhpClientCore extends SchedulerPhpClient{\n". - "$f\n". - "}\n"; -# echo $e; - if (FALSE === eval($e)) { - return $CC_DBC->raiseError("Eval failed"); - } - $spc = new SchedulerPhpClientCore($mdefs, $debug, $verbose); - return $spc; - } - - - /** - * XMLRPC methods wrapper - * Encode XMLRPC request message, send it, receive and decode response. - * - * @param string $method - * method name - * @param array $gettedPars - * returned by func_get_args() in called method - * @return array - * PHP hash with response - */ - function callMethod($method, $gettedPars) - { - $parr = array(); - $XML_RPC_val = new XML_RPC_Value; - foreach ($this->mdefs[$method]['p'] as $i => $p) { - $parr[$p] = new XML_RPC_Value; - $parr[$p]->addScalar($gettedPars[$i], $this->mdefs[$method]['t'][$i]); - } - $XML_RPC_val->addStruct($parr); - $fullmethod = $this->mdefs[$method]['m']; - $msg = new XML_RPC_Message($fullmethod, array($XML_RPC_val)); - if ($this->verbose) { - echo "parr:\n"; - var_dump($parr); - echo "message:\n"; - echo $msg->serialize()."\n"; - } - $this->client->setDebug($this->debug); - $res = $this->client->send($msg); - if ($res->faultCode() > 0) { - return PEAR::raiseError( - "SchedulerPhpClient::$method:".$res->faultString()." ". - $res->faultCode()."\n", $res->faultCode(), - PEAR_ERROR_RETURN - ); - } - if ($this->verbose) { - echo "result:\n"; - echo $res->serialize(); - } - $val = $res->value(); - $resp = XML_RPC_decode($res->value()); - return $resp; - } - -} // class SchedulerPhpClient - -/* ======================================================== class definitions */ - -/** - * Example of use: - * - * / - - -// db object handling: -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); -$CC_DBC->setErrorHandling(PEAR_ERROR_RETURN); - -// scheduler client instantiation: -$spc = SchedulerPhpClient::factory($mdefs); -#$spc = SchedulerPhpClient::factory($mdefs, 0, TRUE); -if(PEAR::isError($spc)){ echo $spc->getMessage."\n"; exit; } - -// call of chosen function by name according to key values in $mdefs array: -// (for testing on storageServer XMLRPC I've changes confPrefix in -// SchedulerPhpClient constructor from 'scheduler' to 'storage' value) -#$r = $spc->LoginGB('root', 'q'); var_dump($r); -#$r = $spc->LogoutGB(''); var_dump($r); - -#$r = $spc->DisplayScheduleMethod($this->Base->sessid, '2005-01-01 00:00:00.000000', '2005-02-01 00:00:00.000000'); var_dump($r); -#$r = $spc->DisplayScheduleMethod('dummySessionId2-1681692777', '2005-01-01 00:00:00.000000', '2005-02-01 00:00:00.000000'); var_dump($r); -$r = $spc->DisplayScheduleMethod($this->Base->sessid, '20040101T00:00:00', '20050401T00:00:00'); var_dump($r); -#$r = $spc->LoginMethod('root', 'q'); var_dump($r); -#$r = $spc->LogoutMethod('dummySessionId3-1714636915'); var_dump($r); -#$r = $spc->listMethods(); var_dump($r); -#$r = $spc->GetSchedulerTimeMethod(); var_dump($r); -================= */ - -?> \ No newline at end of file diff --git a/backend/xmlrpc/simpleGet.php b/backend/xmlrpc/simpleGet.php deleted file mode 100644 index ebb0cf8dc..000000000 --- a/backend/xmlrpc/simpleGet.php +++ /dev/null @@ -1,128 +0,0 @@ - - *
  • sessid : string, session ID
  • - *
  • id : string, global unique ID of requested file
  • - * - * - * On success, returns HTTP return code 200 and requested file. - * - * On errors, returns HTTP return code >200 - * The possible error codes are: - *
      - *
    • 400 - Incorrect parameters passed to method
    • - *
    • 403 - Access denied
    • - *
    • 404 - File not found
    • - *
    • 500 - Application error
    • - *
    - * - */ - -require_once(dirname(__FILE__).'/../../conf.php'); -require_once('DB.php'); -require_once(dirname(__FILE__).'/../LocStor.php'); -require_once(dirname(__FILE__).'/../MetaData.php'); - -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -$locStor = new LocStor(); - -function http_error($code, $err) -{ - header("HTTP/1.1 $code"); - header("Content-type: text/plain; charset=UTF-8"); - echo "$err\r\n"; - exit; -} - -/** - * This function encodes an filename to - * be transferred via HTTP header. - * - * @param string $p_string utf8 filename - * @return string HTTP header encoded filename - */ -function sg_2hexstring($p_string) -{ - for ($x=0; $x < strlen($p_string); $x++) { - $return .= '%' . bin2hex($p_string[$x]); - } - return $return; -} - -// parameter checking: -if (preg_match("|^[0-9a-fA-F]{32}$|", $_REQUEST['sessid'])) { - $sessid = $_REQUEST['sessid']; -} else { - http_error(400, "Error on sessid parameter. ({$_REQUEST['sessid']})"); -} -if (preg_match("|^[0-9a-fA-F]{16}$|", $_REQUEST['id'])) { - $gunid = $_REQUEST['id']; -} else { - http_error(400, "Error on id parameter. ({$_REQUEST['id']})"); -} - -// stored file recall: -$ac = StoredFile::RecallByGunid($gunid); -if (PEAR::isError($ac)) { - switch ($ac->getCode()) { - case GBERR_DENY: - http_error(403, "403 ".$ac->getMessage()); - case GBERR_FILENEX: - case GBERR_FOBJNEX: - http_error(404, "404 File not found"); - default: - http_error(500, "500 ".$ac->getMessage()); - } -} -$lid = BasicStor::IdFromGunid($gunid); -if (PEAR::isError($lid)) { - http_error(500, $lid->getMessage()); -} -if (($res = BasicStor::Authorize('read', $lid, $sessid)) !== TRUE) { - http_error(403, "403 Access denied"); -} -$ftype = BasicStor::GetObjType($lid); -if (PEAR::isError($ftype)) { - http_error(500, $ftype->getMessage()); -} -switch ($ftype) { - case "audioclip": - $realFname = $ac->getRealFileName(); - $mime = $ac->getMime(); - $md = new MetaData($ac->getGunId(), null); - $fileName = $md->getMetadataValue('dc:title').'.'.$ac->getFileExtension(); - header("Content-type: $mime"); - header("Content-length: ".filesize($realFname)); - header("Content-Disposition: attachment; filename*=".sg_2hexstring($fileName).";"); - readfile($realFname); - break; - case "webstream": - $url = $locStor->bsGetMetadataValue($lid, 'ls:url'); - if (empty($url)) { - http_error(500, "Unable to get ls:url value"); - } - $txt = "Location: $url"; - header($txt); - // echo "$txt\n"; - break; - case "playlist"; - // $md = $locStor->bsGetMetadata($ac->getId(), $sessid); - $md = $locStor->getAudioClip($sessid, $gunid); - // header("Content-type: text/xml"); - header("Content-type: application/smil"); - echo $md; - break; - default: - // var_dump($ftype); - http_error(500, "500 Unknown ftype ($ftype)"); -} -?> \ No newline at end of file diff --git a/backend/xmlrpc/urldecode b/backend/xmlrpc/urldecode deleted file mode 100755 index 172c8f73c..000000000 --- a/backend/xmlrpc/urldecode +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/php -q - \ No newline at end of file diff --git a/backend/xmlrpc/xrLocStor.php b/backend/xmlrpc/xrLocStor.php deleted file mode 100644 index 5408a389e..000000000 --- a/backend/xmlrpc/xrLocStor.php +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -faultCode -804 - - -faultString -"); -ini_set("error_append_string", " - - - - -"); -header("Content-type: text/xml"); - -/* ================================================================= includes */ -require_once(dirname(__FILE__).'/../../conf.php'); -require_once('DB.php'); -require_once("XML/RPC/Server.php"); -require_once('XR_LocStor.php'); - -/* ============================================ setting default error handler */ -function errHndl($errno, $errmsg, $filename, $linenum, $vars) -{ - switch ($errno) { - case E_WARNING: - case E_NOTICE: - case E_USER_WARNING: - case E_USER_NOTICE: - return; - break; - default: - $xr = new XML_RPC_Response(0, 805, - htmlspecialchars("ERROR:xrLocStor: $errno $errmsg ($filename:$linenum)")); - header("Content-type: text/xml"); - echo $xr->serialize(); - exit($errno); - } -} -$old_error_handler = set_error_handler("errHndl", E_ALL); - -/* ============================================================= runable code */ -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -if (PEAR::isError($CC_DBC)) { - trigger_error("DB::connect: ".$CC_DBC->getMessage()." ".$CC_DBC->getUserInfo(),E_USER_ERROR); -} -$CC_DBC->setErrorHandling(PEAR_ERROR_RETURN); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -$locStor = new XR_LocStor(); - -$methods = array( - 'test' => 'Tests toupper and checks sessid, params: '. - 'teststring, sessid.', - 'getVersion' => 'Get version of Campcaster.', -// 'authenticate' => 'Checks authentication.', - 'login' => 'Login to storage.', - 'logout' => 'Logout from storage.', - 'existsAudioClip' => 'Checks if an audio clip with the specified '. - 'id is stored in local storage.', - 'storeAudioClipOpen' => 'Open channel to store a new audio clip '. - 'or replace an existing one.', - 'storeAudioClipClose' => 'Close channel to store a new audio clip'. - ' or replace an existing one.', - 'downloadRawAudioDataOpen'=> 'Create and return downloadable URL'. - 'for audio file', - 'downloadRawAudioDataClose'=>'Discard downloadable URL for audio file', - 'downloadMetadataOpen' => 'Create and return downloadable URL'. - 'for metadata', - 'downloadMetadataClose' => 'Discard downloadable URL for metadata', - 'openPut' => 'openPut', - 'closePut' => 'closePut', - 'deleteAudioClip' => 'Delete an existing Audio clip.', - 'updateAudioClipMetadata' => 'Update the metadata of an Audio clip '. - 'stored in Local storage.', - 'searchMetadata' => 'Search through the metadata of stored '. - 'files, return all matching clip ids.', - 'browseCategory' =>'Return values of specified metadata category.', - 'accessRawAudioData' => 'Get access to raw audio data.', - 'releaseRawAudioData' => 'Release access to raw audio data.', - 'getAudioClip' => 'Return the contents of an Audio clip.', -// 'resetStorage' => 'Reset storageServer for debugging.', - 'storeWebstream' => 'Store audio stream identified by URL', - - 'createPlaylist' => 'Create a new Playlist metafile.', - 'editPlaylist' => 'Open a Playlist metafile for editing.', - 'savePlaylist' => 'Save a Playlist metafile.', - 'revertEditedPlaylist' => 'RollBack playlist changes to the locked state.', - 'deletePlaylist' => 'Delete a Playlist metafile.', - 'accessPlaylist' => 'Open readable URL to a Playlist metafile.', - 'releasePlaylist' => 'Release readable URL from accessPlaylist.', - 'existsPlaylist' => 'Check whether a Playlist exists.', - 'playlistIsAvailable' => 'Check whether a Playlist is available '. - 'for editing.', - 'exportPlaylistOpen' => 'Create a tarfile with playlist export.', - 'exportPlaylistClose' => 'Close playlist export.', - 'importPlaylistOpen' => 'Open writable handle for playlist import.', - 'importPlaylistClose' => 'Close import-handle and import playlist.', - - 'renderPlaylistToFileOpen' => 'Render playlist to ogg file (open handle)', - 'renderPlaylistToFileCheck' => 'Render playlist to ogg file (check results)', - 'renderPlaylistToFileClose' => 'Render playlist to ogg file (close handle)', - - 'renderPlaylistToStorageOpen' => 'Render playlist to storage media clip (open handle)', - 'renderPlaylistToStorageCheck' => 'Render playlist to storage media clip (check results)', - - 'renderPlaylistToRSSOpen' => 'Render playlist to RSS file (open handle)', - 'renderPlaylistToRSSCheck' => 'Render playlist to RSS file (check results)', - 'renderPlaylistToRSSClose' => 'Render playlist to RSS file (close handle)', - - 'createBackupOpen' => 'Create backup of storage (open handle)', - 'createBackupCheck' => 'Create backup of storage (check results)', - 'createBackupClose' => 'Create backup of storage (close handle)', - - 'restoreBackupOpen' => 'Restore a backup file (open handle)', - 'restoreBackupClosePut' => 'Restore a backup file (close PUT handle)', - 'restoreBackupCheck' => 'Restore a backup file (check results)', - 'restoreBackupClose' => 'Restore a backup file (close handle)', - - 'loadPref' => 'Load user preference value.', - 'savePref' => 'Save user preference value.', - 'delPref' => 'Delete user preference record.', - 'loadGroupPref' => 'Read group preference record.', - 'saveGroupPref' => 'Delete user preference record.', - - 'getTransportInfo' => 'Common "check" method and info getter for transports', - 'turnOnOffTransports' => 'Turn transports on/off, optionaly return current state', - 'doTransportAction' => 'Pause, resume or cancel transport', - 'uploadFile2Hub' => 'Open async file transfer from local storageServer to network hub', - 'getHubInitiatedTransfers' => 'Get list of prepared transfers initiated by hub', - 'startHubInitiatedTransfer' => 'Start of download initiated by hub', - 'upload2Hub' => 'Start upload of audioclip or playlist from local storageServer to hub', - 'downloadFromHub' => 'Start download of audioclip or playlist from hub to local storageServer', -// 'globalSearch' => 'Start search job on network hub', -// 'getSearchResults' => 'Get results from search job on network hub', - - 'uploadOpen' => 'Open file-layer upload', - 'uploadCheck' => 'Check the checksum of uploaded file', - 'uploadClose' => 'Close file-layer upload', - 'downloadOpen' => 'Open file-layer download', -// 'downloadCheck' => 'Check the checksum of downloaded file', - 'downloadClose' => 'Close file-layer download', - 'prepareHubInitiatedTransfer' => 'Prepare hub initiated transfer', - 'listHubInitiatedTransfers' => 'List hub initiated transfers', - 'setHubInitiatedTransfer' => 'Set state of hub initiated transfers', - 'ping' => 'Echo request', -); - -$defs = array(); -foreach ($methods as $method => $description) { - $defs["locstor.$method"] = array( - "function" => array(&$locStor, "xr_$method"), - // NOTE: the way this signature is set up, every function must take at least one parameter! - "signature" => array( - array($GLOBALS['XML_RPC_Struct'], $GLOBALS['XML_RPC_Struct']) - ), - "docstring" => $description - ); -} - -$s = new XML_RPC_Server($defs); - -?> \ No newline at end of file diff --git a/backend/xmlrpc/xr_cli_test.php b/backend/xmlrpc/xr_cli_test.php deleted file mode 100644 index c282be12b..000000000 --- a/backend/xmlrpc/xr_cli_test.php +++ /dev/null @@ -1,368 +0,0 @@ -debug = 1; - echo "ServerPath: $serverPath\n"; - echo "Host: {$url['host']}, path: {$url['path']}\n"; - echo "Method: $method\n"; - echo "Parameters:\n"; - //var_dump($pars); -} - -$infos = array( - "listMethods" => array('m'=>"system.listMethods", 'p'=>NULL), - "methodHelp" => array('m'=>"system.methodHelp", 'p'=>0), - "methodSignature" => array('m'=>"system.methodSignature", 'p'=>0), - "test" => array('m'=>"locstor.test", 'p'=>array('sessid', 'teststring')), - "ping" => array('m'=>"locstor.ping", 'p'=>array("par")), - "getVersion" => array('m'=>"locstor.getVersion", 'p'=>array("str"), 'r'=>'version'), - "authenticate" => array('m'=>"locstor.authenticate", 'p'=>array('login', 'pass'), 'r'=>'authenticate'), - "login" => array('m'=>"locstor.login", 'p'=>array('login', 'pass'), 'r'=>'sessid'), - "logout" => array('m'=>"locstor.logout", 'p'=>array('sessid'), 'r'=>'status'), - "storeAudioClipOpen" => array('m'=>"locstor.storeAudioClipOpen", - 'p'=>array('sessid', 'gunid', 'metadata', 'fname', 'chsum'), - 'r'=>array('url', 'token') - ), - "storeAudioClipClose" => array('m'=>"locstor.storeAudioClipClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - "accessRawAudioData" => array('m'=>"locstor.accessRawAudioData", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "releaseRawAudioData" => array('m'=>"locstor.releaseRawAudioData", - 'p'=>array('token'), 'r'=>'status'), - "downloadRawAudioDataOpen" => - array('m'=>"locstor.downloadRawAudioDataOpen", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "downloadRawAudioDataClose" => - array('m'=>"locstor.downloadRawAudioDataClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - "downloadMetadataOpen" => array('m'=>"locstor.downloadMetadataOpen", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "downloadMetadataClose" => array('m'=>"locstor.downloadMetadataClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - - "deleteAudioClip" => - array('m'=>"locstor.deleteAudioClip", - 'p'=>array('sessid', 'gunid', 'forced'), 'r'=>'status'), - "existsAudioClip" => array('m'=>"locstor.existsAudioClip", - 'p'=>array('sessid', 'gunid'), 'r'=>'exists'), - "getAudioClip" => array('m'=>"locstor.getAudioClip", - 'p'=>array('sessid', 'gunid'), 'r'=>'metadata'), - "updateAudioClipMetadata" => array('m'=>"locstor.updateAudioClipMetadata", - 'p'=>array('sessid', 'gunid', 'metadata'), 'r'=>'status'), - "searchMetadata" => array('m'=>"locstor.searchMetadata", 'p'=>NULL), - "browseCategory" => array('m'=>"locstor.browseCategory", 'p'=>NULL), -// "resetStorage" => array('m'=>"locstor.resetStorage", -// 'p'=>array()), -# 'p'=>array('loadSampleData', 'invalidateSessionIds')), - "storeWebstream" => array('m'=>"locstor.storeWebstream", - 'p'=>array('sessid', 'gunid', 'metadata', 'fname', 'url'), - 'r'=>array('gunid') - ), - - "createPlaylist" => array('m'=>"locstor.createPlaylist", - 'p'=>array('sessid', 'plid', 'fname'), 'r'=>'plid'), - "editPlaylist" => array('m'=>"locstor.editPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>array('url', 'token')), - "savePlaylist" => array('m'=>"locstor.savePlaylist", - 'p'=>array('sessid', 'token', 'newPlaylist'), 'r'=>'plid'), - "revertEditedPlaylist" => array('m'=>"locstor.revertEditedPlaylist", - 'p'=>array('sessid', 'token'), 'r'=>'plid'), - "deletePlaylist" => array('m'=>"locstor.deletePlaylist", - 'p'=>array('sessid', 'plid', 'forced'), 'r'=>'status'), - "accessPlaylist" => array('m'=>"locstor.accessPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>array('url', 'token')), - "releasePlaylist" => array('m'=>"locstor.releasePlaylist", - 'p'=>array('token'), 'r'=>'plid'), - "existsPlaylist" => array('m'=>"locstor.existsPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>'exists'), - "playlistIsAvailable" => array('m'=>"locstor.playlistIsAvailable", - 'p'=>array('sessid', 'plid'), 'r'=>array('available', 'ownerid', 'ownerlogin')), - - "exportPlaylistOpen" => array('m'=>"locstor.exportPlaylistOpen", - 'p'=>array('sessid', 'plids', 'type', 'standalone'), - 'r'=>array('url', 'token')), - "exportPlaylistClose" => array('m'=>"locstor.exportPlaylistClose", - 'p'=>array('token'), 'r'=>array('status')), - "importPlaylistOpen" => array('m'=>"locstor.importPlaylistOpen", - 'p'=>array('sessid', 'chsum'), 'r'=>array('url', 'token')), - "importPlaylistClose" => array('m'=>"locstor.importPlaylistClose", - 'p'=>array('token'), 'r'=>array('gunid')), - - "renderPlaylistToFileOpen" => array('m'=>"locstor.renderPlaylistToFileOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToFileCheck" => array('m'=>"locstor.renderPlaylistToFileCheck", - 'p'=>array('token'), 'r'=>array('status', 'url')), - "renderPlaylistToFileClose" => array('m'=>"locstor.renderPlaylistToFileClose", - 'p'=>array('token'), 'r'=>array('status')), - "renderPlaylistToStorageOpen" => array('m'=>"locstor.renderPlaylistToStorageOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToStorageCheck" => array('m'=>"locstor.renderPlaylistToStorageCheck", - 'p'=>array('token'), 'r'=>array('status', 'gunid')), - "renderPlaylistToRSSOpen" => array('m'=>"locstor.renderPlaylistToRSSOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToRSSCheck" => array('m'=>"locstor.renderPlaylistToRSSCheck", - 'p'=>array('token'), 'r'=>array('status', 'url')), - "renderPlaylistToRSSClose" => array('m'=>"locstor.renderPlaylistToRSSClose", - 'p'=>array('token'), 'r'=>array('status')), - - "loadPref" => array('m'=>"locstor.loadPref", - 'p'=>array('sessid', 'key'), 'r'=>'value'), - "savePref" => array('m'=>"locstor.savePref", - 'p'=>array('sessid', 'key', 'value'), 'r'=>'status'), - "delPref" => array('m'=>"locstor.delPref", - 'p'=>array('sessid', 'key'), 'r'=>'status'), - "loadGroupPref" => array('m'=>"locstor.loadGroupPref", - 'p'=>array('sessid', 'group', 'key'), 'r'=>'value'), - "saveGroupPref" => array('m'=>"locstor.saveGroupPref", - 'p'=>array('sessid', 'group', 'key', 'value'), 'r'=>'status'), - - "getTransportInfo" => array('m'=>"locstor.getTransportInfo", - 'p'=>array('trtok'), - 'r'=>array('state', 'realsize', 'expectedsize', 'realsum', 'expectedsum')), - "turnOnOffTransports" => array('m'=>"locstor.turnOnOffTransports", - 'p'=>array('sessid', 'onOff'), 'r'=>array('state')), - "doTransportAction" => array('m'=>"locstor.doTransportAction", - 'p'=>array('sessid', 'trtok', 'action'), 'r'=>array('state')), - "uploadFile2Hub" => array('m'=>"locstor.uploadFile2Hub", - 'p'=>array('sessid', 'filePath'), 'r'=>array('trtok')), - "getHubInitiatedTransfers" => array('m'=>"locstor.getHubInitiatedTransfers", - 'p'=>array('sessid'), 'r'=>array()), - "startHubInitiatedTransfer" => array('m'=>"locstor.startHubInitiatedTransfer", - 'p'=>array('trtok'), 'r'=>array()), - "upload2Hub" => array('m'=>"locstor.upload2Hub", - 'p'=>array('sessid', 'gunid'), 'r'=>array('trtok')), - "downloadFromHub" => array('m'=>"locstor.downloadFromHub", - 'p'=>array('sessid', 'gunid'), 'r'=>array('trtok')), -// "globalSearch" => array('m'=>"locstor.globalSearch", -// 'p'=>array('sessid', 'criteria'), 'r'=>array('trtok')), -// "getSearchResults" => array('m'=>"locstor.getSearchResults", -// 'p'=>array('trtok')), - - "createBackupOpen" => array('m'=>"locstor.createBackupOpen", - 'p'=>array('sessid', 'criteria'), 'r'=>array('token')), - "createBackupCheck" => array('m'=>"locstor.createBackupCheck", -# 'p'=>array('token'), 'r'=>array('status', 'url', 'metafile', 'faultString')), - 'p'=>array('token'), 'r'=>array('status', 'url', 'tmpfile')), - "createBackupClose" => array('m'=>"locstor.createBackupClose", - 'p'=>array('token'), 'r'=>array('status')), - "restoreBackupOpen" => array('m'=>"locstor.restoreBackupOpen", - 'p'=>array('sessid', 'chsum'), 'r'=>array('url', 'token')), - "restoreBackupClosePut" => array('m'=>"locstor.restoreBackupClosePut", - 'p'=>array('sessid', 'token'), 'r'=>array('token')), - "restoreBackupCheck" => array('m'=>"locstor.restoreBackupCheck", - 'p'=>array('token'), 'r'=>array('status', 'faultString')), - "restoreBackupClose" => array('m'=>"locstor.restoreBackupClose", - 'p'=>array('token'), 'r'=>array('status')), - -/* - "uploadToArchive" => array('m'=>"locstor.uploadToArchive", - 'p'=>array('sessid', 'gunid'), 'r'=>'trtok'), - "downloadFromArchive" => array('m'=>"locstor.downloadFromArchive", - 'p'=>array('sessid', 'gunid'), 'r'=>'trtok'), -*/ - - "openPut" => array('m'=>"locstor.openPut", 'p'=>array()), - "closePut" => array('m'=>"locstor.closePut", 'p'=>array()), -); - - -switch ($method) { - case "searchMetadata": -// case "globalSearch": - case "createBackupOpen": - $parr = array( - 'sessid'=>$pars[0], - 'criteria'=>array( - 'filetype'=>'audioclip', - 'operator'=>'and', - 'limit'=> 0, - 'offset'=> 0, - 'conditions'=>array( - array('cat'=>$pars[1], 'op'=>'partial', 'val'=>$pars[2]) - ) - ), - ); - break; - case "browseCategory": - $parr = array( - 'sessid'=>$pars[0], - 'category'=>$pars[1], - 'criteria'=>array( - 'filetype'=>'audioclip', - 'operator'=>'and', - 'limit'=> 0, - 'offset'=> 0, - 'conditions'=>array( - array('cat'=>$pars[2], 'op'=>'partial', 'val'=>$pars[3]) - ) - ), - ); - break; -// case "resetStorage": -// $parr = array( -// 'loadSampleData'=>(boolean)$pars[0], -// 'invalidateSessionIds'=>(boolean)$pars[1], -// ); -// break; - default: - $pinfo = $infos[$method]['p']; - if (is_null($pinfo)) { - $parr = NULL; - } elseif(!is_array($pinfo)) { - $parr = $pars[0]; - #echo "pinfo not null and not array.\n"; exit; - } elseif(count($pinfo) == 0) { - $parr = (object)array(); - } else { - $parr = array(); $i=0; - foreach($pinfo as $it){ - if(isset($pars[$i])) $parr[$it] = $pars[$i]; - $i++; - } - } -} // switch - -$fullmethod = $infos[$method]['m']; -if (is_array($options)) { - $msg = new XML_RPC_Message($fullmethod, array(XML_RPC_encode($options))); -} else { - $msg = new XML_RPC_Message($fullmethod); -} -//$msg = new XML_RPC_Message($fullmethod, array(XML_RPC_encode($parr))); - -if ($verbose) { - echo "parr:\n"; - var_dump($parr); - echo "message:\n"; - echo $msg->serialize()."\n"; -} - -#$client->setDebug(1); -$res = $client->send($msg); -if ($res->faultCode() > 0) { - echo "xr_cli_test.php: ".$res->faultString()." ".$res->faultCode()."\n"; -# echo var_export($res); - exit(1); -} - -if ($verbose) { - echo "result:\n"; - echo $res->serialize(); -} - -$resp = XML_RPC_decode($res->value()); -if (isset($infos[$method]['r'])) { - $pom = $infos[$method]['r']; - if (is_array($pom)) { - foreach ($pom as $k => $it) { - $pom[$k] = $resp[$it]; - } - echo join(' ', $pom)."\n"; - } else { - switch ($pom) { - case "status": - case "exists": - echo ($resp[$pom]=='1' ? "TRUE" : "FALSE" )."\n"; - break; - default: - echo "{$resp[$pom]}\n"; - } - } -} else { - switch ($method) { - case "searchMetadata": -// case "getSearchResults": - $acCnt = 0; - $acGunids = array(); - $plCnt = 0; - $plGunids = array(); - $fld = (isset($options['category']) ? $options['category'] : 'gunid' ); - foreach ($resp['results'] as $k => $v) { - if ($v['type']=='audioclip') { - $acCnt++; - $acGunids[] = $v[$fld]; - } - if ($v['type']=='playlist') { - $plCnt++; - $plGunids[] = $v[$fld]; - } - } - echo "AC({$acCnt}): ". - join(", ", $acGunids). - " | PL({$plCnt}): ". - join(", ", $plGunids). - "\n"; - break; - case "browseCategory": - echo "RES({$resp['cnt']}): ". - join(", ", $resp['results']). - "\n"; - break; - default: - print_r($resp); - echo "\n"; - } -} - -?> \ No newline at end of file diff --git a/backend/xmlrpc/xr_web_test.php b/backend/xmlrpc/xr_web_test.php deleted file mode 100644 index 34537170c..000000000 --- a/backend/xmlrpc/xr_web_test.php +++ /dev/null @@ -1,373 +0,0 @@ -'.htmlspecialchars($p_printValue)."\n"; - echo $str; - return $selected; -} // fn camp_html_select_option - - -$serverPath = - "http://{$CC_CONFIG['storageUrlHost']}:{$CC_CONFIG['storageUrlPort']}". - "{$CC_CONFIG['storageUrlPath']}/{$CC_CONFIG['storageXMLRPC']}"; -$serverPath = camp_session_get("storageserver_xmlrpc_path", $serverPath); -$f_selectedMethod = camp_session_get("f_selectedMethod", "listMethods"); -$url = parse_url($serverPath); -$client = new XML_RPC_Client($url['path'], $url['host']); - -$methodDefs = array( - "listMethods" => array('m'=>"system.listMethods", 'p'=>NULL), - "methodHelp" => array('m'=>"system.methodHelp", 'p'=>0), - "methodSignature" => array('m'=>"system.methodSignature", 'p'=>0), - "test" => array('m'=>"locstor.test", 'p'=>array('sessid', 'teststring')), - "getVersion" => array('m'=>"locstor.getVersion", 'p'=>array(), 'r'=>'version'), - "authenticate" => array('m'=>"locstor.authenticate", 'p'=>array('login', 'pass'), 'r'=>'authenticate'), - "login" => array('m'=>"locstor.login", 'p'=>array('login', 'pass'), 'r'=>'sessid'), - "logout" => array('m'=>"locstor.logout", 'p'=>array('sessid'), 'r'=>'status'), - "storeAudioClipOpen" => array('m'=>"locstor.storeAudioClipOpen", - 'p'=>array('sessid', 'gunid', 'metadata', 'fname', 'chsum'), - 'r'=>array('url', 'token') - ), - "storeAudioClipClose" => array('m'=>"locstor.storeAudioClipClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - "accessRawAudioData" => array('m'=>"locstor.accessRawAudioData", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "releaseRawAudioData" => array('m'=>"locstor.releaseRawAudioData", - 'p'=>array('token'), 'r'=>'status'), - "downloadRawAudioDataOpen" => - array('m'=>"locstor.downloadRawAudioDataOpen", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "downloadRawAudioDataClose" => - array('m'=>"locstor.downloadRawAudioDataClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - "downloadMetadataOpen" => array('m'=>"locstor.downloadMetadataOpen", - 'p'=>array('sessid', 'gunid'), 'r'=>array('url', 'token')), - "downloadMetadataClose" => array('m'=>"locstor.downloadMetadataClose", - 'p'=>array('sessid', 'token'), 'r'=>'gunid'), - - "deleteAudioClip" => - array('m'=>"locstor.deleteAudioClip", - 'p'=>array('sessid', 'gunid', 'forced'), 'r'=>'status'), - "existsAudioClip" => array('m'=>"locstor.existsAudioClip", - 'p'=>array('sessid', 'gunid'), 'r'=>'exists'), - "getAudioClip" => array('m'=>"locstor.getAudioClip", - 'p'=>array('sessid', 'gunid'), 'r'=>'metadata'), - "updateAudioClipMetadata" => array('m'=>"locstor.updateAudioClipMetadata", - 'p'=>array('sessid', 'gunid', 'metadata'), 'r'=>'status'), - "searchMetadata" => array('m'=>"locstor.searchMetadata", 'p'=>NULL), - "browseCategory" => array('m'=>"locstor.browseCategory", 'p'=>NULL), -// "resetStorage" => array('m'=>"locstor.resetStorage", -// 'p'=>array()), - "storeWebstream" => array('m'=>"locstor.storeWebstream", - 'p'=>array('sessid', 'gunid', 'metadata', 'fname', 'url'), - 'r'=>array('gunid') - ), - - "createPlaylist" => array('m'=>"locstor.createPlaylist", - 'p'=>array('sessid', 'plid', 'fname'), 'r'=>'plid'), - "editPlaylist" => array('m'=>"locstor.editPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>array('url', 'token')), - "savePlaylist" => array('m'=>"locstor.savePlaylist", - 'p'=>array('sessid', 'token', 'newPlaylist'), 'r'=>'plid'), - "revertEditedPlaylist" => array('m'=>"locstor.revertEditedPlaylist", - 'p'=>array('sessid', 'token'), 'r'=>'plid'), - "deletePlaylist" => array('m'=>"locstor.deletePlaylist", - 'p'=>array('sessid', 'plid', 'forced'), 'r'=>'status'), - "accessPlaylist" => array('m'=>"locstor.accessPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>array('url', 'token')), - "releasePlaylist" => array('m'=>"locstor.releasePlaylist", - 'p'=>array('token'), 'r'=>'plid'), - "existsPlaylist" => array('m'=>"locstor.existsPlaylist", - 'p'=>array('sessid', 'plid'), 'r'=>'exists'), - "playlistIsAvailable" => array('m'=>"locstor.playlistIsAvailable", - 'p'=>array('sessid', 'plid'), 'r'=>array('available', 'ownerid', 'ownerlogin')), - - "exportPlaylistOpen" => array('m'=>"locstor.exportPlaylistOpen", - 'p'=>array('sessid', 'plids', 'type', 'standalone'), - 'r'=>array('url', 'token')), - "exportPlaylistClose" => array('m'=>"locstor.exportPlaylistClose", - 'p'=>array('token'), 'r'=>array('status')), - "importPlaylistOpen" => array('m'=>"locstor.importPlaylistOpen", - 'p'=>array('sessid', 'chsum'), 'r'=>array('url', 'token')), - "importPlaylistClose" => array('m'=>"locstor.importPlaylistClose", - 'p'=>array('token'), 'r'=>array('gunid')), - - "renderPlaylistToFileOpen" => array('m'=>"locstor.renderPlaylistToFileOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToFileCheck" => array('m'=>"locstor.renderPlaylistToFileCheck", - 'p'=>array('token'), 'r'=>array('status', 'url')), - "renderPlaylistToFileClose" => array('m'=>"locstor.renderPlaylistToFileClose", - 'p'=>array('token'), 'r'=>array('status')), - "renderPlaylistToStorageOpen" => array('m'=>"locstor.renderPlaylistToStorageOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToStorageCheck" => array('m'=>"locstor.renderPlaylistToStorageCheck", - 'p'=>array('token'), 'r'=>array('status', 'gunid')), - "renderPlaylistToRSSOpen" => array('m'=>"locstor.renderPlaylistToRSSOpen", - 'p'=>array('sessid', 'plid'), - 'r'=>array('token')), - "renderPlaylistToRSSCheck" => array('m'=>"locstor.renderPlaylistToRSSCheck", - 'p'=>array('token'), 'r'=>array('status', 'url')), - "renderPlaylistToRSSClose" => array('m'=>"locstor.renderPlaylistToRSSClose", - 'p'=>array('token'), 'r'=>array('status')), - - "loadPref" => array('m'=>"locstor.loadPref", - 'p'=>array('sessid', 'key'), 'r'=>'value'), - "savePref" => array('m'=>"locstor.savePref", - 'p'=>array('sessid', 'key', 'value'), 'r'=>'status'), - "delPref" => array('m'=>"locstor.delPref", - 'p'=>array('sessid', 'key'), 'r'=>'status'), - "loadGroupPref" => array('m'=>"locstor.loadGroupPref", - 'p'=>array('sessid', 'group', 'key'), 'r'=>'value'), - "saveGroupPref" => array('m'=>"locstor.saveGroupPref", - 'p'=>array('sessid', 'group', 'key', 'value'), 'r'=>'status'), - - "getTransportInfo" => array('m'=>"locstor.getTransportInfo", - 'p'=>array('trtok'), - 'r'=>array('state', 'realsize', 'expectedsize', 'realsum', 'expectedsum')), - "turnOnOffTransports" => array('m'=>"locstor.turnOnOffTransports", - 'p'=>array('sessid', 'onOff'), 'r'=>array('state')), - "doTransportAction" => array('m'=>"locstor.doTransportAction", - 'p'=>array('sessid', 'trtok', 'action'), 'r'=>array('state')), - "uploadFile2Hub" => array('m'=>"locstor.uploadFile2Hub", - 'p'=>array('sessid', 'filePath'), 'r'=>array('trtok')), - "getHubInitiatedTransfers" => array('m'=>"locstor.getHubInitiatedTransfers", - 'p'=>array('sessid'), 'r'=>array()), - "startHubInitiatedTransfer" => array('m'=>"locstor.startHubInitiatedTransfer", - 'p'=>array('trtok'), 'r'=>array()), - "upload2Hub" => array('m'=>"locstor.upload2Hub", - 'p'=>array('sessid', 'gunid'), 'r'=>array('trtok')), - "downloadFromHub" => array('m'=>"locstor.downloadFromHub", - 'p'=>array('sessid', 'gunid'), 'r'=>array('trtok')), -// "globalSearch" => array('m'=>"locstor.globalSearch", -// 'p'=>array('sessid', 'criteria'), 'r'=>array('trtok')), -// "getSearchResults" => array('m'=>"locstor.getSearchResults", -// 'p'=>array('trtok')), - - "createBackupOpen" => array('m'=>"locstor.createBackupOpen", - 'p'=>array('sessid', 'criteria'), 'r'=>array('token')), - "createBackupCheck" => array('m'=>"locstor.createBackupCheck", -# 'p'=>array('token'), 'r'=>array('status', 'url', 'metafile', 'faultString')), - 'p'=>array('token'), 'r'=>array('status', 'url', 'tmpfile')), - "createBackupClose" => array('m'=>"locstor.createBackupClose", - 'p'=>array('token'), 'r'=>array('status')), - "restoreBackupOpen" => array('m'=>"locstor.restoreBackupOpen", - 'p'=>array('sessid', 'chsum'), 'r'=>array('url', 'token')), - "restoreBackupClosePut" => array('m'=>"locstor.restoreBackupClosePut", - 'p'=>array('sessid', 'token'), 'r'=>array('token')), - "restoreBackupCheck" => array('m'=>"locstor.restoreBackupCheck", - 'p'=>array('token'), 'r'=>array('status', 'faultString')), - "restoreBackupClose" => array('m'=>"locstor.restoreBackupClose", - 'p'=>array('token'), 'r'=>array('status')), - "openPut" => array('m'=>"locstor.openPut", 'p'=>array()), - "closePut" => array('m'=>"locstor.closePut", 'p'=>array()), -); - -if (isset($_REQUEST['go_button'])) { - // Get the parameters - $methodParams = $methodDefs[$f_selectedMethod]['p']; - foreach ($methodParams as $methodParamName) { - $inputParamName = "param_".$methodParamName; - $xmlParameters[$methodParamName] = $_REQUEST[$inputParamName]; - $_SESSION[$inputParamName] = $_REQUEST[$inputParamName]; - } - - // Create the XML-RPC message - $actualMethod = $methodDefs[$f_selectedMethod]['m']; - $msg = new XML_RPC_Message($actualMethod, array(XML_RPC_encode($xmlParameters))); - $sentMessage = $msg->serialize(); - - // Send it - $sendResult = $client->send($msg); - if ($sendResult->faultCode() > 0) { - $errorMsg = "xr_cli_test.php: ".$sendResult->faultString()." ".$sendResult->faultCode()."\n"; - } else { - // If successful - $xmlResponse = XML_RPC_decode($sendResult->value()); - - // Special case state handling - switch ($f_selectedMethod) { - case "login": - // Remember the login session ID so we can use it to call - // other methods. - $loggedIn = true; - $_SESSION['xmlrpc_session_id'] = $xmlResponse['sessid']; - break; - case "logout": - unset($_SESSION['xmlrpc_session_id']); - break; - case "storeAudioClipOpen": - $_SESSION['xmlrpc_token'] = $xmlResponse['token']; - $_SESSION['xmlrpc_put_url'] = $xmlResponse['url']; - break; - } - - if (isset($methodDefs[$method]['r'])) { - $expectedResult = $methodDefs[$method]['r']; - if (is_array($expectedResult)) { - foreach ($expectedResult as $resultName) { - $actualResults[$resultName] = $xmlResponse[$resultName]; - } - echo join(' ', $actualResults)."\n"; - } else { - switch ($expectedResult) { - case "status": - case "exists": - echo ($xmlResponse[$expectedResult]=='1' ? "TRUE" : "FALSE" )."\n"; - break; - default: - echo "{$xmlResponse[$expectedResult]}\n"; - } - } - } else { - switch ($method) { - case "searchMetadata": -// case "getSearchResults": - $acCnt = 0; - $acGunids = array(); - $plCnt = 0; - $plGunids = array(); - $fld = (isset($options['category']) ? $options['category'] : 'gunid' ); - foreach ($xmlResponse['results'] as $k => $v) { - if ($v['type']=='audioclip') { - $acCnt++; - $acGunids[] = $v[$fld]; - } - if ($v['type']=='playlist') { - $plCnt++; - $plGunids[] = $v[$fld]; - } - } - echo "AC({$acCnt}): ". - join(", ", $acGunids). - " | PL({$plCnt}): ". - join(", ", $plGunids). - "\n"; - break; - case "browseCategory": - echo "RES({$xmlResponse['cnt']}): ". - join(", ", $xmlResponse['results']). - "\n"; - break; - default: - //print_r($xmlResponse); - } - } - } -} -?> - - -
    -StorageServer path :
    -Method: - -
    -Parameters: -"; -} else { - echo ""; - foreach ($methodParams as $methodParamName) { - $value = ""; - if ($methodParamName == "sessid" && isset($_SESSION['xmlrpc_session_id'])) { - $value = $_SESSION['xmlrpc_session_id']; - } elseif ($methodParamName == "token" && isset($_SESSION['xmlrpc_token'])) { - $value = $_SESSION['xmlrpc_token']; - } elseif (isset($_SESSION["param_".$methodParamName])) { - $value = $_SESSION["param_".$methodParamName]; - } - echo ""; - echo ""; ?> - "; -} -?> -
    - - - - -
    "; -} -if (isset($sentMessage)) { - ?> - Sent message:
    - -
    - - Error:
    - -
    - - Response:
    - -
    - - - diff --git a/utils/backup.sh b/utils/backup.sh deleted file mode 100755 index 69baf25d0..000000000 --- a/utils/backup.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# param $1: workdir what we would like to tar -# param $2: output file: the .tar file -# param $3: statusfile -echo "==>" -date +\ %Y%m%d\ %H:%M:%S -echo "backup.sh: create tarball $1 to $2" -echo "backup.sh: status: #$3#" -echo "<==" -echo -n "working" > $3; -touch $2 || { echo -n "fault|error with .tar file" > $3; exit 1; } -#sleep 120 -cd $1 -tar cf $2 * || { echo -n "fault|error in tar procedure" > $3; exit 1; } -chmod 666 $2 - -echo -n "success" > $3 diff --git a/utils/createDatabase.sh b/utils/createDatabase.sh deleted file mode 100755 index bc58d6a65..000000000 --- a/utils/createDatabase.sh +++ /dev/null @@ -1,211 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# To report bugs, send an e-mail to bugs@campware.org -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- -# This script creates the database used by Campcaster -# -# Invoke as: -# ./bin/createDatabase.sh -# -# To get usage help, try the -h option -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Determine directories, files -#------------------------------------------------------------------------------- -reldir=`dirname $0`/.. -basedir=`cd $reldir; pwd;` -bindir=$basedir/bin -etcdir=$basedir/etc -docdir=$basedir/doc -tmpdir=$basedir/tmp -usrdir=$basedir/usr - - -#------------------------------------------------------------------------------- -# Print the usage information for this script. -#------------------------------------------------------------------------------- -printUsage() -{ - echo "Campcaster scheduler database creation script."; - echo "parameters"; - echo ""; - echo " -D, --database The name of the Campcaster database."; - echo " [default: Campcaster]"; - echo " -s, --dbserver The name of the database server host."; - echo " [default: localhost]"; - echo " -u, --dbuser The name of the database user to access the" - echo " database. [default: campcaster]"; - echo " -w, --dbpassword The database user password."; - echo " [default: campcaster]"; - echo " -h, --help Print this message and exit."; - echo ""; -} - - -#------------------------------------------------------------------------------- -# Process command line parameters -#------------------------------------------------------------------------------- -CMD=${0##*/} - -opts=$(getopt -o D:hs:u:w: -l database:,dbserver:,dbuser:,dbpassword:,help, -n $CMD -- "$@") || exit 1 -eval set -- "$opts" -while true; do - case "$1" in - -D|--database) - database=$2; - shift; shift;; - -h|--help) - printUsage; - exit 0;; - -s|--dbserver) - dbserver=$2; - shift; shift;; - -u|--dbuser) - dbuser=$2; - shift; shift;; - -w|--dbpassword) - dbpassword=$2; - shift; shift;; - --) - shift; - break;; - *) - echo "Unrecognized option $1."; - printUsage; - exit 1; - esac -done - -if [ "x$dbserver" == "x" ]; then - dbserver=localhost; -fi - -if [ "x$database" == "x" ]; then - database=Campcaster; -fi - -if [ "x$dbuser" == "x" ]; then - dbuser=campcaster; -fi - -if [ "x$dbpassword" == "x" ]; then - dbpassword=campcaster; -fi - -echo "Creating database for Campcaster scheduler."; -echo ""; -echo "Using the following parameters:"; -echo ""; -echo " database server: $dbserver"; -echo " database: $database"; -echo " database user: $dbuser"; -echo " database user password: $dbpassword"; -echo "" - -#------------------------------------------------------------------------------- -# The details of installation -#------------------------------------------------------------------------------- -ls_dbserver=$dbserver -ls_dbuser=$dbuser -ls_dbpassword=$dbpassword -ls_database=$database - - -postgres_user=postgres - -#------------------------------------------------------------------------------- -# Function to check for the existence of an executable on the PATH -# -# @param $1 the name of the exectuable -# @return 0 if the executable exists on the PATH, non-0 otherwise -#------------------------------------------------------------------------------- -check_exe() { - if [ -x "`which $1 2> /dev/null`" ]; then - echo "Executable $1 found..."; - return 0; - else - echo "Executable $1 not found..."; - return 1; - fi -} - - -#------------------------------------------------------------------------------- -# Check to see if this script is being run as root -#------------------------------------------------------------------------------- -if [ `whoami` != "root" ]; then - echo "Please run this script as root."; - exit ; -fi - - -#------------------------------------------------------------------------------- -# Check for required tools -#------------------------------------------------------------------------------- -echo "Checking for required tools..." - -check_exe "su" || exit 1; -check_exe "psql" || exit 1; - - -#------------------------------------------------------------------------------- -# Create the necessary database user and database itself -#------------------------------------------------------------------------------- -echo "Creating database and database user..."; - -# FIXME: the below might not work for remote databases - -if [ "x$ls_dbserver" == "xlocalhost" ]; then - su - $postgres_user -c "echo \"CREATE USER $ls_dbuser \ - ENCRYPTED PASSWORD '$ls_dbpassword' \ - CREATEDB NOCREATEUSER;\" \ - | psql template1" \ - || echo "Couldn't create database user $ls_dbuser."; - - su - $postgres_user -c "echo \"CREATE DATABASE \\\"$ls_database\\\" \ - OWNER $ls_dbuser ENCODING 'utf-8';\" \ - | psql template1" \ - || echo "Couldn't create database $ls_database."; -else - echo "Unable to automatically create database user and table for"; - echo "remote database $ls_dbserver."; - echo "Make sure to create database user $ls_dbuser with password"; - echo "$ls_dbpassword on database server at $ls_dbserver."; - echo "Also create a database called $ld_database, owned by this user."; - echo ""; - echo "The easiest way to achieve this is by issuing the following SQL"; - echo "commands to PostgreSQL:"; - echo "CREATE USER $ls_dbuser"; - echo " ENCRYPTED PASSWORD '$ls_dbpassword'"; - echo " CREATEDB NOCREATEUSER;"; - echo "CREATE DATABASE \"$ls_database\""; - echo " OWNER $ls_dbuser ENCODING 'utf-8';"; -fi - - -# TODO: check for the success of these operations somehow -#------------------------------------------------------------------------------- -# Say goodbye -#------------------------------------------------------------------------------- -echo "Done." - diff --git a/utils/dumpDbSchema.php b/utils/dumpDbSchema.php deleted file mode 100644 index 2ca11f4be..000000000 --- a/utils/dumpDbSchema.php +++ /dev/null @@ -1,9 +0,0 @@ - \ No newline at end of file diff --git a/utils/dumpDbSchema.sh b/utils/dumpDbSchema.sh deleted file mode 100755 index a3b3b624d..000000000 --- a/utils/dumpDbSchema.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- -#------------------------------------------------------------------------------- -# This script dumps the schema of the Campcaster database. -# -# To get usage help, try the -h option -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Determine directories, files -#------------------------------------------------------------------------------- - -reldir=`dirname $0`/.. -phpdir=ls_storageAdmin_phppart_dir -if [ "$phpdir" == "ls_storageAdmin_phppart_dir" ] -then - phpdir=`cd $reldir/var; pwd` -fi -filelistpathname=. - -#------------------------------------------------------------------------------- -# Print the usage information for this script. -#------------------------------------------------------------------------------- -printUsage() -{ - echo "This script dumps the schema of the Campcaster database."; - echo "parameters:"; - echo ""; - echo " -h, --help Print this message and exit."; - echo ""; -} - -#------------------------------------------------------------------------------- -# Process command line parameters -#------------------------------------------------------------------------------- -CMD=${0##*/} - -opts=$(getopt -o h -l help -n $CMD -- "$@") || exit 1 -eval set -- "$opts" -while true; do - case "$1" in - -h|--help) - printUsage; - exit 0;; - --) - shift; - break;; - *) - echo "Unrecognized option $1."; - printUsage; - exit 1; - esac -done - -#------------------------------------------------------------------------------- -# Do the schema dump -#------------------------------------------------------------------------------- - -cd $phpdir -php -q dumpDbSchema.php - -#------------------------------------------------------------------------------- -# Say goodbye -#------------------------------------------------------------------------------- -echo "-- End of dump." diff --git a/utils/getStorPath.php b/utils/getStorPath.php deleted file mode 100644 index 1f8cd5252..000000000 --- a/utils/getStorPath.php +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/utils/getUrl.sh b/utils/getUrl.sh deleted file mode 100755 index f59445521..000000000 --- a/utils/getUrl.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# To report bugs, send an e-mail to bugs@campware.org -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# This script grabs string at suplied URL -#------------------------------------------------------------------------------- - -URL=$1 -RES=`curl -sf ${URL}` || \ - { - ERN=$?; - if [ $ERN -eq 22 ] ; then - echo "ERROR: curl: 22 - wrong URL ($URL)"; - else - echo "ERROR: $ERN - unknown"; - fi; - exit $ERN; - } -echo $RES diff --git a/utils/renderer.sh b/utils/renderer.sh deleted file mode 100755 index d1d7f9cce..000000000 --- a/utils/renderer.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# To report bugs, send an e-mail to bugs@campware.org -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- -# Playlist-to-file renderer caller. DUMMY VERSION. -# -# To get usage help, try the -h option -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Determine directories, files -#------------------------------------------------------------------------------- - -reldir=`dirname $0`/.. - -#------------------------------------------------------------------------------- -# Print the usage information for this script. -#------------------------------------------------------------------------------- -printUsage() -{ - echo "Playlist-to-file renderer caller. DUMMY VERSION."; - echo "parameters:"; - echo ""; - echo " -p, --playlist URL of SMIL playlist to be rendered."; - echo " -s, --statusfile Status file name."; - echo " -o, --output File name where the output will be written."; - echo " -h, --help Print this message and exit."; - echo ""; -} - -#------------------------------------------------------------------------------- -# Process command line parameters -#------------------------------------------------------------------------------- -CMD=${0##*/} - -opts=$(getopt -o hp:s:o: -l help,playlist:,statusfile:,output: -n $CMD -- "$@") || exit 1 -eval set -- "$opts" -while true; do - case "$1" in - -h|--help) - printUsage; - exit 0;; - -p|--playlist) - playlist=$2 - shift; shift;; - -s|--statusfile) - statusfile=$2 - shift; shift;; - -o|--output) - output=$2 - shift; shift;; - --) - shift; - break;; - *) - echo "Unrecognized option $1."; - printUsage; - exit 1; - esac -done - -if [ "x$playlist" == "x" ]; then - echo "Error in playlist parameter"; - printUsage; - exit 1; -fi -if [ "x$statusfile" == "x" ]; then - echo "Error in statusfile parameter"; - printUsage; - exit 1; -fi -if [ "x$output" == "x" ]; then - echo "Error in output parameter"; - printUsage; - exit 1; -fi - -#------------------------------------------------------------------------------- -# Do it -#------------------------------------------------------------------------------- -echo "renderer.sh: rendering $playlist to $output" -echo "working" > $statusfile; -touch $output || { echo "fail" > $statusfile; exit 1; } -#sleep 4 -#sleep 2 -echo -e "$playlist\n$output" >> $output || { echo "fail" > $statusfile; exit 1; } - -echo "success" > $statusfile - -#------------------------------------------------------------------------------- -# Say goodbye -#------------------------------------------------------------------------------- -echo "done" -exit 0 diff --git a/utils/setupDirs.sh b/utils/setupDirs.sh deleted file mode 100755 index 2b7d1e3c8..000000000 --- a/utils/setupDirs.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Campcaster project. -# http://campcaster.sourcefabric.org/ -# -# Campcaster is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Campcaster is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Campcaster; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# This script does httpd writeable directories setup -#------------------------------------------------------------------------------- - -WWW_ROOT=`cd var/install; php -q getWwwRoot.php` || exit $? -echo " *** StorageServer bin/setupDirs.sh BEGIN" -echo " * Root URL: $WWW_ROOT" -PHP_PWD_COMMAND=`bin/getUrl.sh $WWW_ROOT/install/getPwd.php` || \ - { - errno=$? - if [ $errno -eq 22 ] - then - echo "root URL is not accessible - configure HTTP entry point, please" - fi - exit $errno - } - -PHP_PWD=$PHP_PWD_COMMAND -# MOD_PHP may not be working, this command will tell us -if [ ${PHP_PWD_COMMAND:0:5} == ' Probably wrong setting in var/conf.php: URL configuration"; - exit $ERN; - } -echo " ** The system group that is running the http daemon: '$HTTP_GROUP'" - -for i in $* -do - echo " * chown :$HTTP_GROUP $i" - if [ -G $i ]; then - chown :$HTTP_GROUP $i || \ - { - ERN=$?; - echo "ERROR: chown :$HTTP_GROUP $i -> You should have permissions to set group owner to group '$HTTP_GROUP'"; - exit $ERN; - } - echo " * chmod g+sw $i" - chmod g+sw $i || exit $? - fi -done - -echo " *** StorageServer bin/setupDirs.sh END" -exit 0 From 38bc0de9a2619e80b2e6f5419785c129c1f27a11 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 9 Dec 2010 15:58:44 -0500 Subject: [PATCH 2/3] Fixed utils to work with new directory structure. --- utils/CleanStor.php | 4 ++-- utils/campcaster-backup.php | 6 +++--- utils/campcaster-import.php | 4 ++-- utils/restore.php | 6 +++--- utils/restore2.php | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/utils/CleanStor.php b/utils/CleanStor.php index ac9359aee..14d8ff05f 100644 --- a/utils/CleanStor.php +++ b/utils/CleanStor.php @@ -9,10 +9,10 @@ if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) { exit(1); } -require_once('../conf.php'); require_once('DB.php'); +require_once('../application/configs/conf.php'); require_once('../install/installInit.php'); -require_once('../backend/StoredFile.php'); +require_once('../application/models/StoredFile.php'); function printUsage() { diff --git a/utils/campcaster-backup.php b/utils/campcaster-backup.php index 596d156b3..de0f0e405 100644 --- a/utils/campcaster-backup.php +++ b/utils/campcaster-backup.php @@ -5,9 +5,9 @@ header("Content-type: text/plain"); require_once('DB.php'); require_once("XML/Util.php"); require_once("XML/Beautifier.php"); -require_once(dirname(__FILE__)."/../conf.php"); -require_once(dirname(__FILE__)."/../backend/BasicStor.php"); -require_once(dirname(__FILE__)."/../backend/Prefs.php"); +require_once(dirname(__FILE__)."/../application/configs/conf.php"); +require_once(dirname(__FILE__)."/../application/models/BasicStor.php"); +require_once(dirname(__FILE__)."/../application/models/Prefs.php"); PEAR::setErrorHandling(PEAR_ERROR_RETURN); $CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); diff --git a/utils/campcaster-import.php b/utils/campcaster-import.php index 77f2223b0..8cb92dcf3 100644 --- a/utils/campcaster-import.php +++ b/utils/campcaster-import.php @@ -12,8 +12,8 @@ set_time_limit(0); error_reporting(E_ALL); set_error_handler("camp_import_error_handler", E_ALL & !E_NOTICE); -require_once(dirname(__FILE__)."/../conf.php"); -require_once(dirname(__FILE__)."/../backend/GreenBox.php"); +require_once(dirname(__FILE__)."/../application/configs/conf.php"); +require_once(dirname(__FILE__)."/../application/models/GreenBox.php"); require_once('DB.php'); require_once('Console/Getopt.php'); diff --git a/utils/restore.php b/utils/restore.php index cb2b266bb..c83c1be21 100644 --- a/utils/restore.php +++ b/utils/restore.php @@ -7,9 +7,9 @@ header("Content-type: text/plain"); require_once 'DB.php'; require_once "XML/Util.php"; require_once "XML/Beautifier.php"; -require_once dirname(__FILE__)."/../conf.php"; -require_once dirname(__FILE__)."/../backend/BasicStor.php"; -require_once dirname(__FILE__)."/../backend/Prefs.php"; +require_once dirname(__FILE__)."/../application/configs/conf.php"; +require_once dirname(__FILE__)."/../application/models/BasicStor.php"; +require_once dirname(__FILE__)."/../application/models/Prefs.php"; /* =========================================================== misc functions */ function ls_restore_processObject($el) diff --git a/utils/restore2.php b/utils/restore2.php index ef12224ae..a1bf4f38f 100755 --- a/utils/restore2.php +++ b/utils/restore2.php @@ -12,9 +12,9 @@ * */ - require_once(dirname(__FILE__).'/../conf.php'); - require_once(dirname(__FILE__).'/../backend/GreenBox.php'); - require_once(dirname(__FILE__).'/../backend/Restore.php'); + require_once(dirname(__FILE__).'/../application/configs/conf.php'); + require_once(dirname(__FILE__).'/../application/models/GreenBox.php'); + require_once(dirname(__FILE__).'/../application/models/Restore.php'); include_once('DB.php'); PEAR::setErrorHandling(PEAR_ERROR_RETURN); From 84c2a3bceb52cca41e4ef18e48f2b0b819f844aa Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 9 Dec 2010 18:44:47 -0500 Subject: [PATCH 3/3] Converted API functions to Zend Framework. Converted pypo to use the new Zendified URLs. Fixed bugs in the daemontool scripts. The installed scheduler is still not working at this point, but getting close. --- .zfproject.xml | 7 ++++++ application/configs/ACL.php | 4 ++- application/configs/conf.php | 11 ++++++++ application/models/Playlist.php | 19 +++++++++----- application/models/Schedule.php | 20 +++++++++++++++ application/models/StoredFile.php | 2 +- pypo/api_clients/api_client.py | 4 +-- pypo/config.cfg | 12 ++++----- pypo/install/pypo-daemontools-fetch.sh | 4 +-- pypo/install/pypo-daemontools-push.sh | 4 +-- pypo/install/pypo-install.py | 23 +++++++++++++++-- .../models => pypo}/tests/pypoTester.php | 25 +++++++++++++------ .../controllers/ApiControllerTest.php | 20 +++++++++++++++ 13 files changed, 126 insertions(+), 29 deletions(-) rename {application/models => pypo}/tests/pypoTester.php (81%) create mode 100644 tests/application/controllers/ApiControllerTest.php diff --git a/.zfproject.xml b/.zfproject.xml index 986d3777a..05cfc7b75 100644 --- a/.zfproject.xml +++ b/.zfproject.xml @@ -54,6 +54,9 @@ + + + @@ -167,6 +170,9 @@ + + + @@ -207,6 +213,7 @@ + diff --git a/application/configs/ACL.php b/application/configs/ACL.php index 61f657bae..7803aa471 100644 --- a/application/configs/ACL.php +++ b/application/configs/ACL.php @@ -15,6 +15,7 @@ $ccAcl->add(new Zend_Acl_Resource('library')) ->add(new Zend_Acl_Resource('playlist')) ->add(new Zend_Acl_Resource('plupload')) ->add(new Zend_Acl_Resource('schedule')) + ->add(new Zend_Acl_Resource('api')) ->add(new Zend_Acl_Resource('search')); /** Creating permissions */ @@ -23,11 +24,12 @@ $ccAcl->allow('guest', 'index') ->allow('guest', 'error') ->allow('guest', 'library') ->allow('guest', 'search') + ->allow('guest', 'api') ->allow('host', 'plupload') ->allow('host', 'playlist') ->allow('host', 'schedule'); $aclPlugin = new Zend_Controller_Plugin_Acl($ccAcl); -$front = Zend_Controller_Front::getInstance(); +$front = Zend_Controller_Front::getInstance(); $front->registerPlugin($aclPlugin); diff --git a/application/configs/conf.php b/application/configs/conf.php index 0a97c14c4..7779721b5 100644 --- a/application/configs/conf.php +++ b/application/configs/conf.php @@ -25,6 +25,8 @@ $CC_CONFIG = array( 'apiKey' => array('AAA'), + 'apiPath' => "/api/", + 'baseFilesDir' => __DIR__."/../../files", // main directory for storing binary media files 'storageDir' => __DIR__.'/../../files/stor', @@ -162,4 +164,13 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'] .PATH_SEPARATOR.$CC_CONFIG['zendPath'] .PATH_SEPARATOR.$old_include_path); +//$dsn = $CC_CONFIG['dsn']; +//$CC_DBC = DB::connect($dsn, TRUE); +//if (PEAR::isError($CC_DBC)) { +// echo "ERROR: ".$CC_DBC->getMessage()." ".$CC_DBC->getUserInfo()."\n"; +// exit(1); +//} +//$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); + + ?> \ No newline at end of file diff --git a/application/models/Playlist.php b/application/models/Playlist.php index a0ec8385d..78333a88b 100644 --- a/application/models/Playlist.php +++ b/application/models/Playlist.php @@ -102,7 +102,14 @@ class Playlist { } - /** + public static function findPlaylistByName($p_name) + { + $res = CcPlaylistQuery::create()->findByDbName($p_name); + return $res; + } + + + /** * Fetch instance of Playlist object.
    * * @param string $id @@ -414,7 +421,7 @@ class Playlist { if (is_null($media) || PEAR::isError($media)) { return $media; } - + $metadata = $media->getMetadata(); $length = $metadata["length"]; @@ -425,7 +432,7 @@ class Playlist { // insert at end of playlist. if (is_null($p_position)) $p_position = $this->getNextPos(); - + // insert default values if parameter was empty $p_cuein = !is_null($p_cuein) ? $p_cuein : '00:00:00.000000'; $p_cueout = !is_null($p_cueout) ? $p_cueout : $length; @@ -434,9 +441,9 @@ class Playlist { $sql = "SELECT INTERVAL '{$p_cueout}' - INTERVAL '{$p_cuein}'"; $r = $con->query($sql); $p_cliplength = $r->fetchColumn(0); - + $res = $this->insertPlaylistElement($this->id, $p_mediaId, $p_position, $p_cliplength, $p_cuein, $p_cueout, $p_fadeIn, $p_fadeOut); - + return TRUE; } @@ -629,7 +636,7 @@ class Playlist { $sql = "SELECT INTERVAL '{$oldCueOut}' - INTERVAL '{$cueIn}'"; $r = $con->query($sql); $cliplength = $r->fetchColumn(0); - + $row->setDbCuein($cueIn); $row->setDBCliplength($cliplength); } diff --git a/application/models/Schedule.php b/application/models/Schedule.php index fa80671f3..76a028061 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -401,6 +401,26 @@ class Schedule { return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00"; } + /** + * Return true if the input string is in the format YYYY-MM-DD-HH-mm + * + * @param string $p_time + * @return boolean + */ + public static function ValidPypoTimeFormat($p_time) + { + $t = explode("-", $p_time); + if (count($t) != 5) { + return false; + } + foreach ($t as $part) { + if (!is_numeric($part)) { + return false; + } + } + return true; + } + /** * Converts a time value as a string (with format HH:MM:SS.mmmmmm) to * millisecs. diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index 052885be6..9925fcc63 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1697,7 +1697,7 @@ class StoredFile { { global $CC_CONFIG; return "http://".$CC_CONFIG["storageUrlHost"] - .$CC_CONFIG["apiPath"]."get_media.php?file=" + .$CC_CONFIG["apiPath"]."getMedia/file/" .$this->gunid.".".$this->getFileExtension(); } diff --git a/pypo/api_clients/api_client.py b/pypo/api_clients/api_client.py index 59fd22e48..4f6357a74 100644 --- a/pypo/api_clients/api_client.py +++ b/pypo/api_clients/api_client.py @@ -251,7 +251,7 @@ class CampcasterApiClient(ApiClientInterface): logger = logging.getLogger() try: - src = src + "&api_key=" + self.config["api_key"] + src = src + "/api_key/" + self.config["api_key"] # check if file exists already before downloading again filename, headers = urllib.urlretrieve(src, dst) @@ -269,7 +269,7 @@ class CampcasterApiClient(ApiClientInterface): schedule_id = playlist["schedule_id"] url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"] url = url.replace("%%schedule_id%%", str(schedule_id)) - url += "&api_key=" + self.config["api_key"] + url = url.replace("%%api_key%%", self.config["api_key"]) logger.debug(url) try: diff --git a/pypo/config.cfg b/pypo/config.cfg index 26ec732cd..7655854f0 100644 --- a/pypo/config.cfg +++ b/pypo/config.cfg @@ -72,24 +72,24 @@ cue_style = 'pre' api_key = 'AAA' # Path to the base of the API -api_base = 'campcaster/' +api_base = 'api/' # URL to get the version number of the server API -version_url = 'api/api_version.php?api_key=%%api_key%%' +version_url = 'version/api_key/%%api_key%%' # Schedule export path. # %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm # %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm -export_url = 'api/schedule.php?from=%%from%%&to=%%to%%&api_key=%%api_key%%' +export_url = 'schedule/api_key/%%api_key%%/from/%%from%%/to/%%to%%' # Update whether a schedule group has begun playing. -update_item_url = 'api/notify_schedule_group_play.php?schedule_id=%%schedule_id%%' +update_item_url = 'notifyScheduleGroupPlay/api_key/%%api_key%%/schedule_id/%%schedule_id%%' # Update whether an audio clip is currently playing. -update_start_playing_url = 'api/notify_media_item_start_play.php?media_id=%%media_id%%&schedule_id=%%schedule_id%%' +update_start_playing_url = 'notifyMediaItemStartPlay/api_key/%%api_key%%/media_id/%%media_id%%/schedule_id/%%schedule_id%%' # ??? -generate_range_url = 'api/generate_range_dp.php' +generate_range_url = 'generate_range_dp.php' ############## diff --git a/pypo/install/pypo-daemontools-fetch.sh b/pypo/install/pypo-daemontools-fetch.sh index bf762ae89..6e7bed55d 100644 --- a/pypo/install/pypo-daemontools-fetch.sh +++ b/pypo/install/pypo-daemontools-fetch.sh @@ -2,8 +2,8 @@ pypo_user="pypo" export HOME="/home/pypo/" # Location of pypo_cli.py Python script -pypo_path="/opt/pypo/bin" -pypo_script="pypo_cli.py" +pypo_path="/opt/pypo/bin/" +pypo_script="pypo-cli.py" echo "*** Daemontools: starting daemon" cd ${pypo_path} exec 2>&1 diff --git a/pypo/install/pypo-daemontools-push.sh b/pypo/install/pypo-daemontools-push.sh index b933ea838..4c5cc9f7c 100644 --- a/pypo/install/pypo-daemontools-push.sh +++ b/pypo/install/pypo-daemontools-push.sh @@ -2,8 +2,8 @@ pypo_user="pypo" export HOME="/home/pypo/" # Location of pypo_cli.py Python script -pypo_path="/opt/pypo/bin" -pypo_script="pypo_cli.py" +pypo_path="/opt/pypo/bin/" +pypo_script="pypo-cli.py" echo "*** Daemontools: starting daemon" cd ${pypo_path} exec 2>&1 diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index adeb85619..a5a38dfbc 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -61,8 +61,17 @@ try: shutil.copy("../scripts/silence-playlist.lsp", BASE_PATH+"files/basic") shutil.copy("../scripts/silence.mp3", BASE_PATH+"files/basic") shutil.copy("../pypo-cli.py", BASE_PATH+"bin") + shutil.copy("../pypo-notify.py", BASE_PATH+"bin") + shutil.copy("../logging.cfg", BASE_PATH+"bin") + shutil.copy("../config.cfg", BASE_PATH+"bin") shutil.copy("../pypo-log.sh", BASE_PATH+"bin") - + print "Copying directory util" + shutil.copytree("../util", BASE_PATH+"bin/util") + print "Copying directory api_clients" + shutil.copytree("../api_clients", BASE_PATH+"bin/api_clients") + print "Copying directory scripts" + shutil.copytree("../scripts", BASE_PATH+"bin/scripts") + print "Setting permissions" os.system("chmod -R 755 "+BASE_PATH) os.system("chown -R pypo:pypo "+BASE_PATH) @@ -95,8 +104,18 @@ try: output = p.stdout.read() if (output.find("unable to open supervise/ok: file does not exist") >= 0): print "Install has completed, but daemontools is not running, please make sure you have it installed and then reboot." + sys.exit() + print output + + p = Popen('svstat /etc/service/pypo-push', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + print output + + p = Popen('svstat /etc/service/pypo-liquidsoap', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + print output - #os.symlink(BASE_PATH+"bin/pypo-log.sh", "/usr/local/bin/") +#os.symlink(BASE_PATH+"bin/pypo-log.sh", "/usr/local/bin/") except Exception, e: diff --git a/application/models/tests/pypoTester.php b/pypo/tests/pypoTester.php similarity index 81% rename from application/models/tests/pypoTester.php rename to pypo/tests/pypoTester.php index 4443b14c1..0fa1853e9 100644 --- a/application/models/tests/pypoTester.php +++ b/pypo/tests/pypoTester.php @@ -1,12 +1,23 @@ getMessage()." ".$CC_DBC->getUserInfo()."\n"; + exit(1); +} +$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); + $playlistName = "pypo_playlist_test"; $minutesFromNow = 1; @@ -82,4 +93,4 @@ $scheduleGroup = new ScheduleGroup(); $scheduleGroup->add($playTime, null, $pl->getId()); echo " SUCCESS: Playlist scheduled at $playTime\n\n"; -?> \ No newline at end of file +?> diff --git a/tests/application/controllers/ApiControllerTest.php b/tests/application/controllers/ApiControllerTest.php new file mode 100644 index 000000000..aaf96967e --- /dev/null +++ b/tests/application/controllers/ApiControllerTest.php @@ -0,0 +1,20 @@ +
    $methodParamName

    Oc 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 diff --git a/backend/tests/exportedPl_lspl.tar b/backend/tests/exportedPl_lspl.tar deleted file mode 100644 index 42cfb22dddf80f0d0dd3f8c7248666ce11f1e902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 573440 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