Merge pull request #2 from LibreTime/master
get the last changes from master
This commit is contained in:
commit
ab10e93949
|
@ -0,0 +1 @@
|
|||
open_collective: libretime
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**LibreTime version:**
|
||||
Version from the upgrade popup if you can reach it.
|
||||
|
||||
**Installation method:**
|
||||
- OS: [e.g. Ubuntu]
|
||||
- OS Version [e.g. 16.04.5 LTS (Xenial Xerus)]
|
||||
- Method: [e.g. `./install` script or packages]
|
||||
- Details: [how did you call the install script, where did you get packages from]
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Client (please complete the following information if applicable):**
|
||||
- OS: [e.g. Fedora]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature-request
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,30 @@
|
|||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 365
|
||||
|
||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
||||
skipCreatedBefore: false
|
||||
|
||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
||||
exemptLabels: []
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue for
|
||||
related bugs.
|
||||
|
||||
Please chat to us on [discourse](https://discourse.libretime.org/) or
|
||||
ask for help on our [chat](https://chat.libretime.org/) if you have any
|
||||
questions or need further assistance with this issue.
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
|
@ -0,0 +1,58 @@
|
|||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale (5 months)
|
||||
daysUntilStale: 150
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. (1 month)
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
- "[Status] Maybe Later"
|
||||
- "3.0-release-blocker"
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Set to true to ignore issues with an assignee (defaults to false)
|
||||
exemptAssignees: true
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
activity in the last 5 months. It will be closed if no activity occurs in
|
||||
the next month.
|
||||
|
||||
Please chat to us on [discourse](https://discourse.libretime.org/) or
|
||||
ask for help on our [chat](https://chat.libretime.org/) if you have any
|
||||
questions or need further support with getting this issue resolved.
|
||||
|
||||
You may also label an issue as *pinned* if you would like to make sure
|
||||
that it does not get closed by this bot.
|
||||
|
||||
# Comment to post when removing the stale label.
|
||||
# unmarkComment: >
|
||||
# Your comment here.
|
||||
|
||||
# Comment to post when closing a stale Issue or Pull Request.
|
||||
closeComment: >
|
||||
This issue has been autmatically closed after is was marked as stale and
|
||||
did not receive any further inputs.
|
||||
|
||||
Feel free to let us know on [discourse](https://discourse.libretime.org/) or
|
||||
ask for help on our [chat](https://chat.libretime.org/) if you feel this
|
||||
issue should not have been closed.
|
||||
|
||||
Thank you for your contributions.
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
|
@ -15,3 +15,6 @@ VERSION
|
|||
airtime_mvc/tests/log/*.log
|
||||
.vagrant/
|
||||
.DS_Store
|
||||
.idea/
|
||||
/docs/_site/*
|
||||
/docs/.jekyll-cache/*
|
166
.travis.yml
166
.travis.yml
|
@ -1,104 +1,86 @@
|
|||
dist: trusty
|
||||
language: php
|
||||
php:
|
||||
# the latest and greatest, has some issues that are excluded below in matrix.allow_failures
|
||||
- 7.2
|
||||
- 7.1
|
||||
# the 7.0 build demonstrates that everything is basically ok for 7.0, users might want to wait for 7.1 to run it
|
||||
- 7.0
|
||||
# folks who prefer running on 5.x should be using 5.6 in most cases, 5.4 is no in the matrix since noone should use it
|
||||
- 5.6
|
||||
# this is in for centos support, it's still the default on CentOS 7.3 and there were some lang changes after 5.4
|
||||
- 5.4
|
||||
dist: xenial
|
||||
|
||||
services:
|
||||
- postgresql
|
||||
- rabbitmq
|
||||
- postgresql
|
||||
|
||||
env:
|
||||
global:
|
||||
- ENVIRONMENT=testing
|
||||
- LIBRETIME_LOG_DIR=/tmp/log/libretime
|
||||
matrix:
|
||||
- PYTHON=false
|
||||
- PYTHON=true
|
||||
matrix:
|
||||
allow_failures:
|
||||
# there are currently some testing issues with DateTime precision on 7.1
|
||||
- env: PYTHON=false
|
||||
php: 7.1
|
||||
# there are some issues with phpunit as well as some deep in zf1 on 7.2
|
||||
- env: PYTHON=false
|
||||
php: 7.2
|
||||
exclude:
|
||||
# by excluding all of python we make way to just runu python tests in one seperate instance
|
||||
- env: PYTHON=true
|
||||
include:
|
||||
# using latest to run python on since it will last the longest
|
||||
- php: 7.1
|
||||
env: PYTHON=true
|
||||
- ENVIRONMENT=testing
|
||||
- LIBRETIME_LOG_DIR=/tmp/log/libretime
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- silan
|
||||
- liquidsoap
|
||||
- liquidsoap-plugin-mad
|
||||
- liquidsoap-plugin-taglib
|
||||
- liquidsoap-plugin-flac
|
||||
- liquidsoap-plugin-ogg
|
||||
- liquidsoap-plugin-lame
|
||||
- liquidsoap-plugin-faad
|
||||
- liquidsoap-plugin-vorbis
|
||||
- liquidsoap-plugin-opus
|
||||
- python-nose
|
||||
- python-rgain
|
||||
- python-gst-1.0
|
||||
- python-magic
|
||||
- mp3gain
|
||||
install:
|
||||
- >
|
||||
if [[ "$PYTHON" == false ]]; then
|
||||
composer install
|
||||
fi
|
||||
- >
|
||||
if [[ "$PYTHON" == true ]]; then
|
||||
pip install --user mkdocs
|
||||
pushd python_apps/airtime_analyzer
|
||||
python setup.py install --dry-run --no-init-script
|
||||
popd
|
||||
fi
|
||||
- gstreamer1.0-plugins-base
|
||||
- gstreamer1.0-plugins-good
|
||||
- gstreamer1.0-plugins-bad
|
||||
- gstreamer1.0-plugins-ugly
|
||||
- libgirepository1.0-dev
|
||||
- liquidsoap
|
||||
- liquidsoap-plugin-faad
|
||||
- liquidsoap-plugin-lame
|
||||
- liquidsoap-plugin-mad
|
||||
- liquidsoap-plugin-vorbis
|
||||
- python3-gst-1.0
|
||||
- silan
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- language: php
|
||||
php: 7.3
|
||||
stage: test
|
||||
- language: php
|
||||
php: 7.2
|
||||
stage: test
|
||||
- language: php
|
||||
php: 7.1
|
||||
stage: test
|
||||
- language: php
|
||||
php: 7.0
|
||||
stage: test
|
||||
- language: php
|
||||
php: 5.6
|
||||
stage: test
|
||||
- language: python
|
||||
python: 3.8
|
||||
stage: test
|
||||
- language: python
|
||||
python: 3.7
|
||||
stage: test
|
||||
- language: python
|
||||
python: 3.5
|
||||
stage: test
|
||||
- stage: deploy
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
dos2unix
|
||||
script:
|
||||
./travis/release.sh
|
||||
deploy:
|
||||
- provider: releases
|
||||
token: $GITHUB_TOKEN
|
||||
file: build/libretime-*.tar.gz
|
||||
edge: true
|
||||
on:
|
||||
tags: true
|
||||
allow_failures:
|
||||
# https://github.com/LibreTime/libretime/issues/779
|
||||
- language: php
|
||||
php: 7.3
|
||||
- language: php
|
||||
php: 7.2
|
||||
- language: php
|
||||
php: 7.1
|
||||
# https://github.com/LibreTime/libretime/issues/1041
|
||||
- language: python
|
||||
python: 3.5
|
||||
|
||||
install: ./travis/install.sh
|
||||
before_script:
|
||||
# prepare the database as per docs/testing.md
|
||||
- psql -c 'CREATE DATABASE libretime;' -U postgres
|
||||
- psql -c "CREATE USER libretime WITH PASSWORD 'libretime';" -U postgres
|
||||
- psql -c 'GRANT CONNECT ON DATABASE libretime TO libretime;' -U postgres
|
||||
- psql -c 'ALTER USER libretime CREATEDB;' -U postgres
|
||||
- mkdir -p /tmp/log/libretime
|
||||
script:
|
||||
- ./travis/php.sh
|
||||
- ./travis/python.sh
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
local_dir: build/docs
|
||||
github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard
|
||||
target_branch: master
|
||||
repo: LibreTime/LibreTime.github.io
|
||||
project_name: LibreTime
|
||||
fqdn: libretime.org
|
||||
name: R. LibreTime DocBot
|
||||
on:
|
||||
branch: master
|
||||
condition: $PYTHON = true
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: ./travis/release.sh
|
||||
on:
|
||||
tags: true
|
||||
condition: $PYTHON = true
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key: $GITHUB_TOKEN
|
||||
file_glob: true
|
||||
file: build/libretime-*.tar.gz
|
||||
on:
|
||||
tags: true
|
||||
condition: $PYTHON = true
|
||||
script: ./travis/test.sh
|
||||
|
|
401
.zfproject.xml
401
.zfproject.xml
|
@ -1,401 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<projectProfile type="default" version="1.10">
|
||||
<projectDirectory>
|
||||
<projectProfileFile filesystemName=".zfproject.xml"/>
|
||||
<applicationDirectory classNamePrefix="Application_">
|
||||
<apisDirectory enabled="false"/>
|
||||
<configsDirectory>
|
||||
<applicationConfigFile type="ini"/>
|
||||
</configsDirectory>
|
||||
<controllersDirectory>
|
||||
<controllerFile controllerName="Index">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="main"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Error">
|
||||
<actionMethod actionName="denied"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Playlist">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="new"/>
|
||||
<actionMethod actionName="metadata"/>
|
||||
<actionMethod actionName="edit"/>
|
||||
<actionMethod actionName="addItem"/>
|
||||
<actionMethod actionName="moveItem"/>
|
||||
<actionMethod actionName="deleteItem"/>
|
||||
<actionMethod actionName="setCue"/>
|
||||
<actionMethod actionName="setFade"/>
|
||||
<actionMethod actionName="delete"/>
|
||||
<actionMethod actionName="deleteActive"/>
|
||||
<actionMethod actionName="close"/>
|
||||
<actionMethod actionName="setPlaylistFades"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Library">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="contextMenu"/>
|
||||
<actionMethod actionName="delete"/>
|
||||
<actionMethod actionName="contents"/>
|
||||
<actionMethod actionName="editFileMd"/>
|
||||
<actionMethod actionName="getFileMetadata"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Plupload">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="upload"/>
|
||||
<actionMethod actionName="plupload"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Search">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="newfield"/>
|
||||
<actionMethod actionName="display"/>
|
||||
<actionMethod actionName="newgroup"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Login">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="logout"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Schedule">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="eventFeed"/>
|
||||
<actionMethod actionName="moveShow"/>
|
||||
<actionMethod actionName="resizeShow"/>
|
||||
<actionMethod actionName="deleteShow"/>
|
||||
<actionMethod actionName="makeContextMenu"/>
|
||||
<actionMethod actionName="scheduleShow"/>
|
||||
<actionMethod actionName="clearShow"/>
|
||||
<actionMethod actionName="findPlaylists"/>
|
||||
<actionMethod actionName="removeGroup"/>
|
||||
<actionMethod actionName="scheduleShowDialog"/>
|
||||
<actionMethod actionName="showList"/>
|
||||
<actionMethod actionName="getShowData"/>
|
||||
<actionMethod actionName="showContentDialog"/>
|
||||
<actionMethod actionName="editShow"/>
|
||||
<actionMethod actionName="addShow"/>
|
||||
<actionMethod actionName="cancelShow"/>
|
||||
<actionMethod actionName="cancelCurrentShow"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Api">
|
||||
<actionMethod actionName="index"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="User">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="addUser"/>
|
||||
<actionMethod actionName="getHosts"/>
|
||||
<actionMethod actionName="getUserDataTableInfo"/>
|
||||
<actionMethod actionName="getUserData"/>
|
||||
<actionMethod actionName="removeUser"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="SidePlaylist">
|
||||
<actionMethod actionName="index"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Nowplaying">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="getDataGridData"/>
|
||||
<actionMethod actionName="livestream"/>
|
||||
<actionMethod actionName="dayView"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Preference">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="update"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Dashboard">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="help"/>
|
||||
</controllerFile>
|
||||
<controllerFile controllerName="Recorder">
|
||||
<actionMethod actionName="index"/>
|
||||
<actionMethod actionName="getShowSchedule"/>
|
||||
</controllerFile>
|
||||
</controllersDirectory>
|
||||
<formsDirectory>
|
||||
<formFile formName="Login"/>
|
||||
<formFile formName="PlaylistMetadata"/>
|
||||
<formFile formName="AdvancedSearch"/>
|
||||
<formFile formName="AdvancedSearchRow"/>
|
||||
<formFile formName="EditAudioMD"/>
|
||||
<formFile formName="AddShow"/>
|
||||
<formFile formName="ScheduleShow"/>
|
||||
<formFile formName="AddUser"/>
|
||||
<formFile formName="AdvancedSearchGroup"/>
|
||||
<formFile formName="AddShowWhen"/>
|
||||
<formFile formName="AddShowWho"/>
|
||||
<formFile formName="AddShowStyle"/>
|
||||
<formFile formName="AddShowWhat"/>
|
||||
<formFile formName="AddShowRepeats"/>
|
||||
<formFile formName="Preferences"/>
|
||||
<formFile formName="AddShowRR"/>
|
||||
<formFile formName="AddShowRebroadcastDates"/>
|
||||
<formFile formName="AddShowAbsoluteRebroadcastDates"/>
|
||||
<formFile formName="SoundcloudPreferences"/>
|
||||
<formFile formName="GeneralPreferences"/>
|
||||
<formFile formName="WatchedDirPreferences"/>
|
||||
</formsDirectory>
|
||||
<layoutsDirectory enabled="false"/>
|
||||
<modelsDirectory>
|
||||
<modelFile modelName="Nowplaying"/>
|
||||
<modelFile modelName="Preference"/>
|
||||
<modelFile modelName="DateHelper"/>
|
||||
</modelsDirectory>
|
||||
<modulesDirectory enabled="false"/>
|
||||
<viewsDirectory>
|
||||
<viewScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Index">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Error">
|
||||
<viewScriptFile forActionName="error"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="new"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="metadata"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="edit"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="contextMenu"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="delete"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="contents"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Index">
|
||||
<viewScriptFile forActionName="main"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="addItem"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="moveItem"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="deleteItem"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="setCue"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="setFade"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="delete"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="deleteActive"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Index">
|
||||
<viewScriptFile forActionName="newfield"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Index">
|
||||
<viewScriptFile forActionName="display"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Plupload">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Plupload">
|
||||
<viewScriptFile forActionName="upload"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Plupload">
|
||||
<viewScriptFile forActionName="plupload"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Search">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Search">
|
||||
<viewScriptFile forActionName="newfield"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Search">
|
||||
<viewScriptFile forActionName="display"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Login">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Login">
|
||||
<viewScriptFile forActionName="logout"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="eventFeed"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Error">
|
||||
<viewScriptFile forActionName="denied"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="moveShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="resizeShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Api">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="deleteShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="makeContextMenu"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="scheduleShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="clearShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="addUser"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="close"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="editFileMd"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Search">
|
||||
<viewScriptFile forActionName="newgroup"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="findPlaylists"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="removeGroup"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="scheduleShowDialog"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Nowplaying">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Nowplaying">
|
||||
<viewScriptFile forActionName="getDataGridData"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="getHosts"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Nowplaying">
|
||||
<viewScriptFile forActionName="livestream"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="showList"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="getShowData"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="showContentDialog"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Preference">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Preference">
|
||||
<viewScriptFile forActionName="update"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Library">
|
||||
<viewScriptFile forActionName="getFileMetadata"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Nowplaying">
|
||||
<viewScriptFile forActionName="dayView"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="getUserDataTableInfo"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="getUserData"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="User">
|
||||
<viewScriptFile forActionName="removeUser"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Playlist">
|
||||
<viewScriptFile forActionName="setPlaylistFades"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="editShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="addShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Dashboard">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Dashboard">
|
||||
<viewScriptFile forActionName="help"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="cancelShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Recorder">
|
||||
<viewScriptFile forActionName="index"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Recorder">
|
||||
<viewScriptFile forActionName="getShowSchedule"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
<viewControllerScriptsDirectory forControllerName="Schedule">
|
||||
<viewScriptFile forActionName="cancelCurrentShow"/>
|
||||
</viewControllerScriptsDirectory>
|
||||
</viewScriptsDirectory>
|
||||
<viewHelpersDirectory/>
|
||||
<viewFiltersDirectory enabled="false"/>
|
||||
</viewsDirectory>
|
||||
<bootstrapFile filesystemName="Bootstrap.php"/>
|
||||
</applicationDirectory>
|
||||
<dataDirectory enabled="false">
|
||||
<cacheDirectory enabled="false"/>
|
||||
<searchIndexesDirectory enabled="false"/>
|
||||
<localesDirectory enabled="false"/>
|
||||
<logsDirectory enabled="false"/>
|
||||
<sessionsDirectory enabled="false"/>
|
||||
<uploadsDirectory enabled="false"/>
|
||||
</dataDirectory>
|
||||
<docsDirectory>
|
||||
<file filesystemName="README.txt"/>
|
||||
</docsDirectory>
|
||||
<libraryDirectory>
|
||||
<zfStandardLibraryDirectory enabled="false"/>
|
||||
</libraryDirectory>
|
||||
<publicDirectory>
|
||||
<publicStylesheetsDirectory enabled="false"/>
|
||||
<publicScriptsDirectory enabled="false"/>
|
||||
<publicImagesDirectory enabled="false"/>
|
||||
<publicIndexFile filesystemName="index.php"/>
|
||||
<htaccessFile filesystemName=".htaccess"/>
|
||||
</publicDirectory>
|
||||
<projectProvidersDirectory enabled="false"/>
|
||||
<temporaryDirectory enabled="false"/>
|
||||
<testsDirectory>
|
||||
<testPHPUnitConfigFile filesystemName="phpunit.xml"/>
|
||||
<testApplicationDirectory>
|
||||
<testApplicationBootstrapFile filesystemName="bootstrap.php"/>
|
||||
<testApplicationControllerDirectory>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
<testApplicationControllerFile/>
|
||||
</testApplicationControllerDirectory>
|
||||
</testApplicationDirectory>
|
||||
<testLibraryDirectory>
|
||||
<testLibraryBootstrapFile filesystemName="bootstrap.php"/>
|
||||
</testLibraryDirectory>
|
||||
</testsDirectory>
|
||||
</projectDirectory>
|
||||
</projectProfile>
|
|
@ -22,7 +22,7 @@ Common Non-linked Code
|
|||
Airtime Web
|
||||
-----------
|
||||
Linked code:
|
||||
* Zend Framework 1.10.3
|
||||
* Zend Framework 1.10.3
|
||||
- What is it: Framework for PHP web apps
|
||||
- Web site: http://framework.zend.com/
|
||||
- License: New BSD license
|
||||
|
@ -32,7 +32,7 @@ Linked code:
|
|||
- What is it: PHP library
|
||||
- Notes: We only use the PEAR base class PEAR_Error, in the "PEAR" PEAR library.
|
||||
- License: New BSD License
|
||||
- Compatible with GPLv3? Yes.
|
||||
- Compatible with GPLv3? Yes.
|
||||
|
||||
* Propel ORM
|
||||
- What is it: Maps DB data into PHP objects
|
||||
|
@ -40,7 +40,7 @@ Linked code:
|
|||
- License: MIT/Expat License
|
||||
- Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
|
||||
|
||||
* Phing
|
||||
* Phing
|
||||
- What is it: PHP project build system
|
||||
- Web site: http://phing.info/trac/
|
||||
- Note: Only used for development, not needed to run Airtime.
|
||||
|
@ -48,22 +48,27 @@ Linked code:
|
|||
|
||||
* PHP-AMQPLIB
|
||||
- What is it: PHP library to interact with RabbitMQ
|
||||
- Web site: https://github.com/tnc/php-amqplib
|
||||
- Web site: https://github.com/tnc/php-amqplib
|
||||
- License: LGPLv2.1
|
||||
- Compatible with GPLv3? Yes
|
||||
|
||||
* Soundcloud PHP API wrapper
|
||||
- What is it: PHP library to upload to SoundCloud
|
||||
- Web site: https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
|
||||
- License: MIT
|
||||
- License: MIT
|
||||
- Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
|
||||
|
||||
* getID3()
|
||||
- What is it: PHP script that extracts useful information from MP3s & other multimedia file formats:
|
||||
- Web site: https://github.com/JamesHeinrich/getID3
|
||||
- License: GPLv3
|
||||
|
||||
Non-linked code:
|
||||
* Apache Web Server 2.2
|
||||
* Apache Web Server 2.2
|
||||
- Web site: http://httpd.apache.org/
|
||||
- License: Apache 2.0. See http://httpd.apache.org/docs/2.2/license.html
|
||||
|
||||
* PostgreSQL 9.1
|
||||
* PostgreSQL 9.1
|
||||
- Web site: http://www.postgresql.org/
|
||||
- License: The PostgreSQL License. See http://www.postgresql.org/about/licence
|
||||
|
||||
|
@ -71,22 +76,22 @@ Non-linked code:
|
|||
- Web site: http://www.php.net/
|
||||
- License: The PHP License. See http://www.php.net/license/3_01.txt
|
||||
|
||||
* jQuery
|
||||
* jQuery
|
||||
- Web site: http://jquery.com/
|
||||
- License: MIT and GPL. See http://jquery.org/license
|
||||
|
||||
- jQuery components used:
|
||||
* Full Calendar
|
||||
* Full Calendar
|
||||
- Web site: http://arshaw.com/fullcalendar/
|
||||
- License: Dual licensed under MIT and GPLv2
|
||||
|
||||
* Colorpicker
|
||||
* Colorpicker
|
||||
- Web site: http://www.eyecon.ro/colorpicker/
|
||||
- License: Dual licensed under the MIT and GPL licenses.
|
||||
|
||||
* Context Menu
|
||||
- Web site: http://jursza.net/dev/jjmenu/
|
||||
- License: MIT [http://www.opensource.org/licenses/mit-license.php]
|
||||
- License: MIT [http://www.opensource.org/licenses/mit-license.php]
|
||||
|
||||
* PLUpload
|
||||
- Web site: http://www.plupload.com
|
||||
|
@ -98,8 +103,8 @@ Non-linked code:
|
|||
|
||||
* qtip
|
||||
- Web site: http://craigsworks.com/projects/qtip/
|
||||
- License: MIT
|
||||
|
||||
- License: MIT
|
||||
|
||||
* TimePicker
|
||||
- Web site: http://fgelinas.com/code/timepicker/
|
||||
- License: Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
|
@ -120,7 +125,7 @@ Non-linked code:
|
|||
Media-Monitor
|
||||
-------------
|
||||
Linked code:
|
||||
* Mutagen
|
||||
* Mutagen
|
||||
- What is it: Parser of audio file metadata
|
||||
- Web site: http://code.google.com/p/mutagen/
|
||||
- License: GPLv2-only
|
||||
|
@ -129,7 +134,7 @@ Linked code:
|
|||
- What is it: Python interface to RabbitMQ
|
||||
- Web site: http://pypi.python.org/pypi/kombu/
|
||||
- License: New BSD
|
||||
- Compatible with GPLv3? Yes.
|
||||
- Compatible with GPLv3? Yes.
|
||||
|
||||
* pyinotify
|
||||
- Python interface to inotify
|
||||
|
@ -155,7 +160,7 @@ Linked code:
|
|||
- What is it: Python interface to RabbitMQ
|
||||
- Web site: http://pypi.python.org/pypi/kombu/
|
||||
- License: New BSD
|
||||
- Compatible with GPLv3? Yes.
|
||||
- Compatible with GPLv3? Yes.
|
||||
|
||||
Non-linked code:
|
||||
* Python 2.7
|
||||
|
@ -174,7 +179,7 @@ Linked code:
|
|||
* Kombu
|
||||
- Web site: http://pypi.python.org/pypi/kombu/
|
||||
- License: New BSD
|
||||
- Compatible with GPLv3? Yes.
|
||||
- Compatible with GPLv3? Yes.
|
||||
|
||||
Non-linked code:
|
||||
* Python 2.7
|
||||
|
|
84
README
84
README
|
@ -1,84 +0,0 @@
|
|||
=========================================================================
|
||||
================= Airtime - Live Broadcast Together =================
|
||||
=========================================================================
|
||||
|
||||
Airtime is an open source application that provides remote and
|
||||
collaborative automation of a broadcast radio station.
|
||||
|
||||
Home page: http://www.sourcefabric.org/en/airtime/
|
||||
|
||||
Major features:
|
||||
|
||||
* Web-based remote station management. Authorized personnel can add
|
||||
programme material, create playlists or smart blocks, and stream in live,
|
||||
all via a web interface.
|
||||
* Automation. Airtime has a scheduler function that enables users to
|
||||
create shows with content for playback at the exact date and time specified.
|
||||
Playlists, smart blocks and remote stream URLs can be used multiple times.
|
||||
* Solid playout. Airtime uses the open source Liquidsoap streaming language
|
||||
for reliable and precise playback to multiple outputs.
|
||||
* Open, extensible architecture. Stations are free to extend and alter
|
||||
all parts of the program code, under the GNU AGPLv3 license.
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
Basic installation has two steps:
|
||||
|
||||
1) Run the install script, located in the Airtime root directory.
|
||||
|
||||
For an interactive installation, run:
|
||||
|
||||
sudo ./install
|
||||
|
||||
If you're using a terminal that is not running Bash, you'll need to run
|
||||
|
||||
sudo /bin/bash ./install
|
||||
|
||||
instead. You may need to install Bash first.
|
||||
|
||||
The installer will then prompt you about how you want to set up your Airtime
|
||||
installation.
|
||||
|
||||
For a non-interactive full installation (do this if you're installing Airtime from
|
||||
scratch and don't have any of your own configuration set up), run
|
||||
|
||||
sudo ./install -fiap
|
||||
|
||||
What this means:
|
||||
|
||||
-f - force; non-interactive (no prompts)
|
||||
-i - install the default Icecast 2 setup for Airtime
|
||||
-a - install the default apache setup for Airtime
|
||||
-p - create a default Airtime postgres user
|
||||
|
||||
This will install all components necessary for Airtime, and set up
|
||||
/usr/share/airtime as your web root (where apache looks for your Airtime files)
|
||||
|
||||
There are several options for installation - to see them all, run
|
||||
|
||||
sudo ./install --help
|
||||
|
||||
2) Once you've run the installer, open a web browser to http://localhost to run
|
||||
the interactive setup. (If you have a custom apache configuration, navigate to
|
||||
your Airtime web host instead.)
|
||||
|
||||
If you just want to run Airtime with default settings, you won't need to change
|
||||
anything, but if you have any custom configuration settings you'll be able to
|
||||
specify them.
|
||||
|
||||
Once you finish the setup process, you'll be presented with a configuration
|
||||
checklist so you can ensure that your Airtime installation is working
|
||||
correctly. If anything was mis-configured, the checklist will provide some .
|
||||
helpful tips to resolve the issue.
|
||||
|
||||
If your checklist is all green, you're ready to get started with Airtime!
|
||||
|
||||
Quick links to our resources
|
||||
----------------------------
|
||||
User manual: http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/
|
||||
Forums and mailing lists: http://forum.sourcefabric.org
|
||||
Bug tracker: http://dev.sourcefabric.org
|
||||
Source code: http://github.com/sourcefabric/Airtime
|
||||
IRC chat: #airtime on Freenode
|
55
README.md
55
README.md
|
@ -1,17 +1,19 @@
|
|||
# LibreTime
|
||||

|
||||
|
||||
[](https://travis-ci.org/LibreTime/libretime)
|
||||
[](https://opencollective.com/libretime)
|
||||
|
||||
LibreTime makes it easy to run your own online or terrestrial radio station. It is a community managed fork of the AirTime project.
|
||||
LibreTime makes it easy to run your own online or terrestrial radio station. It
|
||||
is a community managed fork of the AirTime project.
|
||||
|
||||
It is managed by a friendly inclusive community of stations
|
||||
from around the globe that use, document and improve LibreTime.
|
||||
Join us in fixing bugs and in defining how we manage the
|
||||
codebase going forward.
|
||||
It is managed by a friendly inclusive community of stations from around the
|
||||
globe that use, document and improve LibreTime. Join us in fixing bugs and in
|
||||
defining how we manage the codebase going forward.
|
||||
|
||||
We are currently ramping up development on this repository.
|
||||
|
||||
Check out the [documentation](http://libretime.org) for more information and start broadcasting!
|
||||
Check out the [documentation](http://libretime.org) for more information and
|
||||
start broadcasting!
|
||||
|
||||
Please note that LibreTime is released with a [Contributor Code
|
||||
of Conduct](https://github.com/LibreTime/code-of-conduct/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
@ -55,7 +57,44 @@ up and running.
|
|||
|
||||
## Support
|
||||
|
||||
To get support for any questions or problems you might have using the software we have a forum at [discourse.libretime.org](http://discourse.libretime.org). We are moving towards using the forum to provide community support and reserving the github issue queue for confirmed bugs and well-formed feature requests.
|
||||
To get support for any questions or problems you might have using the software
|
||||
we have a forum at [discourse.libretime.org](http://discourse.libretime.org).
|
||||
We are moving towards using the forum to provide community support and reserving
|
||||
the github issue queue for confirmed bugs and well-formed feature requests.
|
||||
|
||||
You can also contact us through our [Mattermost instance](https://chat.libretime.org)
|
||||
where you can talk with other users and developers.
|
||||
|
||||
## Contributors
|
||||
|
||||
### Code Contributors
|
||||
|
||||
This project exists thanks to all the people who [contribute](CONTRIBUTING.md).
|
||||
|
||||
### Financial Contributors
|
||||
|
||||
Become a financial contributor and help us sustain our community on
|
||||
[OpenCollective](https://opencollective.com/libretime/contribute).
|
||||
|
||||
#### Individuals
|
||||
|
||||
<a href="https://opencollective.com/libretime"><img src="https://opencollective.com/libretime/individuals.svg?width=890"></a>
|
||||
|
||||
#### Organizations
|
||||
|
||||
[Support](https://opencollective.com/libretime/contribute) this project with
|
||||
your organization. Your logo will show up here with a link to your website.
|
||||
|
||||
<a href="https://opencollective.com/libretime/organization/0/website"><img src="https://opencollective.com/libretime/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/1/website"><img src="https://opencollective.com/libretime/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/2/website"><img src="https://opencollective.com/libretime/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/3/website"><img src="https://opencollective.com/libretime/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/4/website"><img src="https://opencollective.com/libretime/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/5/website"><img src="https://opencollective.com/libretime/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/6/website"><img src="https://opencollective.com/libretime/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/7/website"><img src="https://opencollective.com/libretime/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/8/website"><img src="https://opencollective.com/libretime/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libretime/organization/9/website"><img src="https://opencollective.com/libretime/organization/9/avatar.svg"></a>
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -9,13 +9,15 @@ Vagrant.configure("2") do |config|
|
|||
config.vm.network "forwarded_port", guest: 8000, host:8000
|
||||
# liquidsoap input harbors for instreaming (ie. /master)
|
||||
config.vm.network "forwarded_port", guest: 8001, host:8001
|
||||
config.vm.network "forwarded_port", guest: 8002, host:8002
|
||||
# mkdocs documentation
|
||||
config.vm.network "forwarded_port", guest: 8888, host:8888
|
||||
|
||||
config.vm.network "forwarded_port", guest: 8002, host:8002
|
||||
|
||||
# make sure we are using nfs (doesn't work out of the box with debian)
|
||||
config.vm.synced_folder ".", "/vagrant", type: "nfs"
|
||||
nfsPath = "."
|
||||
# macOS Catalina support
|
||||
if Dir.exist?("/System/Volumes/Data")
|
||||
nfsPath = "/System/Volumes/Data" + Dir.pwd
|
||||
end
|
||||
config.vm.synced_folder nfsPath, "/vagrant", type: "nfs"
|
||||
# private network for nfs
|
||||
config.vm.network "private_network", ip: "192.168.10.100"
|
||||
|
||||
|
@ -40,30 +42,18 @@ Vagrant.configure("2") do |config|
|
|||
# define all the OS boxes we support
|
||||
config.vm.define "ubuntu-bionic" do |os|
|
||||
os.vm.box = "bento/ubuntu-18.04"
|
||||
provision_libretime(os, "ubuntu.sh", installer_args)
|
||||
provision_libretime(os, "debian.sh", installer_args)
|
||||
end
|
||||
config.vm.define "ubuntu-xenial" do |os|
|
||||
os.vm.box = "bento/ubuntu-16.04"
|
||||
provision_libretime(os, "ubuntu.sh", installer_args)
|
||||
end
|
||||
config.vm.define "ubuntu-trusty" do |os|
|
||||
STDERR.puts 'WARNING: The "ubuntu-trusty" option is deprecated. Please migrate to "ubuntu-bionic".'
|
||||
STDERR.puts
|
||||
os.vm.box = "bento/ubuntu-14.04"
|
||||
provision_libretime(os, "ubuntu.sh", installer_args)
|
||||
end
|
||||
config.vm.define "debian-jessie" do |os|
|
||||
os.vm.box = "bento/debian-8.7"
|
||||
provision_libretime(os, "debian.sh", installer_args)
|
||||
end
|
||||
config.vm.define "debian-stretch" do |os|
|
||||
os.vm.box = "bento/debian-9.2"
|
||||
os.vm.box = "bento/debian-9"
|
||||
provision_libretime(os, "debian.sh", installer_args)
|
||||
end
|
||||
config.vm.define "debian-wheezy" do |os|
|
||||
STDERR.puts 'WARNING: The "debian-wheezy" option is deprecated. Please migrate to "debian-stretch".'
|
||||
STDERR.puts
|
||||
os.vm.box = "bento/debian-7.11"
|
||||
config.vm.define "debian-buster" do |os|
|
||||
os.vm.box = "bento/debian-10"
|
||||
provision_libretime(os, "debian.sh", installer_args)
|
||||
end
|
||||
config.vm.define "centos" do |os|
|
||||
|
@ -79,8 +69,7 @@ Vagrant.configure("2") do |config|
|
|||
config.vm.provision "install", type: "shell", inline: "cd /vagrant; ./install %s --web-port=8080" % installer_args
|
||||
|
||||
# Provision docs
|
||||
config.vm.provision "install-mkdocs", type: "shell", path: "docs/scripts/install.sh"
|
||||
config.vm.provision "start-mkdocs", type: "shell", path: "docs/scripts/serve.sh"
|
||||
config.vm.provision "build-site-jekyll", type: "shell", path: "docs/jekyll.sh"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -14,13 +14,6 @@ require_once CONFIG_PATH . "constants.php";
|
|||
|
||||
Logging::setLogPath(LIBRETIME_LOG_DIR . '/zendphp.log');
|
||||
|
||||
// We need to manually route because we can't load Zend without the database being initialized first.
|
||||
if (array_key_exists("REQUEST_URI", $_SERVER) && (stripos($_SERVER["REQUEST_URI"], "/provisioning/create") !== false)) {
|
||||
$provisioningHelper = new ProvisioningHelper($CC_CONFIG["apiKey"][0]);
|
||||
$provisioningHelper->createAction();
|
||||
die();
|
||||
}
|
||||
|
||||
Zend_Session::setOptions(array('strict' => true));
|
||||
Config::setAirtimeVersion();
|
||||
require_once (CONFIG_PATH . 'navigation.php');
|
||||
|
@ -29,7 +22,6 @@ Zend_Validate::setDefaultNamespaces("Zend");
|
|||
|
||||
$front = Zend_Controller_Front::getInstance();
|
||||
$front->registerPlugin(new RabbitMqPlugin());
|
||||
$front->registerPlugin(new Zend_Controller_Plugin_ConversionTracking());
|
||||
$front->throwExceptions(false);
|
||||
|
||||
/* The bootstrap class should only be used to initialize actions that return a view.
|
||||
|
@ -43,29 +35,14 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$view->doctype('XHTML1_STRICT');
|
||||
}
|
||||
|
||||
protected function _initZFDebug()
|
||||
/**
|
||||
* initialize front controller
|
||||
*
|
||||
* This is call ZFrontController to ensure it is executed last in the bootstrap process.
|
||||
*/
|
||||
protected function _initZFrontController()
|
||||
{
|
||||
|
||||
Zend_Controller_Front::getInstance()->throwExceptions(false);
|
||||
|
||||
/*
|
||||
if (APPLICATION_ENV == "development") {
|
||||
$autoloader = Zend_Loader_Autoloader::getInstance();
|
||||
$autoloader->registerNamespace('ZFDebug');
|
||||
|
||||
$options = array(
|
||||
'plugins' => array('Variables',
|
||||
'Exception',
|
||||
'Memory',
|
||||
'Time')
|
||||
);
|
||||
$debug = new ZFDebug_Controller_Plugin_Debug($options);
|
||||
|
||||
$this->bootstrap('frontController');
|
||||
$frontController = $this->getResource('frontController');
|
||||
$frontController->registerPlugin($debug);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
protected function _initRouter()
|
||||
|
|
|
@ -64,10 +64,10 @@ set_include_path(APPLICATION_PATH . '/common/' . PATH_SEPARATOR . get_include_pa
|
|||
require_once 'autoload.php';
|
||||
|
||||
/** Zend_Application */
|
||||
require_once 'Zend/Application.php';
|
||||
$application = new Zend_Application(
|
||||
APPLICATION_ENV,
|
||||
CONFIG_PATH . 'application.ini'
|
||||
CONFIG_PATH . 'application.ini',
|
||||
true
|
||||
);
|
||||
|
||||
require_once(APPLICATION_PATH . "logging/Logging.php");
|
||||
|
|
|
@ -13,7 +13,6 @@ class AutoPlaylistManager {
|
|||
* @return bool true if $_AUTOPLAYLIST_POLL_INTERVAL_SECONDS has passed since the last check
|
||||
*/
|
||||
public static function hasAutoPlaylistPollIntervalPassed() {
|
||||
Logging::info("Checking autoplaylist poll");
|
||||
$lastPolled = Application_Model_Preference::getAutoPlaylistPollLock();
|
||||
return empty($lastPolled) || (microtime(true) > $lastPolled + self::$_AUTOPLAYLIST_POLL_INTERVAL_SECONDS);
|
||||
}
|
||||
|
@ -23,35 +22,63 @@ class AutoPlaylistManager {
|
|||
*
|
||||
*/
|
||||
public static function buildAutoPlaylist() {
|
||||
Logging::info("Checking to run Auto Playlist");
|
||||
$autoPlaylists = static::_upcomingAutoPlaylistShows();
|
||||
foreach ($autoPlaylists as $autoplaylist) {
|
||||
// creates a ShowInstance object to build the playlist in from the ShowInstancesQuery Object
|
||||
$si = new Application_Model_ShowInstance($autoplaylist->getDbId());
|
||||
$playlistid = $si->GetAutoPlaylistId();
|
||||
Logging::info("Scheduling $playlistid");
|
||||
// call the addPlaylist to show function and don't check for user permission to avoid call to non-existant user object
|
||||
$sid = $si->getShowId();
|
||||
$playlistrepeat = new Application_Model_Show($sid);
|
||||
$introplaylistid = Application_Model_Preference::GetIntroPlaylist();
|
||||
$outroplaylistid = Application_Model_Preference::GetOutroPlaylist();
|
||||
|
||||
if ($playlistrepeat->getAutoPlaylistRepeat()) {
|
||||
$full = false;
|
||||
while(!$full) {
|
||||
$si = new Application_Model_ShowInstance($autoplaylist->getDbId());
|
||||
$si->addPlaylistToShow($playlistid, false);
|
||||
$ps = $si->getPercentScheduled();
|
||||
//Logging::info("The total percent scheduled is % $ps");
|
||||
if ($ps > 100) {
|
||||
$full = true;
|
||||
}
|
||||
|
||||
}
|
||||
// we want to check and see if we need to repeat this process until the show is 100% scheduled
|
||||
// so we create a while loop and break it immediately if repeat until full isn't enabled
|
||||
// otherwise we continue to go through adding playlists, including the intro and outro if enabled
|
||||
$full = false;
|
||||
$repeatuntilfull = $playlistrepeat->getAutoPlaylistRepeat();
|
||||
$tempPercentScheduled = 0;
|
||||
$si = new Application_Model_ShowInstance($autoplaylist->getDbId());
|
||||
// the intro playlist should be added exactly once
|
||||
if ($introplaylistid != null) {
|
||||
//Logging::info('adding intro');
|
||||
$si->addPlaylistToShowStart($introplaylistid, false);
|
||||
}
|
||||
else {
|
||||
$si->addPlaylistToShow($playlistid, false);
|
||||
while(!$full) {
|
||||
// we do not want to try to schedule an empty playlist
|
||||
if ($playlistid != null) {
|
||||
$si->addPlaylistToShow($playlistid, false);
|
||||
}
|
||||
$ps = $si->getPercentScheduled();
|
||||
if ($ps > 100) {
|
||||
$full = true;
|
||||
}
|
||||
elseif (!$repeatuntilfull) {
|
||||
break;
|
||||
}
|
||||
// we want to avoid an infinite loop if all of the playlists are null
|
||||
if ($playlistid == null) {
|
||||
break;
|
||||
}
|
||||
// another possible issue would be if the show isn't increasing in length each loop
|
||||
// ie if all of the playlists being added are zero lengths this could cause an infinite loop
|
||||
if ($tempPercentScheduled == $ps) {
|
||||
break;
|
||||
}
|
||||
//now reset it to the current percent scheduled
|
||||
$tempPercentScheduled = $ps;
|
||||
}
|
||||
// the outroplaylist is added at the end, it will always overbook
|
||||
// shows that have repeat until full enabled because they will
|
||||
// never have time remaining for the outroplaylist to be added
|
||||
// this is done outside the content loop to avoid a scenario
|
||||
// where a time remaining smartblock in a outro playlist
|
||||
// prevents the repeat until full from functioning by filling up the show
|
||||
if ($outroplaylistid != null) {
|
||||
$si->addPlaylistToShow($outroplaylistid, false);
|
||||
}
|
||||
$si->setAutoPlaylistBuilt(true);
|
||||
|
||||
}
|
||||
Application_Model_Preference::setAutoPlaylistPollLock(microtime(true));
|
||||
}
|
||||
|
|
|
@ -1,439 +0,0 @@
|
|||
<?php
|
||||
|
||||
define("AIRTIME_PRO_FREE_TRIAL_PLAN_ID", 34);
|
||||
define("WHMCS_AIRTIME_GROUP_ID", 15);
|
||||
|
||||
class Billing
|
||||
{
|
||||
// TODO: remove this once all existing customers have bandwidth limits set
|
||||
public static $PLAN_TYPE_DEFAULTS = array(
|
||||
"trial" => array(
|
||||
"bandwidth_limit" => 3298534883328
|
||||
),
|
||||
"hobbyist" => array(
|
||||
"bandwidth_limit" => 1099511627776
|
||||
),
|
||||
"starter" => array(
|
||||
"bandwidth_limit" => 3298534883328
|
||||
),
|
||||
"starter2" => array(
|
||||
"bandwidth_limit" => 3298534883328
|
||||
),
|
||||
"plus" => array(
|
||||
"bandwidth_limit" => 10995116277760
|
||||
),
|
||||
"plus2" => array(
|
||||
"bandwidth_limit" => 10995116277760
|
||||
),
|
||||
"premium" => array(
|
||||
"bandwidth_limit" => 43980465111040
|
||||
),
|
||||
"premium2" => array(
|
||||
"bandwidth_limit" => 43980465111040
|
||||
),
|
||||
"enterprise" => array(
|
||||
"bandwidth_limit" => 164926744166400
|
||||
),
|
||||
"complimentary" => array(
|
||||
"bandwidth_limit" => 32985348833280
|
||||
),
|
||||
"sida" => array(
|
||||
"bandwidth_limit" => 32985348833280
|
||||
),
|
||||
"custom" => array(
|
||||
"bandwidth_limit" => 10995116277760
|
||||
),
|
||||
"awesome-hobbyist-2015" => array(
|
||||
"bandwidth_limit" => 1099511627776
|
||||
),
|
||||
"awesome-starter-2015" => array(
|
||||
"bandwidth_limit" => 3298534883328
|
||||
),
|
||||
"awesome-plus-2015" => array(
|
||||
"bandwidth_limit" => 10995116277760
|
||||
),
|
||||
"awesome-premium-2015" => array(
|
||||
"bandwidth_limit" => 43980465111040
|
||||
),
|
||||
);
|
||||
|
||||
public static function getAPICredentials()
|
||||
{
|
||||
return array(
|
||||
"username" => $_SERVER["WHMCS_USERNAME"],
|
||||
"password" => $_SERVER["WHMCS_PASSWORD"],
|
||||
"url" => "https://account.sourcefabric.com/includes/api.php?accesskey=".$_SERVER["WHMCS_ACCESS_KEY"],
|
||||
);
|
||||
}
|
||||
|
||||
/** Get the Airtime instance ID of the instance the customer is currently viewing. */
|
||||
public static function getClientInstanceId()
|
||||
{
|
||||
//$currentProduct = Billing::getClientCurrentAirtimeProduct();
|
||||
//return $currentProduct["id"];
|
||||
//XXX: Major hack attack. Since this function gets called often, rather than querying WHMCS
|
||||
// we're just going to extract it from airtime.conf since it's the same as the rabbitmq username.
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$instanceId = $CC_CONFIG['rabbitmq']['user'];
|
||||
if (!is_numeric($instanceId)) {
|
||||
throw new Exception("Invalid instance id in " . __FUNCTION__ . ": " . $instanceId);
|
||||
}
|
||||
return $instanceId;
|
||||
}
|
||||
|
||||
public static function getProducts()
|
||||
{
|
||||
//Making this static to cache the products during a single HTTP request.
|
||||
//This saves us roundtrips to WHMCS if getProducts() is called multiple times.
|
||||
static $products = array();
|
||||
if (!empty($products))
|
||||
{
|
||||
return $products;
|
||||
}
|
||||
|
||||
$credentials = self::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getproducts";
|
||||
$postfields["responsetype"] = "json";
|
||||
//gid is the Airtime product group id on whmcs
|
||||
$postfields["gid"] = WHMCS_AIRTIME_GROUP_ID;
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = self::makeRequest($credentials["url"], $query_string);
|
||||
//Logging::info($result["products"]["product"]);
|
||||
$products = $result["products"]["product"];
|
||||
|
||||
//Blacklist all free plans
|
||||
//Hide the promo plans - we will tell the user if they are eligible for a promo plan
|
||||
foreach ($products as $k => $p) {
|
||||
if ($p["paytype"] === "free" || strpos($p["name"], "Awesome August 2015") !== false)
|
||||
{
|
||||
unset($products[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
return $products;
|
||||
}
|
||||
|
||||
public static function getProductPricesAndTypes()
|
||||
{
|
||||
$products = Billing::getProducts();
|
||||
$productPrices = array();
|
||||
$productTypes = array();
|
||||
|
||||
foreach ($products as $k => $p) {
|
||||
$productPrices[$p["name"]] = array(
|
||||
"monthly" => $p["pricing"]["USD"]["monthly"],
|
||||
"annually" => $p["pricing"]["USD"]["annually"]
|
||||
);
|
||||
$productTypes[$p["pid"]] = $p["name"] . " ($" . $productPrices[$p['name']]['monthly'] . "/mo)";
|
||||
}
|
||||
return array($productPrices, $productTypes);
|
||||
}
|
||||
|
||||
/** Get the plan (or product in WHMCS lingo) that the customer is currently on.
|
||||
* @return An associative array containing the fields for the product
|
||||
* */
|
||||
public static function getClientCurrentAirtimeProduct()
|
||||
{
|
||||
static $airtimeProduct = null;
|
||||
//Ghetto caching to avoid multiple round trips to WHMCS
|
||||
if ($airtimeProduct) {
|
||||
return $airtimeProduct;
|
||||
}
|
||||
$credentials = self::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getclientsproducts";
|
||||
$postfields["responsetype"] = "json";
|
||||
$postfields["clientid"] = Application_Model_Preference::GetClientId();
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = self::makeRequest($credentials["url"], $query_string);
|
||||
|
||||
//XXX: Debugging / local testing
|
||||
if ($_SERVER['SERVER_NAME'] == "localhost") {
|
||||
$_SERVER['SERVER_NAME'] = "bananas.airtime.pro";
|
||||
}
|
||||
|
||||
//This code must run on airtime.pro for it to work... it's trying to match
|
||||
//the server's hostname with the client subdomain. Once it finds a match
|
||||
//between the product and the server's hostname/subdomain, then it
|
||||
//returns the ID of that product (aka. the service ID of an Airtime instance)
|
||||
foreach ($result["products"]["product"] as $product)
|
||||
{
|
||||
if (strpos($product["groupname"], "Airtime") === FALSE)
|
||||
{
|
||||
//Ignore non-Airtime products
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($product["status"] === "Active" ||
|
||||
$product["status"] === "Suspended") {
|
||||
$airtimeProduct = $product;
|
||||
$subdomain = '';
|
||||
|
||||
foreach ($airtimeProduct['customfields']['customfield'] as $customField) {
|
||||
if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME) {
|
||||
$subdomain = $customField['value'];
|
||||
if (($subdomain . ".airtime.pro") === $_SERVER['SERVER_NAME']) {
|
||||
return $airtimeProduct;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("Unable to match subdomain to a service ID");
|
||||
}
|
||||
|
||||
public static function getClientDetails()
|
||||
{
|
||||
try {
|
||||
$credentials = self::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getclientsdetails";
|
||||
$postfields["stats"] = true;
|
||||
$postfields["clientid"] = Application_Model_Preference::GetClientId();
|
||||
$postfields["responsetype"] = "json";
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$arr = self::makeRequest($credentials["url"], $query_string);
|
||||
return $arr["client"];
|
||||
} catch (Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function makeRequest($url, $query_string) {
|
||||
try {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); // WHMCS IP whitelist doesn't support IPv6
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //Aggressive 5 second timeout
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
$jsondata = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
//die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch));
|
||||
throw new Exception("WHMCS server down or invalid request.");
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
return json_decode($jsondata, true);
|
||||
} catch (Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function ensureClientIdIsValid()
|
||||
{
|
||||
if (Application_Model_Preference::GetClientId() == null)
|
||||
{
|
||||
throw new Exception("Invalid client ID: " . Application_Model_Preference::GetClientId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return True if VAT should be applied to the order, false otherwise.
|
||||
*/
|
||||
public static function checkIfVatShouldBeApplied($vatNumber, $countryCode)
|
||||
{
|
||||
if ($countryCode === 'UK') {
|
||||
$countryCode = 'GB'; //VIES database has it as GB
|
||||
}
|
||||
//We don't charge you VAT if you're not in the EU
|
||||
if (!Billing::isCountryInEU($countryCode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//So by here, we know you're in the EU.
|
||||
|
||||
//No VAT number? Then we charge you VAT.
|
||||
if (empty($vatNumber)) {
|
||||
return true;
|
||||
}
|
||||
//Check if VAT number is valid
|
||||
return Billing::validateVATNumber($vatNumber, $countryCode);
|
||||
}
|
||||
|
||||
public static function isCountryInEU($countryCode)
|
||||
{
|
||||
$euCountryCodes = array('BE', 'BG', 'CZ', 'DK', 'DE', 'EE', 'IE', 'EL', 'ES', 'FR',
|
||||
'HR', 'IT', 'CY', 'LV', 'LT', 'LU', 'HU', 'MT', 'NL', 'AT',
|
||||
'PL', 'PT', 'RO', 'SI', 'SK', 'FI', 'SE', 'UK', 'GB');
|
||||
|
||||
if (!in_array($countryCode, $euCountryCodes)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an EU VAT number is valid, using the EU VIES validation web API.
|
||||
*
|
||||
* @param string $vatNumber - A VAT identifier (number), with or without the two letter country code at the
|
||||
* start (either one works) .
|
||||
* @param string $countryCode - A two letter country code
|
||||
* @return boolean true if the VAT number is valid, false otherwise.
|
||||
*/
|
||||
public static function validateVATNumber($vatNumber, $countryCode)
|
||||
{
|
||||
$vatNumber = str_replace(array(' ', '.', '-', ',', ', '), '', trim($vatNumber));
|
||||
|
||||
//If the first two letters are a country code, use that as the country code and remove those letters.
|
||||
$firstTwoCharacters = substr($vatNumber, 0, 2);
|
||||
if (preg_match("/[a-zA-Z][a-zA-Z]/", $firstTwoCharacters) === 1) {
|
||||
$countryCode = strtoupper($firstTwoCharacters); //The country code from the VAT number overrides your country.
|
||||
$vatNumber = substr($vatNumber, 2);
|
||||
}
|
||||
$client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");
|
||||
|
||||
if($client){
|
||||
$params = array('countryCode' => $countryCode, 'vatNumber' => $vatNumber);
|
||||
try{
|
||||
$r = $client->checkVat($params);
|
||||
if($r->valid == true){
|
||||
// VAT-ID is valid
|
||||
return true;
|
||||
} else {
|
||||
// VAT-ID is NOT valid
|
||||
return false;
|
||||
}
|
||||
} catch(SoapFault $e) {
|
||||
Logging::error('VIES EU VAT validation error: '.$e->faultstring);
|
||||
if ($e->faultstring == "INVALID_INPUT") {
|
||||
return false;
|
||||
}
|
||||
//If there was another error with the VAT validation service, we allow
|
||||
//the VAT number to pass. (eg. SERVER_BUSY, MS_UNAVAILABLE, TIMEOUT, SERVICE_UNAVAILABLE)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Connection to host not possible, europe.eu down?
|
||||
Logging::error('VIES EU VAT validation error: Host unreachable');
|
||||
//If there was an error with the VAT validation service, we allow
|
||||
//the VAT number to pass.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function addVatToInvoice($invoice_id)
|
||||
{
|
||||
$credentials = self::getAPICredentials();
|
||||
|
||||
//First we need to get the invoice details: sub total, and total
|
||||
//so we can calcuate the amount of VAT to add
|
||||
$invoicefields = array();
|
||||
$invoicefields["username"] = $credentials["username"];
|
||||
$invoicefields["password"] = md5($credentials["password"]);
|
||||
$invoicefields["action"] = "getinvoice";
|
||||
$invoicefields["invoiceid"] = $invoice_id;
|
||||
$invoicefields["responsetype"] = "json";
|
||||
|
||||
$invoice_query_string = "";
|
||||
foreach ($invoicefields as $k=>$v) $invoice_query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
//TODO: error checking
|
||||
$result = Billing::makeRequest($credentials["url"], $invoice_query_string);
|
||||
|
||||
$vat_amount = $result["subtotal"] * (VAT_RATE/100);
|
||||
$invoice_total = $result["total"] + $vat_amount;
|
||||
|
||||
//Second, update the invoice with the VAT amount and updated total
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "updateinvoice";
|
||||
$postfields["invoiceid"] = $invoice_id;
|
||||
$postfields["tax"] = "$vat_amount";
|
||||
$postfields["taxrate"] = strval(VAT_RATE);
|
||||
$postfields["total"] = "$invoice_total";
|
||||
$postfields["responsetype"] = "json";
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
//TODO: error checking
|
||||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
}
|
||||
|
||||
public static function getInvoices()
|
||||
{
|
||||
Billing::ensureClientIdIsValid();
|
||||
$credentials = Billing::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getinvoices";
|
||||
$postfields["responsetype"] = "json";
|
||||
$postfields["userid"] = Application_Model_Preference::GetClientId();
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
|
||||
$invoices = array();
|
||||
if ($result["invoices"]) {
|
||||
$invoices = $result["invoices"]["invoice"];
|
||||
}
|
||||
return $invoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the customer has any unpaid invoices and if so, returns
|
||||
* the ID of one of them. Returns 0 otherwise.
|
||||
*/
|
||||
public static function checkForUnpaidInvoice() {
|
||||
$invoices = self::getInvoices();
|
||||
$unpaidInvoice = 0;
|
||||
$unpaidInvoices = 0;
|
||||
foreach ($invoices as $invoice)
|
||||
{
|
||||
if ($invoice['status'] == 'Unpaid') {
|
||||
$unpaidInvoices += 1;
|
||||
$unpaidInvoice = $invoice;
|
||||
}
|
||||
}
|
||||
if ($unpaidInvoices > 0) {
|
||||
return $unpaidInvoice;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static function isStationPodcastAllowed() {
|
||||
$planLevel = Application_Model_Preference::GetPlanLevel();
|
||||
if ($planLevel == "hobbyist") {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ class FileDataHelper {
|
|||
"audio/mp4" => "m4a",
|
||||
"video/mp4" => "mp4",
|
||||
"audio/x-flac" => "flac",
|
||||
"audio/flac" => "flac",
|
||||
"audio/wav" => "wav",
|
||||
"audio/x-wav" => "wav",
|
||||
"audio/mp2" => "mp2",
|
||||
|
@ -67,4 +68,385 @@ class FileDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data URI from artwork file
|
||||
*
|
||||
* @param string $file
|
||||
* @param int $size
|
||||
* @param string $filepath
|
||||
*
|
||||
* @return string Data URI for artwork
|
||||
*/
|
||||
public static function getArtworkData($file, $size, $filepath = false)
|
||||
{
|
||||
$baseUrl = Application_Common_HTTPHelper::getStationUrl();
|
||||
$default = $baseUrl . "css/images/no-cover.jpg";
|
||||
|
||||
if ($filepath != false) {
|
||||
$path = $filepath . $file . "-" . $size;
|
||||
if (!file_exists($path)) {
|
||||
$get_file_content = $default;
|
||||
} else {
|
||||
$get_file_content = file_get_contents($path);
|
||||
}
|
||||
} else {
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$path = $storDir->getDirectory() . $file . "-" . $size;
|
||||
if (!file_exists($path)) {
|
||||
$get_file_content = $default;
|
||||
} else {
|
||||
$get_file_content = file_get_contents($path);
|
||||
}
|
||||
}
|
||||
return $get_file_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add artwork file
|
||||
*
|
||||
* @param string $analyzeFile
|
||||
* @param string $filename
|
||||
* @param string $importDir
|
||||
* @param string $DbPath
|
||||
*
|
||||
* @return string Path to artwork
|
||||
*/
|
||||
public static function saveArtworkData($analyzeFile, $filename, $importDir = null, $DbPath = null)
|
||||
{
|
||||
if (class_exists('getID3')) {
|
||||
$getID3 = new \getID3();
|
||||
$getFileInfo = $getID3->analyze($analyzeFile);
|
||||
} else {
|
||||
$getFileInfo = [];
|
||||
Logging::error("Failed to load getid3 library. Please upgrade Libretime.");
|
||||
}
|
||||
|
||||
if(isset($getFileInfo['comments']['picture'][0])) {
|
||||
|
||||
$get_img = "";
|
||||
$timestamp = time();
|
||||
$mime = $getFileInfo['comments']['picture'][0]['image_mime'];
|
||||
$Image = 'data:'.$mime.';charset=utf-8;base64,'.base64_encode($getFileInfo['comments']['picture'][0]['data']);
|
||||
$base64 = @$Image;
|
||||
|
||||
if (!file_exists($importDir . "/" . "artwork/")) {
|
||||
if (!mkdir($importDir . "/" . "artwork/", 0777, true)) {
|
||||
Logging::error("Failed to create artwork directory.");
|
||||
throw new Exception("Failed to create artwork directory.");
|
||||
}
|
||||
}
|
||||
|
||||
$path_parts = pathinfo($filename);
|
||||
$file = $importDir . "artwork/" . $path_parts['filename'];
|
||||
|
||||
//Save Data URI
|
||||
if (file_put_contents($file, $base64)) {
|
||||
$get_img = $DbPath . "artwork/". $path_parts['filename'];
|
||||
} else {
|
||||
Logging::error("Could not save Data URI");
|
||||
}
|
||||
|
||||
if ($mime == "image/png") {
|
||||
$ext = 'png';
|
||||
} elseif ($mime == "image/gif") {
|
||||
$ext = 'gif';
|
||||
} elseif ($mime == "image/bmp") {
|
||||
$ext = 'bmp';
|
||||
} else {
|
||||
$ext = 'jpg';
|
||||
}
|
||||
self::resizeGroup($file, $ext);
|
||||
|
||||
} else {
|
||||
$get_img = '';
|
||||
}
|
||||
return $get_img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset artwork
|
||||
*
|
||||
* @param string $trackid
|
||||
*
|
||||
* @return string $get_img Path to artwork
|
||||
*/
|
||||
public static function resetArtwork($trackid)
|
||||
{
|
||||
$file = Application_Model_StoredFile::RecallById($trackid);
|
||||
$md = $file->getMetadata();
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$fp = $storDir->getDirectory();
|
||||
|
||||
$dbAudioPath = $md["MDATA_KEY_FILEPATH"];
|
||||
$fullpath = $fp . $dbAudioPath;
|
||||
|
||||
if (class_exists('getID3')) {
|
||||
$getID3 = new \getID3();
|
||||
$getFileInfo = $getID3->analyze($fullpath);
|
||||
} else {
|
||||
$getFileInfo = [];
|
||||
Logging::error("Failed to load getid3 library. Please upgrade Libretime.");
|
||||
}
|
||||
|
||||
if(isset($getFileInfo['comments']['picture'][0])) {
|
||||
|
||||
$get_img = "";
|
||||
$mime = $getFileInfo['comments']['picture'][0]['image_mime'];
|
||||
$Image = 'data:'.$getFileInfo['comments']['picture'][0]['image_mime'].';charset=utf-8;base64,'.base64_encode($getFileInfo['comments']['picture'][0]['data']);
|
||||
$base64 = @$Image;
|
||||
|
||||
$audioPath = dirname($fullpath);
|
||||
$dbPath = dirname($dbAudioPath);
|
||||
$path_parts = pathinfo($fullpath);
|
||||
$file = $path_parts['filename'];
|
||||
|
||||
//Save Data URI
|
||||
if (file_put_contents($audioPath . "/" . $file, $base64)) {
|
||||
$get_img = $dbPath . "/" . $file;
|
||||
} else {
|
||||
Logging::error("Could not save Data URI");
|
||||
}
|
||||
|
||||
$rfile = $audioPath . "/" . $file;
|
||||
|
||||
if ($mime == "image/png") {
|
||||
$ext = 'png';
|
||||
} elseif ($mime == "image/gif") {
|
||||
$ext = 'gif';
|
||||
} elseif ($mime == "image/bmp") {
|
||||
$ext = 'bmp';
|
||||
} else {
|
||||
$ext = 'jpg';
|
||||
}
|
||||
self::resizeGroup($rfile, $ext);
|
||||
|
||||
} else {
|
||||
$get_img = "";
|
||||
}
|
||||
return $get_img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload artwork
|
||||
*
|
||||
* @param string $trackid
|
||||
* @param string $data
|
||||
*
|
||||
* @return string Path to artwork
|
||||
*/
|
||||
public static function setArtwork($trackid, $data)
|
||||
{
|
||||
$file = Application_Model_StoredFile::RecallById($trackid);
|
||||
$md = $file->getMetadata();
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$fp = $storDir->getDirectory();
|
||||
|
||||
$dbAudioPath = $md["MDATA_KEY_FILEPATH"];
|
||||
$fullpath = $fp . $dbAudioPath;
|
||||
|
||||
if ($data == "0") {
|
||||
|
||||
$get_img = "";
|
||||
self::removeArtwork($trackid, $data);
|
||||
|
||||
} else {
|
||||
|
||||
$base64 = @$data;
|
||||
$mime = explode(';', $base64)[0];
|
||||
|
||||
$audioPath = dirname($fullpath);
|
||||
$dbPath = dirname($dbAudioPath);
|
||||
$path_parts = pathinfo($fullpath);
|
||||
$file = $path_parts['filename'];
|
||||
|
||||
//Save Data URI
|
||||
if (file_put_contents($audioPath . "/" . $file, $base64)) {
|
||||
$get_img = $dbPath . "/" . $file;
|
||||
} else {
|
||||
Logging::error("Could not save Data URI");
|
||||
}
|
||||
|
||||
$rfile = $audioPath . "/" . $file;
|
||||
|
||||
if ($mime == "data:image/png") {
|
||||
$ext = 'png';
|
||||
} elseif ($mime == "data:image/gif") {
|
||||
$ext = 'gif';
|
||||
} elseif ($mime == "data:image/bmp") {
|
||||
$ext = 'bmp';
|
||||
} else {
|
||||
$ext = 'jpg';
|
||||
}
|
||||
self::resizeGroup($rfile, $ext);
|
||||
|
||||
}
|
||||
return $get_img;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Deletes just the artwork
|
||||
*/
|
||||
public static function removeArtwork($trackid)
|
||||
{
|
||||
$file = Application_Model_StoredFile::RecallById($trackid);
|
||||
$md = $file->getMetadata();
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$fp = $storDir->getDirectory();
|
||||
|
||||
$dbAudioPath = $md["MDATA_KEY_ARTWORK"];
|
||||
$fullpath = $fp . $dbAudioPath;
|
||||
|
||||
if (file_exists($fullpath)) {
|
||||
foreach (glob("$fullpath*", GLOB_NOSORT) as $filename) {
|
||||
unlink($filename);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Could not locate file ".$filepath);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize artwork group
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $ext
|
||||
*/
|
||||
public static function resizeGroup($file, $ext)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
self::resizeImage($file, $file . '-32.jpg', $ext, 32, 100);
|
||||
self::resizeImage($file, $file . '-64.jpg', $ext, 64, 100);
|
||||
self::resizeImage($file, $file . '-128.jpg', $ext, 128, 100);
|
||||
self::resizeImage($file, $file . '-256.jpg', $ext, 256, 100);
|
||||
self::resizeImage($file, $file . '-512.jpg', $ext, 512, 100);
|
||||
self::imgToDataURI($file . '-32.jpg', $file . '-32');
|
||||
self::imgToDataURI($file . '-64.jpg', $file . '-64');
|
||||
self::imgToDataURI($file . '-128.jpg', $file . '-128');
|
||||
self::imgToDataURI($file . '-256.jpg', $file . '-256');
|
||||
} else {
|
||||
Logging::error("The file $file does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render image
|
||||
* Used in API to render JPEG
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public static function renderImage($file)
|
||||
{
|
||||
$im = @imagecreatefromjpeg($file);
|
||||
header('Content-Type: image/jpeg');
|
||||
$img = $im;
|
||||
imagejpeg($img);
|
||||
imagedestroy($img);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Data URI
|
||||
* Used in API to render Data URI
|
||||
*
|
||||
* @param string $dataFile
|
||||
*/
|
||||
public static function renderDataURI($dataFile)
|
||||
{
|
||||
if($filecontent = file_get_contents($dataFile) !== false){
|
||||
$image = @file_get_contents($dataFile);
|
||||
$image = base64_encode($image);
|
||||
if (!$image || $image === '') {
|
||||
return;
|
||||
}
|
||||
$blob = base64_decode($image);
|
||||
$f = finfo_open();
|
||||
$mime_type = finfo_buffer($f, $blob, FILEINFO_MIME_TYPE);
|
||||
finfo_close($f);
|
||||
header("Content-Type: " . $mime_type);
|
||||
echo $blob;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize Image
|
||||
*
|
||||
* @param string $orig_filename
|
||||
* @param string $converted_filename
|
||||
* @param string $ext
|
||||
* @param string $size Default: 500
|
||||
* @param string $quality Default: 75
|
||||
*
|
||||
*/
|
||||
public static function resizeImage($orig_filename, $converted_filename, $ext, $size=500, $quality=75)
|
||||
{
|
||||
$get_cont = file_get_contents($orig_filename);
|
||||
if ($ext == "png") {
|
||||
$im = @imagecreatefrompng($get_cont);
|
||||
} elseif ($ext == "gif") {
|
||||
$im = @imagecreatefromgif($get_cont);
|
||||
} else {
|
||||
$im = @imagecreatefromjpeg($get_cont);
|
||||
}
|
||||
|
||||
// if one of those bombs, create an error image instead
|
||||
if (!$im) {
|
||||
$im = imagecreatetruecolor(150, 30);
|
||||
$bgc = imagecolorallocate($im, 255, 255, 255);
|
||||
$tc = imagecolorallocate($im, 0, 0, 0);
|
||||
imagefilledrectangle($im, 0, 0, 150, 30, $bgc);
|
||||
imagestring($im, 1, 5, 5, 'Error loading ' . $converted_filename, $tc);
|
||||
}
|
||||
|
||||
// scale if appropriate
|
||||
if ($size){
|
||||
$im = imagescale($im , $size);
|
||||
}
|
||||
|
||||
$img = $im;
|
||||
imagejpeg($img, $converted_filename, $quality);
|
||||
imagedestroy($img);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image to Data URI
|
||||
*
|
||||
* @param string $orig_filename
|
||||
* @param string $conv_filename
|
||||
*/
|
||||
public static function imgToDataURI($orig_filename, $conv_filename)
|
||||
{
|
||||
$file = file_get_contents($orig_filename);
|
||||
$Image = 'data:image/jpeg;charset=utf-8;base64,'.base64_encode($file);
|
||||
$base64 = @$Image;
|
||||
|
||||
//Save Data URI
|
||||
if (file_put_contents($conv_filename, $base64)) {
|
||||
|
||||
} else {
|
||||
Logging::error("Could not save Data URI");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track Type
|
||||
*
|
||||
* @return string Track type key value
|
||||
*/
|
||||
public static function saveTrackType()
|
||||
{
|
||||
if (isset($_COOKIE['tt_upload'])) {
|
||||
$tt = $_COOKIE['tt_upload'];
|
||||
} else {
|
||||
// Use default track type
|
||||
$tt = Application_Model_Preference::GetTrackTypeDefault();
|
||||
}
|
||||
return $tt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Application_Common_GoogleAnalytics
|
||||
{
|
||||
|
||||
/** Returns a string containing the JavaScript code to pass some billing account info
|
||||
* into Google Tag Manager / Google Analytics, so we can track things like the plan type.
|
||||
*/
|
||||
public static function generateGoogleTagManagerDataLayerJavaScript()
|
||||
{
|
||||
$code = "";
|
||||
if (LIBRETIME_ENABLE_GOOGLE_ANALYTICS !== true) {
|
||||
return $code;
|
||||
}
|
||||
|
||||
try {
|
||||
$clientId = Application_Model_Preference::GetClientId();
|
||||
|
||||
$plan = Application_Model_Preference::GetPlanLevel();
|
||||
$isTrial = ($plan == "trial");
|
||||
|
||||
//Figure out how long the customer has been around using a mega hack.
|
||||
//(I'm avoiding another round trip to WHMCS for now...)
|
||||
//We calculate it based on the trial end date...
|
||||
$trialEndDateStr = Application_Model_Preference::GetTrialEndingDate();
|
||||
if ($trialEndDateStr == '') {
|
||||
$accountDuration = 0;
|
||||
} else {
|
||||
$today = new DateTime();
|
||||
$trialEndDate = new DateTime($trialEndDateStr);
|
||||
$trialDuration = new DateInterval("P30D"); //30 day trial duration
|
||||
$accountCreationDate = $trialEndDate->sub($trialDuration);
|
||||
$interval = $today->diff($accountCreationDate);
|
||||
$accountDuration = $interval->days;
|
||||
}
|
||||
|
||||
$code = "$( document ).ready(function() {
|
||||
dataLayer.push({
|
||||
'UserID': '" . $clientId . "',
|
||||
'Customer': 'Customer',
|
||||
'PlanType': '" . $plan . "',
|
||||
'Trial': '" . $isTrial . "',
|
||||
'AccountDuration': '" . strval($accountDuration) . "'
|
||||
});
|
||||
});";
|
||||
//No longer sending these variables because we used to make a query to WHMCS
|
||||
//to fetch them, which was slow.
|
||||
// 'ZipCode': '" . $postcode . "',
|
||||
// 'Country': '" . $country . "',
|
||||
|
||||
} catch (Exception $e) {
|
||||
Logging::error($e);
|
||||
return "";
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
/** Generate the JavaScript snippet that logs a trial to paid conversion */
|
||||
public static function generateConversionTrackingJavaScript()
|
||||
{
|
||||
$code = "";
|
||||
if (LIBRETIME_ENABLE_GOOGLE_ANALYTICS !== true) {
|
||||
return $code;
|
||||
}
|
||||
|
||||
$newPlan = Application_Model_Preference::GetPlanLevel();
|
||||
$oldPlan = Application_Model_Preference::GetOldPlanLevel();
|
||||
|
||||
$code = "dataLayer.push({'event': 'Conversion',
|
||||
'Conversion': 'Trial to Paid',
|
||||
'Old Plan' : '$oldPlan',
|
||||
'New Plan' : '$newPlan'});";
|
||||
return $code;
|
||||
}
|
||||
|
||||
/** Return true if the user used to be on a trial plan and was just converted to a paid plan. */
|
||||
public static function didPaidConversionOccur($request)
|
||||
{
|
||||
if (LIBRETIME_ENABLE_GOOGLE_ANALYTICS !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
if ($userInfo) {
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$oldPlan = Application_Model_Preference::GetOldPlanLevel();
|
||||
|
||||
if ($user->isSuperAdmin() &&
|
||||
!$user->isSourcefabricAdmin() &&
|
||||
$request->getControllerKey() !== "thank-you")
|
||||
{
|
||||
//Only tracking trial->paid conversions for now.
|
||||
if ($oldPlan == "trial")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ class Application_Common_HTTPHelper
|
|||
$baseUrl = $CC_CONFIG['baseUrl'];
|
||||
$baseDir = $CC_CONFIG['baseDir'];
|
||||
$basePort = $CC_CONFIG['basePort'];
|
||||
$forceSSL = $CC_CONFIG['forceSSL'];
|
||||
if (empty($baseDir)) {
|
||||
$baseDir = "/";
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ class Application_Common_HTTPHelper
|
|||
}
|
||||
|
||||
$scheme = "http";
|
||||
if ($secured && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
|
||||
if ($forceSSL || ($secured && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')) {
|
||||
$scheme = "https";
|
||||
$basePort = "443"; //Airtime Pro compatibility hack
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
// Global functions for translating domain-specific strings
|
||||
|
||||
function _pro($str) {
|
||||
return dgettext("pro", $str);
|
||||
}
|
||||
|
||||
class Application_Common_LocaleHelper {
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,4 +101,4 @@ class PodcastManager {
|
|||
return (strtotime($a["pub_date"]) < strtotime($b["pub_date"])) ? 1 : -1; // Descending order
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
<?php
|
||||
|
||||
/** This class provides the business logic for station provisioning. */
|
||||
class ProvisioningHelper
|
||||
{
|
||||
|
||||
/* @var $dbh PDO */
|
||||
static $dbh;
|
||||
|
||||
// Parameter values
|
||||
private $dbuser, $dbpass, $dbname, $dbhost, $dbowner, $apikey;
|
||||
private $instanceId;
|
||||
private $stationName, $description;
|
||||
private $defaultIcecastPassword;
|
||||
private $bandwidthLimit;
|
||||
|
||||
public function __construct($apikey)
|
||||
{
|
||||
$this->apikey = $apikey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for setting up and installing the Airtime database. This all has to be done without Zend
|
||||
* which is why the code looks so old school (eg. http_response_code). (We can't currently bootstrap our
|
||||
* Zend app without the database unfortunately.)
|
||||
*/
|
||||
public function createAction()
|
||||
{
|
||||
$apikey = "";
|
||||
if (isset($_SERVER['PHP_AUTH_USER']))
|
||||
{
|
||||
$apikey = $_SERVER['PHP_AUTH_USER'];
|
||||
}
|
||||
if ($apikey != $this->apikey) {
|
||||
Logging::info("Invalid API Key: $apikey");
|
||||
http_response_code(403);
|
||||
echo "ERROR: Incorrect API key";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$this->parsePostParams();
|
||||
|
||||
//For security, the Airtime Pro provisioning system creates the database for the user.
|
||||
if ($this->dbhost && !empty($this->dbhost)) {
|
||||
$this->setNewDatabaseConnection();
|
||||
|
||||
if (!$this->checkDatabaseExists()) {
|
||||
throw new DatabaseDoesNotExistException("ERROR: $this->dbname database does not exist.");
|
||||
}
|
||||
|
||||
//We really want to do this check because all the Propel-generated SQL starts with "DROP TABLE IF EXISTS".
|
||||
//If we don't check, then a second call to this API endpoint would wipe all the tables!
|
||||
if ($this->checkTablesExist()) {
|
||||
throw new DatabaseAlreadyExistsException();
|
||||
}
|
||||
|
||||
$this->createDatabaseTables();
|
||||
$this->initializeMusicDirsTable($this->instanceId);
|
||||
}
|
||||
|
||||
//$this->createDatabase();
|
||||
|
||||
//All we need to do is create the database tables.
|
||||
|
||||
$this->initializePrefs();
|
||||
} catch (DatabaseDoesNotExistException $e) {
|
||||
http_response_code(400);
|
||||
Logging::error($e->getMessage());
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
return;
|
||||
} catch (DatabaseAlreadyExistsException $e) {
|
||||
// When we recreate a terminated instance, the process will fail
|
||||
// if we return a 40x response here. In order to circumvent this,
|
||||
// just return a 200; we still avoid dropping the existing tables
|
||||
http_response_code(200);
|
||||
Logging::info($e->getMessage());
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
|
||||
http_response_code(201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the database settings and credentials given are valid
|
||||
* @return boolean true if the database given exists and the user is valid and can access it
|
||||
*/
|
||||
private function checkDatabaseExists()
|
||||
{
|
||||
$statement = self::$dbh->prepare("SELECT datname FROM pg_database WHERE datname = :dbname");
|
||||
$statement->execute(array(":dbname" => $this->dbname));
|
||||
$result = $statement->fetch();
|
||||
return isset($result[0]);
|
||||
}
|
||||
|
||||
private function checkTablesExist()
|
||||
{
|
||||
try {
|
||||
$result = self::$dbh->query("SELECT 1 FROM cc_files LIMIT 1");
|
||||
} catch (Exception $e) {
|
||||
// We got an exception == table not found
|
||||
echo($e . PHP_EOL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Result is either boolean FALSE (no table found) or PDOStatement Object (table found)
|
||||
return $result !== FALSE;
|
||||
}
|
||||
|
||||
private function parsePostParams()
|
||||
{
|
||||
$this->dbuser = $_POST['dbuser'];
|
||||
$this->dbpass = $_POST['dbpass'];
|
||||
$this->dbname = $_POST['dbname'];
|
||||
$this->dbhost = $_POST['dbhost'];
|
||||
$this->dbowner = $_POST['dbowner'];
|
||||
$this->instanceId = $_POST['instanceid'];
|
||||
|
||||
if (isset($_POST['station_name'])) {
|
||||
$this->stationName = $_POST['station_name'];
|
||||
}
|
||||
if (isset($_POST['description'])) {
|
||||
$this->description = $_POST['description'];
|
||||
}
|
||||
if (isset($_POST['icecast_pass'])) {
|
||||
$this->defaultIcecastPassword = $_POST['icecast_pass'];
|
||||
}
|
||||
if (isset($_POST['bandwidth_limit'])) {
|
||||
$this->bandwidthLimit = $_POST['bandwidth_limit'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a new database connection based on the parameters in the request
|
||||
* @throws PDOException upon failure to connect
|
||||
*/
|
||||
private function setNewDatabaseConnection()
|
||||
{
|
||||
self::$dbh = new PDO("pgsql:host=" . $this->dbhost
|
||||
. ";dbname=" . $this->dbname
|
||||
. ";port=5432" . ";user=" . $this->dbuser
|
||||
. ";password=" . $this->dbpass);
|
||||
//Turn on PDO exceptions because they're off by default.
|
||||
//self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$err = self::$dbh->errorInfo();
|
||||
if ($err[1] != null) {
|
||||
throw new PDOException("ERROR: Could not connect to database");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Airtime database using the given credentials
|
||||
* @throws Exception
|
||||
*/
|
||||
private function createDatabase()
|
||||
{
|
||||
Logging::info("Creating database...");
|
||||
$statement = self::$dbh->prepare("CREATE DATABASE " . pg_escape_string($this->dbname)
|
||||
. " WITH ENCODING 'UTF8' TEMPLATE template0"
|
||||
. " OWNER " . pg_escape_string($this->dbowner));
|
||||
if (!$statement->execute()) {
|
||||
throw new Exception("ERROR: Failed to create Airtime database");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the Airtime database
|
||||
* @throws Exception
|
||||
*/
|
||||
private function createDatabaseTables()
|
||||
{
|
||||
Logging::info("Creating database tables...");
|
||||
$sqlDir = dirname(APPLICATION_PATH) . "/build/sql/";
|
||||
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
|
||||
foreach ($files as $f) {
|
||||
/*
|
||||
* Unfortunately, we need to use exec here due to PDO's lack of support for importing
|
||||
* multi-line .sql files. PDO->exec() almost works, but any SQL errors stop the import,
|
||||
* so the necessary DROPs on non-existent tables make it unusable. Prepared statements
|
||||
* have multiple issues; they similarly die on any SQL errors, fail to read in multi-line
|
||||
* commands, and fail on any unescaped ? or $ characters.
|
||||
*/
|
||||
exec("PGPASSWORD=$this->dbpass psql -U $this->dbuser --dbname $this->dbname -h $this->dbhost -f $sqlDir$f", $out, $status);
|
||||
if ($status != 0) {
|
||||
throw new Exception("ERROR: Failed to create database tables");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function initializeMusicDirsTable($instanceId)
|
||||
{
|
||||
if (!is_string($instanceId) || empty($instanceId) || !is_numeric($instanceId))
|
||||
{
|
||||
throw new Exception("Invalid instance id: " . $instanceId);
|
||||
}
|
||||
|
||||
$instanceIdPrefix = $instanceId[0];
|
||||
|
||||
//Reinitialize Propel, just in case...
|
||||
Propel::init(__DIR__."/../configs/airtime-conf-production.php");
|
||||
|
||||
//Create the cc_music_dir entry
|
||||
$musicDir = new CcMusicDirs();
|
||||
$musicDir->setType("stor");
|
||||
$musicDir->setExists(true);
|
||||
$musicDir->setWatched(true);
|
||||
$musicDir->setDirectory("/mnt/airtimepro/instances/$instanceIdPrefix/$instanceId/srv/airtime/stor/");
|
||||
$musicDir->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize preference values passed from the dashboard (if any exist)
|
||||
*/
|
||||
private function initializePrefs() {
|
||||
if ($this->stationName) {
|
||||
Application_Model_Preference::SetStationName($this->stationName);
|
||||
}
|
||||
if ($this->description) {
|
||||
Application_Model_Preference::SetStationDescription($this->description);
|
||||
}
|
||||
if (isset($this->defaultIcecastPassword)) {
|
||||
Application_Model_Preference::setDefaultIcecastPassword($this->defaultIcecastPassword);
|
||||
}
|
||||
if (isset($this->bandwidthLimit)) {
|
||||
Application_Model_Preference::setBandwidthLimit($this->bandwidthLimit);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DatabaseAlreadyExistsException extends Exception {
|
||||
private static $_defaultMessage = "ERROR: airtime tables already exists";
|
||||
public function __construct($message = null, $code = 0, Exception $previous = null) {
|
||||
$message = _((is_null($message) ? self::$_defaultMessage : $message));
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
class DatabaseDoesNotExistException extends Exception {}
|
||||
|
|
@ -103,13 +103,6 @@ class Application_Common_UsabilityHints
|
|||
"<a href=\"/schedule\">",
|
||||
"</a>");
|
||||
}
|
||||
} else if (LIBRETIME_ENABLE_BILLING === true && $userIsOnShowbuilderPage && $userIsSuperAdmin) {
|
||||
$unpaidInvoice = Billing::checkForUnpaidInvoice();
|
||||
if ($unpaidInvoice != null) {
|
||||
$invoiceUrl = "/billing/invoice?invoiceid=" . $unpaidInvoice['id'];
|
||||
$amount = $unpaidInvoice['currencyprefix'] . $unpaidInvoice['total'];
|
||||
return _pro(sprintf("You have an unpaid invoice for %s due soon. <a href='%s'>Please pay it to keep your station on the air.</a>", $amount, $invoiceUrl));;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -225,4 +218,4 @@ class Application_Common_UsabilityHints
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ define("DAYS_PER_WEEK", 7);
|
|||
|
||||
class WidgetHelper
|
||||
{
|
||||
public static function getWeekInfo($timezone)
|
||||
public static function getWeekInfo($userDefinedTimezone)
|
||||
{
|
||||
//weekStart is in station time.
|
||||
$weekStartDateTime = Application_Common_DateHelper::getWeekStartDateTime();
|
||||
|
@ -17,10 +17,12 @@ class WidgetHelper
|
|||
|
||||
// default to the station timezone
|
||||
$timezone = Application_Model_Preference::GetDefaultTimezone();
|
||||
$userDefinedTimezone = strtolower($timezone);
|
||||
// if the timezone defined by the user exists, use that
|
||||
if (array_key_exists($userDefinedTimezone, timezone_abbreviations_list())) {
|
||||
$timezone = $userDefinedTimezone;
|
||||
if ($userDefinedTimezone) {
|
||||
$userDefinedTimezone = strtolower($userDefinedTimezone);
|
||||
// if the timezone defined by the user exists, use that
|
||||
if (array_key_exists($userDefinedTimezone, timezone_abbreviations_list())) {
|
||||
$timezone = $userDefinedTimezone;
|
||||
}
|
||||
}
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
|
||||
|
@ -170,4 +172,4 @@ class WidgetHelper
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ $ccAcl->addRole(new Zend_Acl_Role('G'))
|
|||
$ccAcl->add(new Zend_Acl_Resource('library'))
|
||||
->add(new Zend_Acl_Resource('index'))
|
||||
->add(new Zend_Acl_Resource('user'))
|
||||
->add(new Zend_Acl_Resource('tracktype'))
|
||||
->add(new Zend_Acl_Resource('error'))
|
||||
->add(new Zend_Acl_Resource('login'))
|
||||
->add(new Zend_Acl_Resource('whmcs-login'))
|
||||
->add(new Zend_Acl_Resource('playlist'))
|
||||
->add(new Zend_Acl_Resource('plupload'))
|
||||
->add(new Zend_Acl_Resource('schedule'))
|
||||
|
@ -26,6 +26,7 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
->add(new Zend_Acl_Resource('playouthistory'))
|
||||
->add(new Zend_Acl_Resource('playouthistorytemplate'))
|
||||
->add(new Zend_Acl_Resource('listenerstat'))
|
||||
->add(new Zend_Acl_Resource('showlistenerstat'))
|
||||
->add(new Zend_Acl_Resource('usersettings'))
|
||||
->add(new Zend_Acl_Resource('audiopreview'))
|
||||
->add(new Zend_Acl_Resource('webstream'))
|
||||
|
@ -37,9 +38,6 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
->add(new Zend_Acl_Resource('rest:podcast'))
|
||||
->add(new Zend_Acl_Resource('rest:podcast-episodes'))
|
||||
->add(new Zend_Acl_Resource('podcast'))
|
||||
->add(new Zend_Acl_Resource('billing'))
|
||||
->add(new Zend_Acl_Resource('thank-you'))
|
||||
->add(new Zend_Acl_Resource('provisioning'))
|
||||
->add(new Zend_Acl_Resource('player'))
|
||||
->add(new Zend_Acl_Resource('render'))
|
||||
->add(new Zend_Acl_Resource('soundcloud'))
|
||||
|
@ -50,7 +48,6 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
/** Creating permissions */
|
||||
$ccAcl->allow('G', 'index')
|
||||
->allow('G', 'login')
|
||||
->allow('G', 'whmcs-login')
|
||||
->allow('G', 'error')
|
||||
->allow('G', 'user', 'edit-user')
|
||||
->allow('G', 'showbuilder')
|
||||
|
@ -62,7 +59,6 @@ $ccAcl->allow('G', 'index')
|
|||
->allow('G', 'webstream')
|
||||
->allow('G', 'locale')
|
||||
->allow('G', 'upgrade')
|
||||
->allow('G', 'provisioning')
|
||||
->allow('G', 'downgrade')
|
||||
->allow('G', 'rest:show-image', 'get')
|
||||
->allow('G', 'rest:media', 'get')
|
||||
|
@ -83,14 +79,14 @@ $ccAcl->allow('G', 'index')
|
|||
->allow('H', 'library')
|
||||
->allow('H', 'playlist')
|
||||
->allow('H', 'playouthistory')
|
||||
->allow('H', 'listenerstat')
|
||||
->allow('H', 'showlistenerstat')
|
||||
->allow('A', 'playouthistorytemplate')
|
||||
->allow('A', 'listenerstat')
|
||||
->allow('A', 'user')
|
||||
->allow('A', 'tracktype')
|
||||
->allow('A', 'systemstatus')
|
||||
->allow('A', 'preference')
|
||||
->allow('S', 'thank-you')
|
||||
->allow('S', 'billing');
|
||||
|
||||
->allow('A', 'preference');
|
||||
|
||||
|
||||
$aclPlugin = new Zend_Controller_Plugin_Acl($ccAcl);
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@ return array (
|
|||
'BaseCcStreamSetting' => 'airtime/om/BaseCcStreamSetting.php',
|
||||
'BaseCcStreamSettingPeer' => 'airtime/om/BaseCcStreamSettingPeer.php',
|
||||
'BaseCcStreamSettingQuery' => 'airtime/om/BaseCcStreamSettingQuery.php',
|
||||
'BaseCcTracktypes' => 'airtime/om/BaseCcTracktypes.php',
|
||||
'BaseCcTracktypesPeer' => 'airtime/om/BaseCcTracktypesPeer.php',
|
||||
'BaseCcTracktypesQuery' => 'airtime/om/BaseCcTracktypesQuery.php',
|
||||
'BaseCcSubjs' => 'airtime/om/BaseCcSubjs.php',
|
||||
'BaseCcSubjsPeer' => 'airtime/om/BaseCcSubjsPeer.php',
|
||||
'BaseCcSubjsQuery' => 'airtime/om/BaseCcSubjsQuery.php',
|
||||
|
@ -233,6 +236,10 @@ return array (
|
|||
'CcStreamSettingPeer' => 'airtime/CcStreamSettingPeer.php',
|
||||
'CcStreamSettingQuery' => 'airtime/CcStreamSettingQuery.php',
|
||||
'CcStreamSettingTableMap' => 'airtime/map/CcStreamSettingTableMap.php',
|
||||
'CcTracktypes' => 'airtime/CcTracktypes.php',
|
||||
'CcTracktypesPeer' => 'airtime/CcTracktypesPeer.php',
|
||||
'CcTracktypesQuery' => 'airtime/CcTracktypesQuery.php',
|
||||
'CcTracktypesTableMap' => 'airtime/map/CcTracktypesTableMap.php',
|
||||
'CcSubjs' => 'airtime/CcSubjs.php',
|
||||
'CcSubjsPeer' => 'airtime/CcSubjsPeer.php',
|
||||
'CcSubjsQuery' => 'airtime/CcSubjsQuery.php',
|
||||
|
|
|
@ -31,6 +31,7 @@ class Config {
|
|||
$CC_CONFIG['basePort'] = $values['general']['base_port'];
|
||||
$CC_CONFIG['stationId'] = $values['general']['station_id'];
|
||||
$CC_CONFIG['phpDir'] = $values['general']['airtime_dir'];
|
||||
$CC_CONFIG['forceSSL'] = isset($values['general']['force_ssl']) ? $values['general']['force_ssl'] : FALSE;
|
||||
if (isset($values['general']['dev_env'])) {
|
||||
$CC_CONFIG['dev_env'] = $values['general']['dev_env'];
|
||||
} else {
|
||||
|
|
|
@ -165,19 +165,19 @@ $result = $r1 && $r2;
|
|||
</tr>
|
||||
<tr class="<?=$analyzer ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Airtime Analyzer
|
||||
Media Analyzer
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime Upload and File Analysis service
|
||||
<?php echo _("LibreTime media analyzer service") ?>
|
||||
</td>
|
||||
<td class="solution <?php if ($analyzer) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime_analyzer service is installed correctly in <code>/etc/init.d</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime_analyzer</code><br/>
|
||||
If not, try running <code>sudo service airtime_analyzer start</code>
|
||||
<?php echo _("Check that the libretime-analyzer service is installed correctly in ") ?><code>/etc/systemd/system/</code>,
|
||||
<?php echo _(" and ensure that it's running with ") ?>
|
||||
<br/><code>systemctl status libretime-analyzer</code><br/>
|
||||
<?php echo _("If not, try ") ?><br/><code>sudo systemctl restart libretime-analyzer</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -188,16 +188,16 @@ $result = $r1 && $r2;
|
|||
Pypo
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime playout service
|
||||
<?php echo _("LibreTime playout service") ?>
|
||||
</td>
|
||||
<td class="solution <?php if ($pypo) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-playout service is installed correctly in <code>/etc/init.d</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-playout</code><br/>
|
||||
If not, try running <code>sudo service airtime-playout restart</code>
|
||||
<?php echo _("Check that the libretime-playout service is installed correctly in ") ?><code>/etc/systemd/system/</code>,
|
||||
<?php echo _(" and ensure that it's running with ") ?>
|
||||
<br/><code>systemctl status libretime-playout</code><br/>
|
||||
<?php echo _("If not, try ") ?><br/><code>sudo systemctl restart libretime-playout</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -208,16 +208,16 @@ $result = $r1 && $r2;
|
|||
Liquidsoap
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime liquidsoap service
|
||||
<?php echo _("LibreTime liquidsoap service") ?>
|
||||
</td>
|
||||
<td class="solution <?php if ($liquidsoap) {echo 'check';?>">
|
||||
<td class="solution <?php if ($liquidsoap) {echo 'check';?>" >
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-liquidsoap service is installed correctly in <code>/etc/init.d</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-liquidsoap</code><br/>
|
||||
If not, try running <code>sudo service airtime-liquidsoap restart</code>
|
||||
<?php echo _("Check that the libretime-liquidsoap service is installed correctly in ") ?><code>/etc/systemd/system/</code>,
|
||||
<?php echo _(" and ensure that it's running with ") ?>
|
||||
<br/><code>systemctl status libretime-liquidsoap</code><br/>
|
||||
<?php echo _("If not, try ") ?><br/><code>sudo systemctl restart libretime-liquidsoap</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -228,16 +228,16 @@ $result = $r1 && $r2;
|
|||
Celery
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime Celery Task service
|
||||
<?php echo _("LibreTime Celery Task service") ?>
|
||||
</td>
|
||||
<td class="solution <?php if ($celery) {echo 'check';?>">
|
||||
<td class="solution <?php if ($celery) {echo 'check';?>" >
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-celery service is installed correctly in <code>/etc/init.d</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-celery</code><br/>
|
||||
If not, try running <code>sudo service airtime-celery restart</code>
|
||||
<?php echo _("Check that the libretime-celery service is installed correctly in ") ?><code>/etc/systemd/system/</code>,
|
||||
<?php echo _(" and ensure that it's running with ") ?>
|
||||
<br/><code>systemctl status libretime-celery</code><br/>
|
||||
<?php echo _("If not, try ") ?><br/><code>sudo systemctl restart libretime-celery</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -15,14 +15,14 @@ define('SUPPORT_ADDRESS' , 'https://discourse.libretime.org/');
|
|||
define("AIRTIMEPRO_API_URL", "https://account.example.com:5001/api/");
|
||||
|
||||
define('HELP_URL' , 'https://discourse.libretime.org/');
|
||||
define('FAQ_URL' , 'http://libretime.org/faq/');
|
||||
define('FAQ_URL' , 'http://libretime.org/faq');
|
||||
define('WHOS_USING_URL' , 'https://github.com/orgs/LibreTime/people');
|
||||
define('TERMS_AND_CONDITIONS_URL' , 'https://github.com/LibreTime/libretime/blob/master/README.md');
|
||||
define('PRIVACY_POLICY_URL' , 'https://github.com/LibreTime/code-of-conduct/blob/master/CODE_OF_CONDUCT.md');
|
||||
define('USER_MANUAL_URL' , 'http://libretime.org/manual/');
|
||||
define('USER_MANUAL_URL' , 'http://libretime.org/');
|
||||
define('ABOUT_AIRTIME_URL' , 'http://libretime.org');
|
||||
define('AIRTIME_TRANSIFEX_URL' , 'http://libretime.org/translating/');
|
||||
define('SUPPORT_TICKET_URL' , 'https://github.com/LibreTime/libretime/issues');
|
||||
define('LIBRETIME_CONTRIBUTE_URL' , 'https://libretime.org/contribute');
|
||||
define('LIBRETIME_DISCOURSE_URL' , 'https://discourse.libretime.org');
|
||||
define('UI_REVAMP_EMBED_URL' , 'https://www.youtube.com/embed/nqpNnCKGluY');
|
||||
define('LIBRETIME_WHATS_NEW_URL' , 'https://github.com/LibreTime/libretime/releases');
|
||||
define('LIBRETIME_UPDATE_FEED' , 'https://github.com/LibreTime/libretime/releases.atom');
|
||||
|
@ -81,6 +81,9 @@ define('MDATA_KEY_REPLAYGAIN' , 'replay_gain');
|
|||
define('MDATA_KEY_OWNER_ID' , 'owner_id');
|
||||
define('MDATA_KEY_CUE_IN' , 'cuein');
|
||||
define('MDATA_KEY_CUE_OUT' , 'cueout');
|
||||
define('MDATA_KEY_ARTWORK' , 'artwork');
|
||||
define('MDATA_KEY_ARTWORK_DATA', 'artwork_data');
|
||||
define('MDATA_KEY_TRACK_TYPE' , 'track_type');
|
||||
|
||||
define('UI_MDATA_VALUE_FORMAT_FILE' , 'File');
|
||||
define('UI_MDATA_VALUE_FORMAT_STREAM' , 'live stream');
|
||||
|
@ -106,25 +109,9 @@ define('UI_PLAYLISTCONTROLLER_OBJ_SESSNAME', 'PLAYLISTCONTROLLER_OBJ');
|
|||
/*define('UI_PLAYLIST_SESSNAME', 'PLAYLIST');
|
||||
define('UI_BLOCK_SESSNAME', 'BLOCK');*/
|
||||
|
||||
// Google Analytics integration
|
||||
define('LIBRETIME_ENABLE_GOOGLE_ANALYTICS', false);
|
||||
|
||||
//WHMCS integration
|
||||
define('LIBRETIME_ENABLE_WHMCS', false);
|
||||
define('WHMCS_PASSWORD_RESET_URL', 'https://account.example.com/pwreset.php');
|
||||
define('WHMCS_API_URL' , 'https://account.example.org/includes/api.php');
|
||||
define('SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME', 'Choose your domain');
|
||||
|
||||
//LiveChat integration
|
||||
define('LIBRETIME_ENABLE_LIVECHAT', false);
|
||||
|
||||
//Sentry error logging
|
||||
define('SENTRY_CONFIG_PATH', LIBRETIME_CONF_DIR . '/sentry.airtime_web.ini');
|
||||
|
||||
//Provisioning status
|
||||
define('PROVISIONING_STATUS_SUSPENDED' , 'Suspended');
|
||||
define('PROVISIONING_STATUS_ACTIVE' , 'Active');
|
||||
|
||||
//TuneIn integration
|
||||
define("TUNEIN_API_URL", "http://air.radiotime.com/Playing.ashx");
|
||||
|
||||
|
@ -150,6 +137,3 @@ define('STATION_PODCAST_SERVICE_NAME', 'station_podcast');
|
|||
//define('IMPORTED_PODCAST', 1);
|
||||
|
||||
define('ITUNES_XML_NAMESPACE_URL', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
|
||||
|
||||
// Billing configuration
|
||||
define('LIBRETIME_ENABLE_BILLING', false);
|
||||
|
|
|
@ -57,21 +57,14 @@ $pages[] = array(
|
|||
'module' => 'default',
|
||||
'controller' => 'embeddablewidgets',
|
||||
'action' => 'schedule',
|
||||
),
|
||||
array(
|
||||
'label' => _('Facebook'),
|
||||
'module' => 'default',
|
||||
'controller' => 'embeddablewidgets',
|
||||
'action' => 'facebook',
|
||||
)
|
||||
)
|
||||
);
|
||||
$pages[] = array(
|
||||
'label' => _("Settings"),
|
||||
'resource' => 'preference',
|
||||
'action' => 'index',
|
||||
'action' => 'edit-user',
|
||||
'module' => 'default',
|
||||
'controller' => 'preference',
|
||||
'controller' => 'user',
|
||||
'class' => '<i class="icon-cog icon-white"></i>',
|
||||
'title' => 'Settings',
|
||||
'pages' => array(
|
||||
|
@ -84,8 +77,7 @@ $pages[] = array(
|
|||
array(
|
||||
'label' => _('My Profile'),
|
||||
'controller' => 'user',
|
||||
'action' => 'edit-user',
|
||||
'resource' => 'usersettings'
|
||||
'action' => 'edit-user'
|
||||
),
|
||||
array(
|
||||
'label' => _('Users'),
|
||||
|
@ -93,6 +85,12 @@ $pages[] = array(
|
|||
'controller' => 'user',
|
||||
'action' => 'add-user',
|
||||
'resource' => 'user'
|
||||
),array(
|
||||
'label' => _('Track Types'),
|
||||
'module' => 'default',
|
||||
'controller' => 'tracktype',
|
||||
'action' => 'add-tracktype',
|
||||
'resource' => 'tracktype'
|
||||
),
|
||||
array(
|
||||
'label' => _('Streams'),
|
||||
|
@ -140,40 +138,16 @@ $pages[] = array(
|
|||
'action' => 'index',
|
||||
'resource' => 'listenerstat'
|
||||
),
|
||||
array(
|
||||
'label' => _('Show Listener Stats'),
|
||||
'module' => 'default',
|
||||
'controller' => 'listenerstat',
|
||||
'action' => 'show',
|
||||
'resource' => 'showlistenerstat'
|
||||
),
|
||||
|
||||
)
|
||||
);
|
||||
if (LIBRETIME_ENABLE_BILLING === true) {
|
||||
$pages[] = array(
|
||||
'label' => (Application_Model_Preference::GetPlanLevel()=="trial") ? "<i class='icon-star icon-orange'></i><span style='color: #ff5d1a'>"._('Upgrade')."</span>" : "<i class='icon-briefcase icon-white'></i>"._('Billing'),
|
||||
'controller' => 'billing',
|
||||
'action' => 'upgrade',
|
||||
'resource' => 'billing',
|
||||
'title' => 'Billing',
|
||||
'pages' => array(
|
||||
array(
|
||||
'label' => _('Account Plans'),
|
||||
'module' => 'default',
|
||||
'controller' => 'billing',
|
||||
'action' => 'upgrade',
|
||||
'resource' => 'billing'
|
||||
),
|
||||
array(
|
||||
'label' => _('Account Details'),
|
||||
'module' => 'default',
|
||||
'controller' => 'billing',
|
||||
'action' => 'client',
|
||||
'resource' => 'billing'
|
||||
),
|
||||
array(
|
||||
'label' => _('View Invoices'),
|
||||
'module' => 'default',
|
||||
'controller' => 'billing',
|
||||
'action' => 'invoices',
|
||||
'resource' => 'billing'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$pages[] = array(
|
||||
'label' => _('Help'),
|
||||
'controller' => 'dashboard',
|
||||
|
@ -200,13 +174,13 @@ $pages[] = array(
|
|||
'target' => "_blank"
|
||||
),
|
||||
array(
|
||||
'label' => _('File a Support Ticket'),
|
||||
'uri' => SUPPORT_TICKET_URL,
|
||||
'label' => _('Get Help Online'),
|
||||
'uri' => LIBRETIME_DISCOURSE_URL,
|
||||
'target' => "_blank"
|
||||
),
|
||||
array(
|
||||
'label' => _(sprintf("Help Translate %s", PRODUCT_NAME)),
|
||||
'uri' => AIRTIME_TRANSIFEX_URL,
|
||||
'label' => _('Contribute to LibreTime'),
|
||||
'uri' => LIBRETIME_CONTRIBUTE_URL,
|
||||
'target' => "_blank"
|
||||
),
|
||||
array(
|
||||
|
@ -223,4 +197,4 @@ $container = new Zend_Navigation($pages);
|
|||
$container->id = "nav";
|
||||
|
||||
//store it in the registry:
|
||||
Zend_Registry::set('Zend_Navigation', $container);
|
||||
Zend_Registry::set('Zend_Navigation', $container);
|
||||
|
|
|
@ -15,17 +15,19 @@ class ApiController extends Zend_Controller_Action
|
|||
}
|
||||
|
||||
//Ignore API key and session authentication for these APIs:
|
||||
$ignoreAuth = array("live-info",
|
||||
"live-info-v2",
|
||||
"week-info",
|
||||
"station-metadata",
|
||||
$ignoreAuth = array("live-info",
|
||||
"live-info-v2",
|
||||
"week-info",
|
||||
"station-metadata",
|
||||
"station-logo",
|
||||
"show-history-feed",
|
||||
"show-history-feed",
|
||||
"item-history-feed",
|
||||
"shows",
|
||||
"show-tracks",
|
||||
"show-schedules",
|
||||
"show-logo",
|
||||
"track",
|
||||
"track-types",
|
||||
"stream-m3u"
|
||||
);
|
||||
|
||||
|
@ -57,7 +59,6 @@ class ApiController extends Zend_Controller_Action
|
|||
->addActionContext('status' , 'json')
|
||||
->addActionContext('register-component' , 'json')
|
||||
->addActionContext('update-liquidsoap-status' , 'json')
|
||||
->addActionContext('live-chat' , 'json')
|
||||
->addActionContext('update-file-system-mount' , 'json')
|
||||
->addActionContext('handle-watched-dir-missing' , 'json')
|
||||
->addActionContext('rabbitmq-do-push' , 'json')
|
||||
|
@ -178,6 +179,7 @@ class ApiController extends Zend_Controller_Action
|
|||
//Used by the SaaS monitoring
|
||||
public function onAirLightAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
|
@ -185,12 +187,16 @@ class ApiController extends Zend_Controller_Action
|
|||
$result["on_air_light"] = false;
|
||||
$result["on_air_light_expected_status"] = false;
|
||||
$result["station_down"] = false;
|
||||
$result["master_stream"] = false;
|
||||
$result["live_stream"] = false;
|
||||
$result["master_stream_on_air"] = false;
|
||||
$result["live_stream_on_air"] = false;
|
||||
|
||||
$range = Application_Model_Schedule::GetPlayOrderRange();
|
||||
|
||||
$isItemCurrentlyScheduled = !is_null($range["current"]) && count($range["currentShow"]) > 0 ? true : false;
|
||||
$isItemCurrentlyScheduled = !is_null($range["tracks"]["current"]) && count($range["tracks"]["current"]) > 0 ? true : false;
|
||||
|
||||
$isCurrentItemPlaying = $range["current"]["media_item_played"] ? true : false;
|
||||
$isCurrentItemPlaying = $range["tracks"]["current"]["media_item_played"] ? true : false;
|
||||
|
||||
if ($isItemCurrentlyScheduled ||
|
||||
Application_Model_Preference::GetSourceSwitchStatus("live_dj") == "on" ||
|
||||
|
@ -210,9 +216,28 @@ class ApiController extends Zend_Controller_Action
|
|||
$result["station_down"] = true;
|
||||
}
|
||||
|
||||
$live_dj_stream = Application_Model_Preference::GetSourceStatus("live_dj");
|
||||
$master_dj_stream = Application_Model_Preference::GetSourceStatus("master_dj");
|
||||
$live_dj_on_air = Application_Model_Preference::GetSourceSwitchStatus("live_dj");
|
||||
$master_dj_on_air = Application_Model_Preference::GetSourceSwitchStatus("master_dj");
|
||||
|
||||
if($live_dj_stream == true){
|
||||
$result["live_stream"] = true;
|
||||
if ($live_dj_on_air == "on") {
|
||||
$result["live_stream_on_air"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($master_dj_stream == true){
|
||||
$result["master_stream"] = true;
|
||||
if ($master_dj_on_air == "on") {
|
||||
$result["master_stream_on_air"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->returnJsonOrJsonp($request, $result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the currently playing show as well as upcoming shows.
|
||||
* Number of shows returned and the time interval in which to
|
||||
|
@ -234,18 +259,18 @@ class ApiController extends Zend_Controller_Action
|
|||
// disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
|
||||
$utcTimeNow = gmdate(DEFAULT_TIMESTAMP_FORMAT);
|
||||
$utcTimeEnd = ""; // if empty, getNextShows will use interval instead of end of day
|
||||
|
||||
|
||||
// default to the station timezone
|
||||
$timezone = Application_Model_Preference::GetDefaultTimezone();
|
||||
$userDefinedTimezone = strtolower($request->getParam('timezone'));
|
||||
$upcase = false; // only upcase the timezone abbreviations
|
||||
$this->updateTimezone($userDefinedTimezone, $timezone, $upcase);
|
||||
|
||||
|
||||
$type = $request->getParam('type');
|
||||
$limit = $request->getParam('limit');
|
||||
if ($limit == "" || !is_numeric($limit)) {
|
||||
|
@ -255,12 +280,12 @@ class ApiController extends Zend_Controller_Action
|
|||
* we are using two entirely different codepaths for very similar functionality (type = endofday
|
||||
* vs type = interval). Needs to be fixed for 2.3 - MK */
|
||||
if ($type == "endofday") {
|
||||
|
||||
|
||||
// make getNextShows use end of day
|
||||
$end = Application_Common_DateHelper::getTodayStationEndDateTime();
|
||||
$end->setTimezone(new DateTimeZone("UTC"));
|
||||
$utcTimeEnd = $end->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
|
||||
$result = array(
|
||||
"env" => APPLICATION_ENV,
|
||||
"schedulerTime" => $utcTimeNow,
|
||||
|
@ -271,6 +296,26 @@ class ApiController extends Zend_Controller_Action
|
|||
$result = Application_Model_Schedule::GetPlayOrderRangeOld($limit);
|
||||
}
|
||||
|
||||
$stationUrl = Application_Common_HTTPHelper::getStationUrl();
|
||||
|
||||
if (($result["previous"]["type"] != "livestream") && isset($result["previous"]["metadata"])) {
|
||||
$previousID = $result["previous"]["metadata"]["id"];
|
||||
$get_prev_artwork_url = $stationUrl . 'api/track?id='. $previousID .'&return=artwork';
|
||||
$result["previous"]["metadata"]["artwork_url"] = $get_prev_artwork_url;
|
||||
}
|
||||
|
||||
if (($result["current"]["type"] != "livestream") && isset($result["current"]["metadata"])) {
|
||||
$currID = $result["current"]["metadata"]["id"];
|
||||
$get_curr_artwork_url = $stationUrl . 'api/track?id='. $currID .'&return=artwork';
|
||||
$result["current"]["metadata"]["artwork_url"] = $get_curr_artwork_url;
|
||||
}
|
||||
|
||||
if (($result["next"]["type"] != "livestream") && isset($result["next"]["metadata"])) {
|
||||
$nextID = $result["next"]["metadata"]["id"];
|
||||
$get_next_artwork_url = $stationUrl . 'api/track?id='. $nextID .'&return=artwork';
|
||||
$result["next"]["metadata"]["artwork_url"] = $get_next_artwork_url;
|
||||
}
|
||||
|
||||
// apply user-defined timezone, or default to station
|
||||
Application_Common_DateHelper::convertTimestampsToTimezone(
|
||||
$result['currentShow'],
|
||||
|
@ -282,7 +327,7 @@ class ApiController extends Zend_Controller_Action
|
|||
array("starts", "ends", "start_timestamp","end_timestamp"),
|
||||
$timezone
|
||||
);
|
||||
|
||||
|
||||
//Convert the UTC scheduler time ("now") to the user-defined timezone.
|
||||
$result["schedulerTime"] = Application_Common_DateHelper::UTCStringToTimezoneString($result["schedulerTime"], $timezone);
|
||||
$result["timezone"] = $upcase ? strtoupper($timezone) : $timezone;
|
||||
|
@ -326,13 +371,13 @@ class ApiController extends Zend_Controller_Action
|
|||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
|
||||
// default to the station timezone
|
||||
$timezone = Application_Model_Preference::GetDefaultTimezone();
|
||||
$userDefinedTimezone = strtolower($request->getParam('timezone'));
|
||||
$upcase = false; // only upcase the timezone abbreviations
|
||||
$this->updateTimezone($userDefinedTimezone, $timezone, $upcase);
|
||||
|
||||
|
||||
$daysToRetrieve = $request->getParam('days');
|
||||
$showsToRetrieve = $request->getParam('shows');
|
||||
if ($daysToRetrieve == "" || !is_numeric($daysToRetrieve)) {
|
||||
|
@ -341,7 +386,7 @@ class ApiController extends Zend_Controller_Action
|
|||
if ($showsToRetrieve == "" || !is_numeric($showsToRetrieve)) {
|
||||
$showsToRetrieve = self::DEFAULT_SHOWS_TO_RETRIEVE;
|
||||
}
|
||||
|
||||
|
||||
// set the end time to the day's start n days from now.
|
||||
// days=1 will return shows until the end of the current day,
|
||||
// days=2 will return shows until the end of tomorrow, etc.
|
||||
|
@ -350,7 +395,7 @@ class ApiController extends Zend_Controller_Action
|
|||
$utcTimeEnd = $end->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
$result = Application_Model_Schedule::GetPlayOrderRange($utcTimeEnd, $showsToRetrieve);
|
||||
|
||||
|
||||
// apply user-defined timezone, or default to station
|
||||
$this->applyLiveTimezoneAdjustments($result, $timezone, $upcase);
|
||||
|
||||
|
@ -359,7 +404,16 @@ class ApiController extends Zend_Controller_Action
|
|||
|
||||
// convert image paths to point to api endpoints
|
||||
WidgetHelper::findAndConvertPaths($result);
|
||||
|
||||
|
||||
// Expose the live source status
|
||||
$live_dj = Application_Model_Preference::GetSourceSwitchStatus('live_dj') ;
|
||||
$master_dj = Application_Model_Preference::GetSourceSwitchStatus('master_dj') ;
|
||||
$scheduled_play = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play') ;
|
||||
$result["sources"] = array();
|
||||
$result["sources"]["livedj"] = $live_dj;
|
||||
$result["sources"]["masterdj"] = $master_dj;
|
||||
$result["sources"]["scheduledplay"] = $scheduled_play;
|
||||
|
||||
// used by caller to determine if the airtime they are running or widgets in use is out of date.
|
||||
$result["station"]["AIRTIME_API_VERSION"] = AIRTIME_API_VERSION;
|
||||
|
||||
|
@ -370,12 +424,12 @@ class ApiController extends Zend_Controller_Action
|
|||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that the value for the timezone the user gave is valid.
|
||||
* If it is, override the default (station) timezone.
|
||||
* Check that the value for the timezone the user gave is valid.
|
||||
* If it is, override the default (station) timezone.
|
||||
* If it's an abbreviation (pst, edt) we upcase the output.
|
||||
*
|
||||
*
|
||||
* @param string $userDefinedTimezone the requested timezone value
|
||||
* @param string $timezone the default timezone
|
||||
* @param boolean $upcase whether the timezone output should be upcased
|
||||
|
@ -396,28 +450,28 @@ class ApiController extends Zend_Controller_Action
|
|||
$timezone = $userDefinedTimezone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the user passed in a timezone parameter, adjust timezone-dependent
|
||||
* If the user passed in a timezone parameter, adjust timezone-dependent
|
||||
* variables in the result to reflect the given timezone.
|
||||
*
|
||||
*
|
||||
* @param array $result reference to the object to send back to the user
|
||||
* @param string $timezone the user's timezone parameter value
|
||||
* @param boolean $upcase whether the timezone output should be upcased
|
||||
*/
|
||||
private function applyLiveTimezoneAdjustments(&$result, $timezone, $upcase)
|
||||
private function applyLiveTimezoneAdjustments(&$result, $timezone, $upcase)
|
||||
{
|
||||
Application_Common_DateHelper::convertTimestampsToTimezone(
|
||||
$result,
|
||||
array("starts", "ends", "start_timestamp","end_timestamp"),
|
||||
$timezone
|
||||
);
|
||||
|
||||
|
||||
//Convert the UTC scheduler time ("now") to the user-defined timezone.
|
||||
$result["station"]["schedulerTime"] = Application_Common_DateHelper::UTCStringToTimezoneString($result["station"]["schedulerTime"], $timezone);
|
||||
$result["station"]["timezone"] = $upcase ? strtoupper($timezone) : $timezone;
|
||||
}
|
||||
|
||||
|
||||
public function weekInfoAction()
|
||||
{
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||
|
@ -438,11 +492,11 @@ class ApiController extends Zend_Controller_Action
|
|||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* API endpoint to display the show logo
|
||||
*/
|
||||
public function showLogoAction()
|
||||
public function showLogoAction()
|
||||
{
|
||||
// Disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
|
@ -459,7 +513,7 @@ class ApiController extends Zend_Controller_Action
|
|||
if (empty($show)) {
|
||||
throw new ZendActionHttpException($this, 400, "ERROR: No show with ID $showId exists.");
|
||||
}
|
||||
|
||||
|
||||
$path = $show->getDbImagePath();
|
||||
try {
|
||||
$mime_type = mime_content_type($path);
|
||||
|
@ -488,9 +542,116 @@ class ApiController extends Zend_Controller_Action
|
|||
header('HTTP/1.0 401 Unauthorized');
|
||||
print _('You are not allowed to access this resource. ');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* New API endpoint to display metadata from any single track
|
||||
*
|
||||
* Find metadata to any track imported (eg. id=1&return=json)
|
||||
*
|
||||
* @param int $id track ID
|
||||
* @param string $return json, artwork_data, or artwork
|
||||
*
|
||||
*/
|
||||
public function trackAction()
|
||||
{
|
||||
// Disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$trackid = $request->getParam('id');
|
||||
$return = $request->getParam('return');
|
||||
|
||||
if (empty($return)) {
|
||||
throw new ZendActionHttpException($this, 400, "ERROR: No return was given.");
|
||||
}
|
||||
|
||||
if (empty($trackid)) {
|
||||
throw new ZendActionHttpException($this, 400, "ERROR: No ID was given.");
|
||||
}
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$fp = $storDir->getDirectory();
|
||||
|
||||
//$this->view->type = $type;
|
||||
$file = Application_Model_StoredFile::RecallById($trackid);
|
||||
$md = $file->getMetadata();
|
||||
|
||||
if ($return === "artwork-data") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderDataURI($fp . $md['MDATA_KEY_ARTWORK']);
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork-data-32") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderDataURI($fp . $md['MDATA_KEY_ARTWORK']. '-32');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork") {
|
||||
//default
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderImage($fp . $md['MDATA_KEY_ARTWORK'].'-512.jpg');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork-32") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderImage($fp . $md['MDATA_KEY_ARTWORK'].'-32.jpg');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork-64") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderImage($fp . $md['MDATA_KEY_ARTWORK'].'-64.jpg');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork-128") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderImage($fp . $md['MDATA_KEY_ARTWORK'].'-128.jpg');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "artwork-512") {
|
||||
foreach ($md as $key => $value) {
|
||||
if ($key == 'MDATA_KEY_ARTWORK' && !is_null($value)) {
|
||||
FileDataHelper::renderImage($fp . $md['MDATA_KEY_ARTWORK'].'-512.jpg');
|
||||
}
|
||||
}
|
||||
} elseif ($return === "json") {
|
||||
$data =json_encode($md);
|
||||
echo $data;
|
||||
}
|
||||
|
||||
} else {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
print _('You are not allowed to access this resource. ');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
public function trackTypesAction()
|
||||
{
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||
// disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$tracktypes = Application_Model_Tracktype::getTracktypes();
|
||||
$this->_helper->json->sendJson($tracktypes);
|
||||
} else {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
print _('You are not allowed to access this resource. ');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API endpoint to provide station metadata
|
||||
*/
|
||||
|
@ -500,18 +661,18 @@ class ApiController extends Zend_Controller_Action
|
|||
// disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$baseDir = Application_Common_OsPath::formatDirectoryWithDirectorySeparators($CC_CONFIG['baseDir']);
|
||||
$path = 'http://'.$_SERVER['HTTP_HOST'].$baseDir."api/station-logo";
|
||||
|
||||
|
||||
$result["name"] = Application_Model_Preference::GetStationName();
|
||||
$result["logo"] = $path;
|
||||
$result["description"] = Application_Model_Preference::GetStationDescription();
|
||||
$result["timezone"] = Application_Model_Preference::GetDefaultTimezone();
|
||||
$result["locale"] = Application_Model_Preference::GetDefaultLocale();
|
||||
$result["stream_data"] = Application_Model_StreamSetting::getEnabledStreamData();
|
||||
|
||||
|
||||
// used by caller to determine if the airtime they are running or widgets in use is out of date.
|
||||
$result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION;
|
||||
|
||||
|
@ -526,27 +687,27 @@ class ApiController extends Zend_Controller_Action
|
|||
/**
|
||||
* API endpoint to display the current station logo
|
||||
*/
|
||||
public function stationLogoAction()
|
||||
public function stationLogoAction()
|
||||
{
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||
// disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
|
||||
$logo = Application_Model_Preference::GetStationLogo();
|
||||
// if there's no logo, just die - redirects to a 404
|
||||
if (!$logo || $logo === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// we're passing this as an image instead of using it in a data uri, so decode it
|
||||
$blob = base64_decode($logo);
|
||||
|
||||
|
||||
// use finfo to get the mimetype from the decoded blob
|
||||
$f = finfo_open();
|
||||
$mime_type = finfo_buffer($f, $blob, FILEINFO_MIME_TYPE);
|
||||
finfo_close($f);
|
||||
|
||||
|
||||
header("Content-Type: " . $mime_type);
|
||||
echo $blob;
|
||||
} else {
|
||||
|
@ -555,7 +716,7 @@ class ApiController extends Zend_Controller_Action
|
|||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function scheduleAction()
|
||||
{
|
||||
$this->view->layout()->disableLayout();
|
||||
|
@ -571,13 +732,13 @@ class ApiController extends Zend_Controller_Action
|
|||
public function notifyMediaItemStartPlayAction()
|
||||
{
|
||||
$media_id = $this->_getParam("media_id");
|
||||
|
||||
|
||||
// We send a fake media id when playing on-demand ads;
|
||||
// in this case, simply return
|
||||
if ($media_id === '0' || $media_id === '-1') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Logging::debug("Received notification of new media item start: $media_id");
|
||||
Application_Model_Schedule::UpdateMediaPlayedStatus($media_id);
|
||||
|
||||
|
@ -619,7 +780,7 @@ class ApiController extends Zend_Controller_Action
|
|||
|
||||
$this->_helper->json->sendJson(array("status"=>1, "message"=>""));
|
||||
}
|
||||
|
||||
|
||||
public function recordedShowsAction()
|
||||
{
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
|
@ -637,7 +798,7 @@ class ApiController extends Zend_Controller_Action
|
|||
$this->view->server_timezone = Application_Model_Preference::GetDefaultTimezone();
|
||||
|
||||
$rows = Application_Model_Show::getCurrentShow();
|
||||
|
||||
|
||||
if (count($rows) > 0) {
|
||||
$this->view->is_recording = ($rows[0]['record'] == 1);
|
||||
}
|
||||
|
@ -664,7 +825,7 @@ class ApiController extends Zend_Controller_Action
|
|||
try {
|
||||
$show_inst = new Application_Model_ShowInstance($show_instance_id);
|
||||
$show_inst->setRecordedFile($file_id);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
//we've reached here probably because the show was
|
||||
//cancelled, and therefore the show instance does not exist
|
||||
|
@ -717,7 +878,7 @@ class ApiController extends Zend_Controller_Action
|
|||
if ($md['is_record'] != 0) {
|
||||
$this->uploadRecordedActionParam($md['MDATA_KEY_TRACKNUMBER'], $file->getId());
|
||||
}
|
||||
|
||||
|
||||
} elseif ($mode == "modify") {
|
||||
$filepath = $md['MDATA_KEY_FILEPATH'];
|
||||
$file = Application_Model_StoredFile::RecallByFilepath($filepath, $con);
|
||||
|
@ -830,7 +991,7 @@ class ApiController extends Zend_Controller_Action
|
|||
} catch (Exception $e) {
|
||||
Logging::warn($e->getMessage());
|
||||
Logging::warn(gettype($e));
|
||||
}
|
||||
}
|
||||
// We tack on the 'key' back to every request in case the would like to associate
|
||||
// his requests with particular responses
|
||||
$response['key'] = $k;
|
||||
|
@ -1085,7 +1246,7 @@ class ApiController extends Zend_Controller_Action
|
|||
} elseif ($djtype == "dj") {
|
||||
//check against show dj auth
|
||||
$showInfo = Application_Model_Show::getCurrentShow();
|
||||
|
||||
|
||||
// there is current playing show
|
||||
if (isset($showInfo[0]['id'])) {
|
||||
$current_show_id = $showInfo[0]['id'];
|
||||
|
@ -1139,12 +1300,12 @@ class ApiController extends Zend_Controller_Action
|
|||
|
||||
$this->_helper->json->sendJson($rows);
|
||||
}
|
||||
|
||||
|
||||
public function getFilesWithoutSilanValueAction()
|
||||
{
|
||||
//connect to db and get get sql
|
||||
$rows = Application_Model_StoredFile::getAllFilesWithoutSilan();
|
||||
|
||||
|
||||
$this->_helper->json->sendJson($rows);
|
||||
}
|
||||
|
||||
|
@ -1163,7 +1324,7 @@ class ApiController extends Zend_Controller_Action
|
|||
|
||||
$this->_helper->json->sendJson(array());
|
||||
}
|
||||
|
||||
|
||||
public function updateCueValuesBySilanAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
|
@ -1213,12 +1374,12 @@ class ApiController extends Zend_Controller_Action
|
|||
$data = $request->getParam("data");
|
||||
$media_id = intval($request->getParam("media_id"));
|
||||
$data_arr = json_decode($data);
|
||||
|
||||
|
||||
//$media_id is -1 sometimes when a stream has stopped playing
|
||||
if (!is_null($media_id) && $media_id > 0) {
|
||||
|
||||
if (isset($data_arr->title)) {
|
||||
|
||||
|
||||
$data_title = substr($data_arr->title, 0, 1024);
|
||||
|
||||
$previous_metadata = CcWebstreamMetadataQuery::create()
|
||||
|
@ -1235,20 +1396,20 @@ class ApiController extends Zend_Controller_Action
|
|||
}
|
||||
|
||||
if ($do_insert) {
|
||||
|
||||
|
||||
$startDT = new DateTime("now", new DateTimeZone("UTC"));
|
||||
|
||||
|
||||
$webstream_metadata = new CcWebstreamMetadata();
|
||||
$webstream_metadata->setDbInstanceId($media_id);
|
||||
$webstream_metadata->setDbStartTime($startDT);
|
||||
$webstream_metadata->setDbLiquidsoapData($data_title);
|
||||
$webstream_metadata->save();
|
||||
|
||||
|
||||
$historyService = new Application_Service_HistoryService();
|
||||
$historyService->insertWebstreamMetadata($media_id, $startDT, $data_arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->response = $data;
|
||||
$this->view->media_id = $media_id;
|
||||
|
@ -1271,11 +1432,11 @@ class ApiController extends Zend_Controller_Action
|
|||
Application_Model_ListenerStat::insertDataPoints($data);
|
||||
$this->view->data = $data;
|
||||
}
|
||||
|
||||
|
||||
public function updateStreamSettingTableAction() {
|
||||
$request = $this->getRequest();
|
||||
$data = json_decode($request->getParam("data"), true);
|
||||
|
||||
|
||||
foreach ($data as $k=>$v) {
|
||||
Application_Model_StreamSetting::SetListenerStatError($k, $v);
|
||||
}
|
||||
|
@ -1317,9 +1478,9 @@ class ApiController extends Zend_Controller_Action
|
|||
$request = $this->getRequest();
|
||||
$params = $request->getParams();
|
||||
$userId = $request->getParam("user_id", null);
|
||||
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
|
||||
|
||||
$historyService = new Application_Service_HistoryService();
|
||||
$shows = $historyService->getShowList($startsDT, $endsDT, $userId);
|
||||
|
||||
|
@ -1343,8 +1504,8 @@ class ApiController extends Zend_Controller_Action
|
|||
$params = $request->getParams();
|
||||
$showId = $request->getParam("show_id", null);
|
||||
$results = array();
|
||||
|
||||
if (empty($showId)) {
|
||||
|
||||
if (empty($showId)) {
|
||||
$shows = CcShowQuery::create()->find();
|
||||
foreach($shows as $show) {
|
||||
$results[] = $show->getShowInfo();
|
||||
|
@ -1361,19 +1522,19 @@ class ApiController extends Zend_Controller_Action
|
|||
Logging::info($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* display show schedule for given show_id
|
||||
*
|
||||
* @return json array
|
||||
*/
|
||||
public function showSchedulesAction()
|
||||
public function showSchedulesAction()
|
||||
{
|
||||
try {
|
||||
$request = $this->getRequest();
|
||||
$params = $request->getParams();
|
||||
$showId = $request->getParam("show_id", null);
|
||||
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
|
||||
if ((!isset($showId)) || (!is_numeric($showId))) {
|
||||
|
@ -1382,7 +1543,7 @@ class ApiController extends Zend_Controller_Action
|
|||
array("jsonrpc" => "2.0", "error" => array("code" => 400, "message" => "missing invalid type for required show_id parameter. use type int.".$showId))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$shows = Application_Model_Show::getShows($startsDT, $endsDT, FALSE, $showId);
|
||||
|
||||
// is this a valid show?
|
||||
|
@ -1400,7 +1561,7 @@ class ApiController extends Zend_Controller_Action
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* displays track listing for given instance_id
|
||||
*
|
||||
|
@ -1421,7 +1582,7 @@ class ApiController extends Zend_Controller_Action
|
|||
|
||||
$showInstance = new Application_Model_ShowInstance($instanceId);
|
||||
$showInstanceContent = $showInstance->getShowListContent($prefTimezone);
|
||||
|
||||
|
||||
// is this a valid show instance with content?
|
||||
if (empty($showInstanceContent)) {
|
||||
$this->_helper->json->sendJson(
|
||||
|
|
|
@ -1,301 +0,0 @@
|
|||
<?php
|
||||
|
||||
define('VAT_RATE', 19.00);
|
||||
|
||||
class BillingController extends Zend_Controller_Action {
|
||||
|
||||
public function init()
|
||||
{
|
||||
//Two of the actions in this controller return JSON because they're used for AJAX:
|
||||
$ajaxContext = $this->_helper->getHelper('AjaxContext');
|
||||
$ajaxContext->addActionContext('vat-validator', 'json')
|
||||
->addActionContext('is-country-in-eu', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$this->_redirect('billing/upgrade');
|
||||
}
|
||||
|
||||
public function upgradeAction()
|
||||
{
|
||||
//If you're not on a trial and you're suspended, we don't let you access the plans page and redirect you to the invoices
|
||||
//page to force you to pay your bills first.
|
||||
$isTrial = (Application_Model_Preference::GetPlanLevel() == 'trial');
|
||||
if (!$isTrial && (Application_Model_Preference::getProvisioningStatus() == PROVISIONING_STATUS_SUSPENDED)) {
|
||||
$this->_redirect('billing/invoices');
|
||||
}
|
||||
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Billing');
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']);
|
||||
Billing::ensureClientIdIsValid();
|
||||
|
||||
//Zend's CSRF token element requires the session to be open for writing
|
||||
SessionHelper::reopenSessionForWriting();
|
||||
|
||||
$request = $this->getRequest();
|
||||
$form = new Application_Form_BillingUpgradeDowngrade();
|
||||
|
||||
if ($request->isPost()) {
|
||||
|
||||
$formData = $request->getPost();
|
||||
|
||||
if ($form->isValid($formData)) {
|
||||
|
||||
$credentials = Billing::getAPICredentials();
|
||||
|
||||
//Check if VAT should be applied or not to this invoice.
|
||||
if (in_array("7", $formData["customfields"])) {
|
||||
$apply_vat = Billing::checkIfVatShouldBeApplied($formData["customfields"]["7"], $formData["country"]);
|
||||
} else {
|
||||
$apply_vat = false;
|
||||
}
|
||||
|
||||
$placeAnUpgradeOrder = true;
|
||||
|
||||
$currentPlanProduct = Billing::getClientCurrentAirtimeProduct();
|
||||
$currentPlanProductId = $currentPlanProduct["pid"];
|
||||
$currentPlanProductBillingCycle = strtolower($currentPlanProduct["billingcycle"]);
|
||||
//If there's been no change in the plan or the billing cycle, we should not
|
||||
//place an upgrade order. WHMCS doesn't allow this in its web interface,
|
||||
//and it freaks out and does the wrong thing if we do it via the API
|
||||
//so we have to do avoid that.
|
||||
if (($currentPlanProductId == $formData["newproductid"]) &&
|
||||
($currentPlanProductBillingCycle == $formData["newproductbillingcycle"])
|
||||
) {
|
||||
$placeAnUpgradeOrder = false;
|
||||
}
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "upgradeproduct";
|
||||
$postfields["clientid"] = Application_Model_Preference::GetClientId();
|
||||
|
||||
$postfields["serviceid"] = Billing::getClientInstanceId();
|
||||
$postfields["type"] = "product";
|
||||
$postfields["newproductid"] = $formData["newproductid"];
|
||||
$postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"];
|
||||
$postfields["paymentmethod"] = $formData["paymentmethod"];
|
||||
$postfields["responsetype"] = "json";
|
||||
|
||||
$upgrade_query_string = "";
|
||||
foreach ($postfields AS $k => $v) $upgrade_query_string .= "$k=" . urlencode($v) . "&";
|
||||
|
||||
//update client info
|
||||
|
||||
$clientfields = array();
|
||||
$clientfields["username"] = $credentials["username"];
|
||||
$clientfields["password"] = md5($credentials["password"]);
|
||||
$clientfields["action"] = "updateclient";
|
||||
$clientfields["clientid"] = Application_Model_Preference::GetClientId();
|
||||
$clientfields["customfields"] = base64_encode(serialize($formData["customfields"]));
|
||||
unset($formData["customfields"]);
|
||||
$clientfields["responsetype"] = "json";
|
||||
unset($formData["newproductid"]);
|
||||
unset($formData["newproductbillingcycle"]);
|
||||
unset($formData["paymentmethod"]);
|
||||
unset($formData["action"]);
|
||||
$clientfields = array_merge($clientfields, $formData);
|
||||
unset($clientfields["password2verify"]);
|
||||
unset($clientfields["submit"]);
|
||||
$client_query_string = "";
|
||||
foreach ($clientfields AS $k => $v) $client_query_string .= "$k=" . urlencode($v) . "&";
|
||||
|
||||
//Update the client details in WHMCS first
|
||||
$result = Billing::makeRequest($credentials["url"], $client_query_string);
|
||||
Logging::info($result);
|
||||
if ($result["result"] == "error") {
|
||||
$this->setErrorMessage();
|
||||
$this->view->form = $form;
|
||||
return;
|
||||
}
|
||||
|
||||
//If there were no changes to the plan or billing cycle, we just redirect you to the
|
||||
//invoices screen and show a message.
|
||||
if (!$placeAnUpgradeOrder) {
|
||||
$this->_redirect('billing/invoices?planupdated');
|
||||
return;
|
||||
}
|
||||
|
||||
//Then place an upgrade order in WHMCS
|
||||
$result = Billing::makeRequest($credentials["url"], $upgrade_query_string);
|
||||
if ($result["result"] == "error") {
|
||||
Logging::info($_SERVER['HTTP_HOST'] . " - Account upgrade failed. - " . $result["message"]);
|
||||
$this->setErrorMessage();
|
||||
$this->view->form = $form;
|
||||
} else {
|
||||
Logging::info($_SERVER['HTTP_HOST'] . "Account plan upgrade request:");
|
||||
Logging::info($result);
|
||||
|
||||
// Disable the view and the layout here, squashes an error.
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
if ($apply_vat) {
|
||||
Billing::addVatToInvoice($result["invoiceid"]);
|
||||
}
|
||||
|
||||
// there may not be an invoice created if the client is downgrading
|
||||
if (!empty($result["invoiceid"])) {
|
||||
self::viewInvoice($result["invoiceid"]);
|
||||
} else {
|
||||
$this->_redirect('billing/invoices?planupdated');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->view->form = $form;
|
||||
}
|
||||
} else {
|
||||
$this->view->form = $form;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function isCountryInEuAction()
|
||||
{
|
||||
// Disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$request = $this->getRequest();
|
||||
if (!$request->isPost()) {
|
||||
throw new Exception("Must POST data to isCountryInEuAction.");
|
||||
}
|
||||
$formData = $request->getPost();
|
||||
|
||||
//Set the return JSON value
|
||||
$this->_helper->json(array("result"=>Billing::isCountryInEU($formData["country"])));
|
||||
}
|
||||
|
||||
public function vatValidatorAction()
|
||||
{
|
||||
// Disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$request = $this->getRequest();
|
||||
if (!$request->isPost()) {
|
||||
throw new Exception("Must POST data to vatValidatorAction.");
|
||||
}
|
||||
$formData = $request->getPost();
|
||||
|
||||
$vatNumber = trim($formData["vatnumber"]);
|
||||
if (empty($vatNumber)) {
|
||||
$this->_helper->json(array("result"=>false));
|
||||
}
|
||||
|
||||
//Set the return JSON value
|
||||
$this->_helper->json(array("result"=>Billing::checkIfVatShouldBeApplied($vatNumber, $formData["country"])));
|
||||
}
|
||||
|
||||
|
||||
private function setErrorMessage($msg=null)
|
||||
{
|
||||
if (!is_null($msg)) {
|
||||
$this->view->errorMessage = $msg;
|
||||
} else {
|
||||
$this->view->errorMessage = "An error occurred and we could not update your account. Please contact support for help.";
|
||||
}
|
||||
}
|
||||
|
||||
private function setSuccessMessage($msg=null)
|
||||
{
|
||||
if (!is_null($msg)) {
|
||||
$this->view->successMessage = $msg;
|
||||
} else {
|
||||
$this->view->successMessage = "Your account has been updated.";
|
||||
}
|
||||
}
|
||||
|
||||
private static function viewInvoice($invoice_id)
|
||||
{
|
||||
$whmcsurl = "https://account.sourcefabric.com/dologin.php";
|
||||
$autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"];
|
||||
$timestamp = time(); //whmcs timezone?
|
||||
$client = Billing::getClientDetails();
|
||||
$email = $client["email"];
|
||||
$hash = sha1($email.$timestamp.$autoauthkey);
|
||||
$goto = "viewinvoice.php?id=".$invoice_id;
|
||||
header("Location: ".$whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto");
|
||||
}
|
||||
|
||||
public function clientAction()
|
||||
{
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Billing');
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
//Zend's CSRF token element requires the session to be open for writing
|
||||
SessionHelper::reopenSessionForWriting();
|
||||
|
||||
$request = $this->getRequest();
|
||||
$form = new Application_Form_BillingClient();
|
||||
Billing::ensureClientIdIsValid();
|
||||
if ($request->isPost()) {
|
||||
$formData = $request->getPost();
|
||||
if ($form->isValid($formData)) {
|
||||
|
||||
$credentials = Billing::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "updateclient";
|
||||
|
||||
$postfields["customfields"] = base64_encode(serialize($formData["customfields"]));
|
||||
unset($formData["customfields"]);
|
||||
|
||||
$postfields["clientid"] = Application_Model_Preference::GetClientId();
|
||||
$postfields["responsetype"] = "json";
|
||||
$postfields = array_merge($postfields, $formData);
|
||||
unset($postfields["password2verify"]);
|
||||
unset($postfields["submit"]);
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
|
||||
if ($result["result"] == "error") {
|
||||
$this->setErrorMessage();
|
||||
} else {
|
||||
$form = new Application_Form_BillingClient();
|
||||
$this->setSuccessMessage();
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
} else {
|
||||
$this->view->form = $form;
|
||||
}
|
||||
} else {
|
||||
$this->view->form = $form;
|
||||
}
|
||||
}
|
||||
|
||||
public function invoicesAction()
|
||||
{
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Billing');
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$this->view->invoices = Billing::getInvoices();
|
||||
}
|
||||
|
||||
public function invoiceAction()
|
||||
{
|
||||
Billing::ensureClientIdIsValid();
|
||||
$request = $this->getRequest();
|
||||
$invoice_id = $request->getParam('invoiceid');
|
||||
self::viewInvoice($invoice_id);
|
||||
}
|
||||
}
|
|
@ -25,9 +25,8 @@ class EmbedController extends Zend_Controller_Action
|
|||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$this->view->mrp_js = Application_Common_HTTPHelper::getStationUrl() . "js/airtime/player/mrp.js?".$CC_CONFIG['airtime_version'];
|
||||
$this->view->playerhtml5_js = Application_Common_HTTPHelper::getStationUrl() . "js/airtime/player/playerhtml5.js?".$CC_CONFIG['airtime_version'];
|
||||
$this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "js/libs/jquery-1.10.2.js";
|
||||
$this->view->muses_swf = Application_Common_HTTPHelper::getStationUrl() . "js/airtime/player/muses.swf";
|
||||
$this->view->metadata_api_url = Application_Common_HTTPHelper::getStationUrl() . "api/live-info";
|
||||
$this->view->player_title = json_encode($this->view->escape($request->getParam('title')));
|
||||
$this->view->jquery_i18n = Application_Common_HTTPHelper::getStationUrl() . "js/i18n/jquery.i18n.js?";
|
||||
|
|
|
@ -27,7 +27,7 @@ class EmbeddableWidgetsController extends Zend_Controller_Action
|
|||
} else {
|
||||
$this->view->player_error_msg = _("To configure and use the embeddable player you must:<br><br>
|
||||
1. Enable at least one MP3, AAC, or OGG stream under Settings -> Streams<br>
|
||||
2. Enable the Public Airtime API under Settings -> Preferences");
|
||||
2. Enable the Public LibreTime API under Settings -> Preferences");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,11 @@ class EmbeddableWidgetsController extends Zend_Controller_Action
|
|||
|
||||
if (!$apiEnabled) {
|
||||
$this->view->weekly_schedule_error_msg = _("To use the embeddable weekly schedule widget you must:<br><br>
|
||||
Enable the Public Airtime API under Settings -> Preferences");
|
||||
Enable the Public LibreTime API under Settings -> Preferences");
|
||||
}
|
||||
}
|
||||
|
||||
// The Facebook widget is untested & unsupported, the widget has been removed from the navigation in navigation.php
|
||||
public function facebookAction()
|
||||
{
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Widgets');
|
||||
|
@ -51,7 +52,7 @@ class EmbeddableWidgetsController extends Zend_Controller_Action
|
|||
|
||||
if (!$apiEnabled) {
|
||||
$this->view->facebook_error_msg = _("To add the Radio Tab to your Facebook Page, you must first:<br><br>
|
||||
Enable the Public Airtime API under Settings -> Preferences");
|
||||
Enable the Public LibreTime API under Settings -> Preferences");
|
||||
}
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
|
|
@ -364,6 +364,7 @@ class LibraryController extends Zend_Controller_Action
|
|||
{
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
$isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER));
|
||||
$isAdmin = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN));
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
|
@ -380,6 +381,10 @@ class LibraryController extends Zend_Controller_Action
|
|||
$form->removeActionButtons();
|
||||
$this->view->permissionDenied = true;
|
||||
}
|
||||
// only admins should be able to edit the owner of a file
|
||||
if (!$isAdmin) {
|
||||
$form->removeOwnerEdit();
|
||||
}
|
||||
|
||||
if ($request->isPost()) {
|
||||
|
||||
|
@ -387,7 +392,23 @@ class LibraryController extends Zend_Controller_Action
|
|||
$serialized = array();
|
||||
//need to convert from serialized jQuery array.
|
||||
foreach ($js as $j) {
|
||||
$serialized[$j["name"]] = $j["value"];
|
||||
//on edit, if no artwork is set and audiofile has image, automatically add it
|
||||
if ($j["name"] == "artwork") {
|
||||
if ($j["value"] == null || $j["value"] == ''){
|
||||
$serialized["artwork"] = FileDataHelper::resetArtwork($file_id);
|
||||
}
|
||||
} elseif ($j["name"] == "set_artwork") {
|
||||
if ($j["value"] != null || $j["value"] != ''){
|
||||
$serialized["artwork"] = FileDataHelper::setArtwork($file_id, $j["value"] );
|
||||
}
|
||||
} elseif ($j["name"] == "remove_artwork") {
|
||||
if ($j["value"] == 1){
|
||||
$remove_artwork = true;
|
||||
$serialized["artwork"] = FileDataHelper::removeArtwork($file_id);
|
||||
}
|
||||
} else {
|
||||
$serialized[$j["name"]] = $j["value"];
|
||||
}
|
||||
}
|
||||
|
||||
// Sanitize any wildly incorrect metadata before it goes to be validated.
|
||||
|
@ -404,6 +425,9 @@ class LibraryController extends Zend_Controller_Action
|
|||
$this->view->form = $form;
|
||||
$this->view->id = $file_id;
|
||||
$this->view->title = $file->getPropelOrm()->getDbTrackTitle();
|
||||
$this->view->artist_name = $file->getPropelOrm()->getDbArtistName();
|
||||
$this->view->filePath = $file->getPropelOrm()->getDbFilepath();
|
||||
$this->view->artwork = $file->getPropelOrm()->getDbArtwork();
|
||||
$this->view->html = $this->view->render('library/edit-file-md.phtml');
|
||||
}
|
||||
|
||||
|
@ -480,13 +504,6 @@ class LibraryController extends Zend_Controller_Action
|
|||
|
||||
public function publishDialogAction() {
|
||||
$this->_helper->layout->disableLayout();
|
||||
|
||||
|
||||
if (LIBRETIME_ENABLE_BILLING === true && !Billing::isStationPodcastAllowed()) {
|
||||
$this->renderScript("podcast/featureupgrade-pane.phtml");
|
||||
}
|
||||
|
||||
|
||||
//This just spits out publish-dialog.phtml!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ class ListenerstatController extends Zend_Controller_Action
|
|||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
|
@ -56,12 +55,76 @@ class ListenerstatController extends Zend_Controller_Action
|
|||
$this->view->errorStatus = $out;
|
||||
$this->view->date_form = $form;
|
||||
}
|
||||
public function showAction() {
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$request = $this->getRequest();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$headScript = $this->view->headScript();
|
||||
AirtimeTableView::injectTableJavaScriptDependencies($headScript, $baseUrl, $CC_CONFIG['airtime_version']);
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Analytics');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/listenerstat/showlistenerstat.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'js/datatables/plugin/TableTools-2.1.5/css/TableTools.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/show_analytics.css'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
|
||||
$this->view->showAllShows = true;
|
||||
}
|
||||
$data = [];
|
||||
$this->view->showData = $data;
|
||||
|
||||
$form = new Application_Form_ShowListenerStat();
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$startsDT->setTimezone($userTimezone);
|
||||
$endsDT->setTimezone($userTimezone);
|
||||
$form->populate(array(
|
||||
'his_date_start' => $startsDT->format("Y-m-d"),
|
||||
'his_time_start' => $startsDT->format("H:i"),
|
||||
'his_date_end' => $endsDT->format("Y-m-d"),
|
||||
'his_time_end' => $endsDT->format("H:i")
|
||||
));
|
||||
|
||||
$this->view->date_form = $form;
|
||||
}
|
||||
|
||||
public function getDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
|
||||
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
|
||||
public function getShowDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$show_id = $this->getRequest()->getParam("show_id", null);
|
||||
$data = Application_Model_ListenerStat::getShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT),$show_id);
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
public function getAllShowData(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$data = Application_Model_ListenerStat::getAllShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getAllShowDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$show_id = $this->getRequest()->getParam("show_id", null);
|
||||
$data = Application_Model_ListenerStat::getAllShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,16 @@ final class LocaleController extends Zend_Controller_Action
|
|||
//"Adding 1 Item" => _("Adding 1 Item"),
|
||||
//"Adding %s Items" => _("Adding %s Items"),
|
||||
//library/library.js
|
||||
"Add" => _("Add"),
|
||||
"New" => _("New"),
|
||||
"Edit" => _("Edit"),
|
||||
"Add to Schedule" => _("Add to Schedule"),
|
||||
"Add to next show" => _("Add to next show"),
|
||||
"Add to current show" => _("Add to current show"),
|
||||
"Add after selected items" => _("Add after selected items"),
|
||||
"Delete" => _("Delete"),
|
||||
"Publish" => _("Publish"),
|
||||
"Remove" => _("Remove"),
|
||||
"Edit Metadata" => _("Edit Metadata"),
|
||||
"Add to selected show" => _("Add to selected show"),
|
||||
"Select" => _("Select"),
|
||||
|
@ -108,6 +118,10 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"Are you sure you want to delete the selected item?" => _("Are you sure you want to delete the selected item?"),
|
||||
"Uploading in progress..." => _("Uploading in progress..."),
|
||||
"Retrieving data from the server..." => _("Retrieving data from the server..."),
|
||||
//library/podcast.js
|
||||
"Import" => _("Import"),
|
||||
"Imported?" => _("Imported?"),
|
||||
"View" => _("View"),
|
||||
// SOUNDCLOUD
|
||||
"Are you sure? SoundCloud stats and comments for this track will be permanently removed." => "Are you sure? SoundCloud stats and comments for this track will be permanently removed.",
|
||||
"Your track is being deleted from SoundCloud" => "Your track is being deleted from SoundCloud",
|
||||
|
@ -147,8 +161,8 @@ final class LocaleController extends Zend_Controller_Action
|
|||
=> _("A static smart block will save the criteria and generate the block content immediately. This allows you to edit and view it in the Library before adding it to a show."),
|
||||
"A dynamic smart block will only save the criteria. The block content will get generated upon adding it to a show. You will not be able to view and edit the content in the Library."
|
||||
=> _("A dynamic smart block will only save the criteria. The block content will get generated upon adding it to a show. You will not be able to view and edit the content in the Library."),
|
||||
"The desired block length will not be reached if Airtime cannot find enough unique tracks to match your criteria. Enable this option if you wish to allow tracks to be added multiple times to the smart block."
|
||||
=> _("The desired block length will not be reached if Airtime cannot find enough unique tracks to match your criteria. Enable this option if you wish to allow tracks to be added multiple times to the smart block."),
|
||||
"The desired block length will not be reached if %s cannot find enough unique tracks to match your criteria. Enable this option if you wish to allow tracks to be added multiple times to the smart block."
|
||||
=> _("The desired block length will not be reached if %s cannot find enough unique tracks to match your criteria. Enable this option if you wish to allow tracks to be added multiple times to the smart block."),
|
||||
"Smart block shuffled" => _("Smart block shuffled"),
|
||||
"Smart block generated and criteria saved" => _("Smart block generated and criteria saved"),
|
||||
"Smart block saved" => _("Smart block saved"),
|
||||
|
@ -179,9 +193,9 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"The stream is disabled" => _("The stream is disabled"),
|
||||
"Getting information from the server..." => _("Getting information from the server..."),
|
||||
"Can not connect to the streaming server" => _("Can not connect to the streaming server"),
|
||||
"If Airtime is behind a router or firewall, you may need to configure port forwarding and this field information will be incorrect. In this case you will need to manually update this field so it shows the correct host/port/mount that your DJ's need to connect to. The allowed range is between 1024 and 49151."
|
||||
=> _("If Airtime is behind a router or firewall, you may need to configure port forwarding and this field information will be incorrect. In this case you will need to manually update this field so it shows the correct host/port/mount that your DJ's need to connect to. The allowed range is between 1024 and 49151."),
|
||||
"For more details, please read the %sAirtime Manual%s" => _("For more details, please read the %sAirtime Manual%s"),
|
||||
"If %s is behind a router or firewall, you may need to configure port forwarding and this field information will be incorrect. In this case you will need to manually update this field so it shows the correct host/port/mount that your DJ's need to connect to. The allowed range is between 1024 and 49151."
|
||||
=> _("If %s is behind a router or firewall, you may need to configure port forwarding and this field information will be incorrect. In this case you will need to manually update this field so it shows the correct host/port/mount that your DJ's need to connect to. The allowed range is between 1024 and 49151."),
|
||||
"For more details, please read the %s%s Manual%s" => _("For more details, please read the %s%s Manual%s"),
|
||||
"Check this option to enable metadata for OGG streams (stream metadata is the track title, artist, and show name that is displayed in an audio player). VLC and mplayer have a serious bug when playing an OGG/VORBIS stream that has metadata information enabled: they will disconnect from the stream after every song. If you are using an OGG stream and your listeners do not require support for these audio players, then feel free to enable this option."
|
||||
=> _("Check this option to enable metadata for OGG streams (stream metadata is the track title, artist, and show name that is displayed in an audio player). VLC and mplayer have a serious bug when playing an OGG/VORBIS stream that has metadata information enabled: they will disconnect from the stream after every song. If you are using an OGG stream and your listeners do not require support for these audio players, then feel free to enable this option."),
|
||||
"Check this box to automatically switch off Master/Show source upon source disconnection." => _("Check this box to automatically switch off Master/Show source upon source disconnection."),
|
||||
|
@ -314,6 +328,7 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"Trim overbooked shows" => _("Trim overbooked shows"),
|
||||
"Remove selected scheduled items" => _("Remove selected scheduled items"),
|
||||
"Jump to the current playing track" => _("Jump to the current playing track"),
|
||||
"Jump to Current" => _("Jump to Current"),
|
||||
"Cancel current show" => _("Cancel current show"),
|
||||
//already in schedule/schedule.js
|
||||
//"Cancel Current Show?" => _("Cancel Current Show?"),
|
||||
|
@ -341,7 +356,7 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"Import media files" => _("Import media files"),
|
||||
"Create playlists, smart blocks, and webstreams" => _("Create playlists, smart blocks, and webstreams"),
|
||||
"Manage their own library content" => _("Manage their own library content"),
|
||||
"Progam Managers can do the following:" => _("Progam Managers can do the following:"),
|
||||
"Program Managers can do the following:" => _("Program Managers can do the following:"),
|
||||
"View and manage show content" => _("View and manage show content"),
|
||||
"Schedule shows" => _("Schedule shows"),
|
||||
"Manage all library content" => _("Manage all library content"),
|
||||
|
@ -355,6 +370,7 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"View listener stats" => _("View listener stats"),
|
||||
//dataTables/ColVis.js
|
||||
"Show / hide columns" => _("Show / hide columns"),
|
||||
"Columns" => _("Columns"),
|
||||
//datatables.columnFilter.js
|
||||
"From {from} to {to}" => _("From {from} to {to}"),
|
||||
"kbps" => _("kbps"),
|
||||
|
@ -415,24 +431,76 @@ final class LocaleController extends Zend_Controller_Action
|
|||
"New Show" => _("New Show"),
|
||||
"New Log Entry" => _("New Log Entry"),
|
||||
//Datatables:
|
||||
"No data available in table",
|
||||
"Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"Showing 0 to 0 of 0 entries",
|
||||
"(filtered from _MAX_ total entries)",
|
||||
"",
|
||||
",",
|
||||
"Show _MENU_",
|
||||
"Loading...",
|
||||
"Processing...",
|
||||
"No matching records found",
|
||||
"First",
|
||||
"Last",
|
||||
"Next",
|
||||
"Previous",
|
||||
"No data available in table" => _("No data available in table"),
|
||||
"(filtered from _MAX_ total entries)" => _("(filtered from _MAX_ total entries)"),
|
||||
": activate to sort column ascending",
|
||||
": activate to sort column descending",
|
||||
//End of datatables
|
||||
"Welcome to the new Airtime Pro!" => _("Welcome to the new Airtime Pro!"),
|
||||
|
||||
//New entries from .js "" => _(""),
|
||||
"First" => _("First"),
|
||||
"Last" => _("Last"),
|
||||
"Next" => _("Next"),
|
||||
"Previous" => _("Previous"),
|
||||
"Search:" => _("Search:"),
|
||||
"No matching records found" => _("No matching records found"),
|
||||
"Drag tracks here from the library" => _("Drag tracks here from the library"),
|
||||
"No tracks were played during the selected time period." => _("No tracks were played during the selected time period."),
|
||||
"Unpublish" => _("Unpublish"),
|
||||
"No matching results found." => _("No matching results found."),
|
||||
"Author" => _("Author"),
|
||||
"Description" => _("Description"),
|
||||
"Link" => _("Link"),
|
||||
"Publication Date" => _("Publication Date"),
|
||||
"Import Status" => _("Import Status"),
|
||||
"Actions" => _("Actions"),
|
||||
"Delete from Library" => _("Delete from Library"),
|
||||
"Successfully imported" => _("Successfully imported"),
|
||||
"No matching records found" => _("No matching records found"),
|
||||
"Show _MENU_" => _("Show _MENU_"),
|
||||
"Show _MENU_ entries" => _("Show _MENU_ entries"),
|
||||
"Showing _START_ to _END_ of _TOTAL_ entries" => _("Showing _START_ to _END_ of _TOTAL_ entries"),
|
||||
"Showing _START_ to _END_ of _TOTAL_ tracks" => _("Showing _START_ to _END_ of _TOTAL_ tracks"),
|
||||
"Showing _START_ to _END_ of _TOTAL_ track types" => _("Showing _START_ to _END_ of _TOTAL_ track types"),
|
||||
"Showing _START_ to _END_ of _TOTAL_ users" => _("Showing _START_ to _END_ of _TOTAL_ users"),
|
||||
"Showing 0 to 0 of 0 entries" => _("Showing 0 to 0 of 0 entries"),
|
||||
"Showing 0 to 0 of 0 tracks" => _("Showing 0 to 0 of 0 tracks"),
|
||||
"Showing 0 to 0 of 0 track types" => _("Showing 0 to 0 of 0 track types"),
|
||||
"(filtered from _MAX_ total track types)" => _("(filtered from _MAX_ total track types)"),
|
||||
//"This is used for tracks containing music." => _("This is used for tracks containing music."),
|
||||
"Are you sure you want to delete this tracktype?" => _("Are you sure you want to delete this tracktype?"),
|
||||
"No track types were found." => _("No track types were found."),
|
||||
"No track types found" => _("No track types found"),
|
||||
"No matching track types found" => _("No matching track types found"),
|
||||
"Enabled" => _("Enabled"),
|
||||
"Disabled" => _("Disabled"),
|
||||
"Cancel upload" => _("Cancel upload"),
|
||||
"Type" => _("Type"),
|
||||
"Autoloading playlists' contents are added to shows one hour before the show airs. <a target='_blank' href='http://libretime.org/manual/calendar/#autoloading-playlist'>More information</a>" => _("Autoloading playlists' contents are added to shows one hour before the show airs. <a target='_blank' href='http://libretime.org/manual/calendar/#autoloading-playlist'>More information</a>"),
|
||||
"Podcast settings saved" => _("Podcast settings saved"),
|
||||
"Are you sure you want to delete this user?" => _("Are you sure you want to delete this user?"),
|
||||
"Can't delete yourself!" => _("Can't delete yourself!"),
|
||||
"You haven't published any episodes!" => _("You haven't published any episodes!"),
|
||||
"You can publish your uploaded content from the 'Tracks' view." => _("You can publish your uploaded content from the 'Tracks' view."),
|
||||
"Try it now" => _("Try it now"),
|
||||
"<p>If this option is unchecked, the smartblock will schedule as many tracks as can be played out <strong>in their entirety</strong> within the specified duration. This will usually result in audio playback that is slightly less than the specified duration.</p><p>If this option is checked, the smartblock will also schedule one final track which will overflow the specified duration. This final track may be cut off mid-way if the show into which the smartblock is added finishes.</p>" => _("<p>If this option is unchecked, the smartblock will schedule as many tracks as can be played out <strong>in their entirety</strong> within the specified duration. This will usually result in audio playback that is slightly less than the specified duration.</p><p>If this option is checked, the smartblock will also schedule one final track which will overflow the specified duration. This final track may be cut off mid-way if the show into which the smartblock is added finishes.</p>"),
|
||||
"Playlist preview" => _("Playlist preview"),
|
||||
"Smart Block" => _("Smart Block"),
|
||||
"Webstream preview" => _("Webstream preview"),
|
||||
"You don't have permission to view the library." => _("You don't have permission to view the library."),
|
||||
"Now" => _("Now"),
|
||||
"Click 'New' to create one now." => _("Click 'New' to create one now."),
|
||||
"Click 'Upload' to add some now." => _("Click 'Upload' to add some now."),
|
||||
"Feed URL" => _("Feed URL"),
|
||||
"Import Date" => _("Import Date"),
|
||||
"Add New Podcast" => _("Add New Podcast"),
|
||||
"Cannot schedule outside a show.\nTry creating a show first." => _("Cannot schedule outside a show.\nTry creating a show first."),
|
||||
"No files have been uploaded yet." => _("No files have been uploaded yet."),
|
||||
//"Value is required and can't be empty" => _("Value is required and can't be empty"),
|
||||
//"mute" => _("mute"),
|
||||
//"max volume" => _("max volume"),
|
||||
|
||||
//embed player
|
||||
"On Air" => _("On Air"),
|
||||
"Off Air" => _("Off Air"),
|
||||
|
|
|
@ -58,11 +58,7 @@ class LoginController extends Zend_Controller_Action
|
|||
//Open the session for writing, because we close it for writing by default in Bootstrap.php as an optimization.
|
||||
//session_start();
|
||||
|
||||
// if the post contains recaptcha field, which means form had recaptcha field.
|
||||
// Hence add the element for validation.
|
||||
if (array_key_exists('recaptcha_response_field', $request->getPost())) {
|
||||
$form->addRecaptcha();
|
||||
}
|
||||
|
||||
if ($form->isValid($request->getPost())) {
|
||||
//get the username and password from the form
|
||||
$username = $form->getValue('username');
|
||||
|
@ -92,21 +88,6 @@ class LoginController extends Zend_Controller_Action
|
|||
Application_Model_Preference::SetUserLocale($locale);
|
||||
|
||||
$this->_redirect('showbuilder');
|
||||
} elseif (LIBRETIME_ENABLE_WHMCS) {
|
||||
$email = $form->getValue('username');
|
||||
$authAdapter = new WHMCS_Auth_Adapter("admin", $email, $password);
|
||||
$auth = Zend_Auth::getInstance();
|
||||
$result = $auth->authenticate($authAdapter);
|
||||
if ($result->isValid()) {
|
||||
Zend_Session::regenerateId();
|
||||
//set the user locale in case user changed it in when logging in
|
||||
Application_Model_Preference::SetUserLocale($locale);
|
||||
|
||||
$this->_redirect('showbuilder');
|
||||
}
|
||||
else {
|
||||
$form = $this->loginError($username);
|
||||
}
|
||||
} else {
|
||||
$form = $this->loginError($username);
|
||||
}
|
||||
|
@ -179,18 +160,7 @@ class LoginController extends Zend_Controller_Action
|
|||
$form->email->addError($this->view->translate(_("Email could not be sent. Check your mail server settings and ensure it has been configured properly.")));
|
||||
}
|
||||
} else {
|
||||
if (!LIBRETIME_ENABLE_WHMCS) {
|
||||
$form->email->addError($this->view->translate(_("That username or email address could not be found.")));
|
||||
} else {
|
||||
$form->email->addError(
|
||||
$this->view->translate(
|
||||
sprintf(
|
||||
_pro("That username or email address could not be found. If you are the station owner, you should <a href=\"%s\">reset your here</a>."),
|
||||
WHMCS_PASSWORD_RESET_URL
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$form->email->addError($this->view->translate(_("That username or email address could not be found.")));
|
||||
}
|
||||
} else { //Form is not valid
|
||||
$form->email->addError($this->view->translate(_("There was a problem with the username or email address you entered.")));
|
||||
|
@ -276,10 +246,6 @@ class LoginController extends Zend_Controller_Action
|
|||
Application_Model_LoginAttempts::increaseAttempts($_SERVER['REMOTE_ADDR']);
|
||||
$form = new Application_Form_Login();
|
||||
$this->view->error = true;
|
||||
//Only show the captcha if you get your login wrong 4 times in a row.
|
||||
if (Application_Model_Subjects::getLoginAttempts($username) > 3) {
|
||||
$form->addRecaptcha();
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
|
||||
$this->view->obj = $obj;
|
||||
$this->view->contents = $obj->getContents();
|
||||
if ($formIsValid) {
|
||||
if ($formIsValid && $obj instanceof Application_Model_Block) {
|
||||
$this->view->poolCount = $obj->getListofFilesMeetCriteria()['count'];
|
||||
}
|
||||
$this->view->showPoolCount = true;
|
||||
|
|
|
@ -27,15 +27,10 @@ class PodcastController extends Zend_Controller_Action {
|
|||
*/
|
||||
public function stationAction() {
|
||||
|
||||
if (LIBRETIME_ENABLE_BILLING === true && !Billing::isStationPodcastAllowed()) {
|
||||
$this->render("featureupgrade-page");
|
||||
return;
|
||||
}
|
||||
|
||||
$stationPodcastId = Application_Model_Preference::getStationPodcastId();
|
||||
$podcast = Application_Service_PodcastService::getPodcastById($stationPodcastId);
|
||||
$this->view->podcast = json_encode($podcast);
|
||||
$this->view->form = new Application_Form_StationPodcast();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class PreferenceController extends Zend_Controller_Action
|
|||
$request = $this->getRequest();
|
||||
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Settings');
|
||||
|
||||
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/preferences.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
@ -42,11 +42,14 @@ class PreferenceController extends Zend_Controller_Action
|
|||
{
|
||||
Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view);
|
||||
Application_Model_Preference::SetStationDescription($values["stationDescription"]);
|
||||
Application_Model_Preference::SetTrackTypeDefault($values["tracktypeDefault"]);
|
||||
Application_Model_Preference::SetDefaultCrossfadeDuration($values["stationDefaultCrossfadeDuration"]);
|
||||
Application_Model_Preference::SetDefaultFadeIn($values["stationDefaultFadeIn"]);
|
||||
Application_Model_Preference::SetDefaultFadeOut($values["stationDefaultFadeOut"]);
|
||||
Application_Model_Preference::SetPodcastAlbumOverride($values["podcastAlbumOverride"]);
|
||||
Application_Model_Preference::SetPodcastAutoSmartblock($values["podcastAutoSmartblock"]);
|
||||
Application_Model_Preference::SetIntroPlaylist($values["introPlaylistSelect"]);
|
||||
Application_Model_Preference::SetOutroPlaylist($values["outroPlaylistSelect"]);
|
||||
Application_Model_Preference::SetAllow3rdPartyApi($values["thirdPartyApi"]);
|
||||
Application_Model_Preference::SetAllowedCorsUrls($values["allowedCorsUrls"]);
|
||||
Application_Model_Preference::SetDefaultLocale($values["locale"]);
|
||||
|
@ -69,7 +72,7 @@ class PreferenceController extends Zend_Controller_Action
|
|||
Application_Model_Preference::setTuneinPartnerId($values["tunein_partner_id"]);
|
||||
|
||||
// SoundCloud Preferences
|
||||
if (Billing::isStationPodcastAllowed() && array_key_exists('SoundCloudLicense', $values)) {
|
||||
if (array_key_exists('SoundCloudLicense', $values)) {
|
||||
Application_Model_Preference::setDefaultSoundCloudLicenseType($values["SoundCloudLicense"]);
|
||||
Application_Model_Preference::setDefaultSoundCloudSharingType($values["SoundCloudSharing"]);
|
||||
}
|
||||
|
@ -110,47 +113,6 @@ class PreferenceController extends Zend_Controller_Action
|
|||
$this->_helper->json->sendJson(array("url" => $url));
|
||||
}
|
||||
|
||||
public function supportSettingAction()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/support-setting.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->statusMsg = "";
|
||||
|
||||
SessionHelper::reopenSessionForWriting();
|
||||
|
||||
$form = new Application_Form_SupportSettings();
|
||||
if ($request->isPost()) {
|
||||
$values = $request->getPost();
|
||||
if ($form->isValid($values)) {
|
||||
Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view);
|
||||
Application_Model_Preference::SetPhone($values["Phone"]);
|
||||
Application_Model_Preference::SetEmail($values["Email"]);
|
||||
Application_Model_Preference::SetStationWebSite($values["StationWebSite"]);
|
||||
|
||||
Application_Model_Preference::SetStationCountry($values["Country"]);
|
||||
Application_Model_Preference::SetStationCity($values["City"]);
|
||||
Application_Model_Preference::SetStationDescription($values["Description"]);
|
||||
if (isset($values["Privacy"])) {
|
||||
Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
|
||||
}
|
||||
}
|
||||
$this->view->statusMsg = "<div class='success'>"._("Support setting updated.")."</div>";
|
||||
}
|
||||
|
||||
$privacyChecked = false;
|
||||
if (Application_Model_Preference::GetPrivacyPolicyCheck() == 1) {
|
||||
$privacyChecked = true;
|
||||
}
|
||||
$this->view->privacyChecked = $privacyChecked;
|
||||
$this->view->section_title = _('Support Feedback');
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
public function directoryConfigAction()
|
||||
{
|
||||
}
|
||||
|
@ -541,7 +503,7 @@ class PreferenceController extends Zend_Controller_Action
|
|||
{
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
|
||||
if (!SecurityHelper::verifyCSRFToken($this->_getParam('csrf_token'))) {
|
||||
Logging::error(__FILE__ . ': Invalid CSRF token');
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0", "valid" => false, "error" => "CSRF token did not match."));
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Aws\S3\S3Client;
|
||||
|
||||
class ProvisioningController extends Zend_Controller_Action
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The "create action" is in ProvisioningHelper because it needs to have no dependency on Zend,
|
||||
* since when we bootstrap Zend, we already need the database set up and working (Bootstrap.php is a mess).
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Endpoint to change Airtime preferences remotely.
|
||||
* Mainly for use with the dashboard right now.
|
||||
*/
|
||||
public function changeAction() {
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
if (!RestAuth::verifyAuth(true, false, $this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// This is hacky and should be genericized
|
||||
if (isset($_POST['station_name'])) {
|
||||
Application_Model_Preference::SetStationName($_POST['station_name']);
|
||||
}
|
||||
if (isset($_POST['description'])) {
|
||||
Application_Model_Preference::SetStationDescription($_POST['description']);
|
||||
}
|
||||
if (isset($_POST['provisioning_status'])) {
|
||||
Application_Model_Preference::setProvisioningStatus($_POST['provisioning_status']);
|
||||
}
|
||||
if (isset($_POST['icecast_pass'])) {
|
||||
Application_Model_Preference::setDefaultIcecastPassword($_POST['icecast_pass']);
|
||||
}
|
||||
if (isset($_POST['bandwidth_limit'])) {
|
||||
Application_Model_Preference::setBandwidthLimit($_POST['bandwidth_limit']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(400)
|
||||
->appendBody("ERROR: " . $e->getMessage());
|
||||
Logging::error($e->getMessage());
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody("OK");
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the Airtime Pro station's files from Amazon S3
|
||||
*
|
||||
* FIXME: When we deploy this next time, we should ensure that
|
||||
* this function can only be accessed with POST requests!
|
||||
*/
|
||||
public function terminateAction()
|
||||
{
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
if (!RestAuth::verifyAuth(true, false, $this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
foreach ($CC_CONFIG["supportedStorageBackends"] as $storageBackend) {
|
||||
$proxyStorageBackend = new ProxyStorageBackend($storageBackend);
|
||||
$proxyStorageBackend->deleteAllCloudFileObjects();
|
||||
}
|
||||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody("OK");
|
||||
}
|
||||
|
||||
}
|
|
@ -122,7 +122,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$currentUser = $service_user->getCurrentUser();
|
||||
|
||||
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
|
||||
|
||||
$start = new DateTime($this->_getParam('start', null), $userTimezone);
|
||||
$start->setTimezone(new DateTimeZone("UTC"));
|
||||
$end = new DateTime($this->_getParam('end', null), $userTimezone);
|
||||
|
@ -187,7 +187,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$this->view->show_error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$error = $service_calendar->moveShow($deltaDay, $deltaMin);
|
||||
if (isset($error)) {
|
||||
$this->view->error = $error;
|
||||
|
@ -209,7 +209,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$log_vars["params"]["delta day"] = $deltaDay;
|
||||
$log_vars["params"]["delta minute"] = $deltaMin;
|
||||
Logging::info($log_vars);
|
||||
|
||||
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
|
||||
|
@ -239,7 +239,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$log_vars["params"] = array();
|
||||
$log_vars["params"]["instance id"] = $instanceId;
|
||||
Logging::info($log_vars);
|
||||
|
||||
|
||||
$service_show = new Application_Service_ShowService();
|
||||
$showId = $service_show->deleteShow($instanceId, true);
|
||||
|
||||
|
@ -261,7 +261,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
public function clearShowAction()
|
||||
{
|
||||
$instanceId = $this->_getParam('id');
|
||||
|
||||
|
||||
$log_vars = array();
|
||||
$log_vars["url"] = $_SERVER['HTTP_HOST'];
|
||||
$log_vars["action"] = "schedule/clear-show";
|
||||
|
@ -296,12 +296,16 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
/* Convert all UTC times to localtime before sending back to user. */
|
||||
$range["schedulerTime"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["schedulerTime"]);
|
||||
|
||||
|
||||
if (isset($range["previous"])) {
|
||||
$range["previous"]["starts"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["previous"]["starts"]);
|
||||
$range["previous"]["ends"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["previous"]["ends"]);
|
||||
}
|
||||
if (isset($range["current"])) {
|
||||
if (isset($range["current"]["metadata"])) {
|
||||
$get_artwork = FileDataHelper::getArtworkData($range["current"]["metadata"]["artwork"], 256);
|
||||
$range["current"]["metadata"]["artwork_data"] = $get_artwork;
|
||||
}
|
||||
$range["current"]["starts"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["current"]["starts"]);
|
||||
$range["current"]["ends"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["current"]["ends"]);
|
||||
}
|
||||
|
@ -309,14 +313,14 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$range["next"]["starts"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["next"]["starts"]);
|
||||
$range["next"]["ends"] = Application_Common_DateHelper::UTCStringToUserTimezoneString($range["next"]["ends"]);
|
||||
}
|
||||
|
||||
|
||||
Application_Common_DateHelper::convertTimestamps(
|
||||
$range["currentShow"],
|
||||
$range["currentShow"],
|
||||
array("starts", "ends", "start_timestamp", "end_timestamp"),
|
||||
"user"
|
||||
);
|
||||
Application_Common_DateHelper::convertTimestamps(
|
||||
$range["nextShow"],
|
||||
$range["nextShow"],
|
||||
array("starts", "ends", "start_timestamp", "end_timestamp"),
|
||||
"user"
|
||||
);
|
||||
|
@ -324,7 +328,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
//TODO: Add timezone and timezoneOffset back into the ApiController's results.
|
||||
$range["timezone"] = Application_Common_DateHelper::getUserTimezoneAbbreviation();
|
||||
$range["timezoneOffset"] = Application_Common_DateHelper::getUserTimezoneOffset();
|
||||
|
||||
|
||||
$source_status = array();
|
||||
$switch_status = array();
|
||||
$live_dj = Application_Model_Preference::GetSourceStatus("live_dj");
|
||||
|
@ -358,7 +362,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$originalShowId = $show->isRebroadcast();
|
||||
if (!is_null($originalShowId)) {
|
||||
try {
|
||||
|
@ -375,7 +379,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$displayTimeZone = new DateTimeZone(Application_Model_Preference::GetTimezone());
|
||||
$originalDateTime = new DateTime($originalShowStart, new DateTimeZone("UTC"));
|
||||
$originalDateTime->setTimezone($displayTimeZone);
|
||||
|
||||
|
||||
$this->view->additionalShowInfo =
|
||||
sprintf(_("Rebroadcast of show %s from %s at %s"),
|
||||
$originalShowName,
|
||||
|
@ -461,7 +465,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$log_vars["params"] = array();
|
||||
$log_vars["params"]["form_data"] = $data;
|
||||
Logging::info($log_vars);
|
||||
|
||||
|
||||
$service_showForm = new Application_Service_ShowFormService(
|
||||
$data["add_show_id"], $data["add_show_instance_id"]);
|
||||
$service_show = new Application_Service_ShowService(null, $data);
|
||||
|
@ -513,7 +517,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
if ($data['add_show_day_check'] == "") {
|
||||
$data['add_show_day_check'] = null;
|
||||
}
|
||||
|
||||
|
||||
$log_vars = array();
|
||||
$log_vars["url"] = $_SERVER['HTTP_HOST'];
|
||||
$log_vars["action"] = "schedule/edit-show";
|
||||
|
@ -525,12 +529,12 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
list($data, $validateStartDate, $validateStartTime, $originalShowStartDateTime) =
|
||||
$service_showForm->preEditShowValidationCheck($data);
|
||||
|
||||
|
||||
if ($service_showForm->validateShowForms($forms, $data, $validateStartDate,
|
||||
$originalShowStartDateTime, true, $data["add_show_instance_id"])) {
|
||||
// Get the show ID from the show service to pass as a parameter to the RESTful ShowImageController
|
||||
$this->view->showId = $service_show->addUpdateShow($data);
|
||||
|
||||
|
||||
$this->view->addNewShow = true;
|
||||
$this->view->newForm = $this->view->render('schedule/add-show-form.phtml');
|
||||
} else {
|
||||
|
@ -541,7 +545,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$this->view->when->getElement('add_show_start_time')->setOptions(array('disabled' => true));
|
||||
}
|
||||
//$this->view->rr->getElement('add_show_record')->setOptions(array('disabled' => true));
|
||||
|
||||
|
||||
$this->view->addNewShow = false;
|
||||
$this->view->action = "edit-show";
|
||||
$this->view->form = $this->view->render('schedule/add-show-form.phtml');
|
||||
|
@ -551,7 +555,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
public function addShowAction()
|
||||
{
|
||||
$service_showForm = new Application_Service_ShowFormService(null);
|
||||
|
||||
|
||||
$js = $this->_getParam('data');
|
||||
$data = array();
|
||||
|
||||
|
@ -565,20 +569,20 @@ class ScheduleController extends Zend_Controller_Action
|
|||
// TODO: move this to js
|
||||
$data['add_show_hosts'] = $this->_getParam('hosts');
|
||||
$data['add_show_day_check'] = $this->_getParam('days');
|
||||
|
||||
|
||||
if ($data['add_show_day_check'] == "") {
|
||||
$data['add_show_day_check'] = null;
|
||||
}
|
||||
|
||||
|
||||
$log_vars = array();
|
||||
$log_vars["url"] = $_SERVER['HTTP_HOST'];
|
||||
$log_vars["action"] = "schedule/add-show";
|
||||
$log_vars["params"] = array();
|
||||
$log_vars["params"]["form_data"] = $data;
|
||||
Logging::info($log_vars);
|
||||
|
||||
|
||||
$forms = $this->createShowFormAction();
|
||||
|
||||
|
||||
$this->view->addNewShow = true;
|
||||
|
||||
if ($data['add_show_start_now'] == "now") {
|
||||
|
@ -597,18 +601,18 @@ class ScheduleController extends Zend_Controller_Action
|
|||
if ($service_showForm->validateShowForms($forms, $data)) {
|
||||
// Get the show ID from the show service to pass as a parameter to the RESTful ShowImageController
|
||||
$this->view->showId = $service_show->addUpdateShow($data);
|
||||
|
||||
|
||||
//send new show forms to the user
|
||||
$this->createShowFormAction(true);
|
||||
$this->view->newForm = $this->view->render('schedule/add-show-form.phtml');
|
||||
|
||||
|
||||
Logging::debug("Show creation succeeded");
|
||||
} else {
|
||||
$this->view->form = $this->view->render('schedule/add-show-form.phtml');
|
||||
Logging::debug("Show creation failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function createShowFormAction($populateDefaults=false)
|
||||
{
|
||||
$service_showForm = new Application_Service_ShowFormService();
|
||||
|
@ -638,7 +642,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
public function deleteShowAction()
|
||||
{
|
||||
$instanceId = $this->_getParam('id');
|
||||
|
||||
|
||||
$log_vars = array();
|
||||
$log_vars["url"] = $_SERVER['HTTP_HOST'];
|
||||
$log_vars["action"] = "schedule/delete-show";
|
||||
|
@ -648,7 +652,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
$service_show = new Application_Service_ShowService();
|
||||
$showId = $service_show->deleteShow($instanceId);
|
||||
|
||||
|
||||
if (!$showId) {
|
||||
$this->view->show_error = true;
|
||||
}
|
||||
|
@ -663,7 +667,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$log_vars["params"] = array();
|
||||
$log_vars["params"]["instance id"] = $this->_getParam('id');
|
||||
Logging::info($log_vars);
|
||||
|
||||
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
|
||||
if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
|
||||
|
@ -730,7 +734,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
$start = $this->_getParam('startTime');
|
||||
$end = $this->_getParam('endTime');
|
||||
$timezone = $this->_getParam('timezone');
|
||||
|
||||
|
||||
$service_showForm = new Application_Service_ShowFormService();
|
||||
$result = $service_showForm->calculateDuration($start, $end, $timezone);
|
||||
|
||||
|
@ -741,10 +745,10 @@ class ScheduleController extends Zend_Controller_Action
|
|||
public function updateFutureIsScheduledAction()
|
||||
{
|
||||
$schedId = $this->_getParam('schedId');
|
||||
|
||||
|
||||
$scheduleService = new Application_Service_SchedulerService();
|
||||
$redrawLibTable = $scheduleService->updateFutureIsScheduled($schedId, false);
|
||||
|
||||
|
||||
$this->_helper->json->sendJson(array("redrawLibTable" => $redrawLibTable));
|
||||
}
|
||||
|
||||
|
@ -762,5 +766,5 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
$this->_helper->json->sendJson($localTime);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
//$this->_helper->layout->setLayout("showbuilder");
|
||||
|
||||
$this->view->headScript()->appendScript("localStorage.setItem( 'user-type', '$userType' );");
|
||||
$this->view->headScript()->appendScript(Application_Common_GoogleAnalytics::generateGoogleTagManagerDataLayerJavaScript());
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl . 'css/redmond/jquery-ui-1.8.8.custom.css?' . $CC_CONFIG['airtime_version']);
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ThankYouController extends Zend_Controller_Action
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
//Variable for the template (thank-you/index.phtml)
|
||||
$this->view->stationUrl = Application_Common_HTTPHelper::getStationUrl();
|
||||
$this->view->conversionUrl = Application_Common_HTTPHelper::getStationUrl() . 'thank-you/confirm-conversion';
|
||||
$this->view->gaEventTrackingJsCode = ""; //Google Analytics event tracking code that logs an event.
|
||||
|
||||
// Embed the Google Analytics conversion tracking code if the
|
||||
// user is a super admin and old plan level is set to trial.
|
||||
if (Application_Common_GoogleAnalytics::didPaidConversionOccur($this->getRequest())) {
|
||||
$this->view->gaEventTrackingJsCode = Application_Common_GoogleAnalytics::generateConversionTrackingJavaScript();
|
||||
}
|
||||
|
||||
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||
$csrf_element = new Zend_Form_Element_Hidden('csrf');
|
||||
$csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label');
|
||||
$csrf_form = new Zend_Form();
|
||||
$csrf_form->addElement($csrf_element);
|
||||
$this->view->form = $csrf_form;
|
||||
}
|
||||
|
||||
/** Confirm that a conversion was tracked. */
|
||||
public function confirmConversionAction()
|
||||
{
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$current_namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||
$observed_csrf_token = $this->_getParam('csrf_token');
|
||||
$expected_csrf_token = $current_namespace->authtoken;
|
||||
|
||||
if($observed_csrf_token != $expected_csrf_token) {
|
||||
Logging::info("Invalid CSRF token");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getRequest()->isPost()) {
|
||||
Logging::info("Goal conversion from trial to paid.");
|
||||
// Clear old plan level so we prevent duplicate events.
|
||||
// This should only be called from AJAX. See thank-you/index.phtml
|
||||
Application_Model_Preference::ClearOldPlanLevel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
class TracktypeController extends Zend_Controller_Action
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$ajaxContext = $this->_helper->getHelper('AjaxContext');
|
||||
$ajaxContext->addActionContext('get-tracktype-data-table-info', 'json')
|
||||
->addActionContext('get-tracktype-data', 'json')
|
||||
->addActionContext('remove-tracktype', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
||||
public function addTracktypeAction()
|
||||
{
|
||||
// Start the session to re-open write permission to the session so we can
|
||||
// create the namespace for our csrf token verification
|
||||
SessionHelper::reopenSessionForWriting();
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Settings');
|
||||
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
||||
$js_files = array(
|
||||
'js/datatables/js/jquery.dataTables.js?',
|
||||
'js/datatables/plugin/dataTables.pluginAPI.js?',
|
||||
'js/airtime/tracktype/tracktype.js?'
|
||||
);
|
||||
|
||||
foreach ($js_files as $js) {
|
||||
$this->view->headScript()->appendFile(
|
||||
$baseUrl.$js.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
}
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/tracktypes.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$form = new Application_Form_AddTracktype();
|
||||
|
||||
$this->view->successMessage = "";
|
||||
|
||||
if ($request->isPost()) {
|
||||
$params = $request->getPost();
|
||||
$postData = explode('&', $params['data']);
|
||||
$formData = array();
|
||||
foreach($postData as $k=>$v) {
|
||||
$v = explode('=', $v);
|
||||
$formData[$v[0]] = urldecode($v[1]);
|
||||
}
|
||||
|
||||
if ($form->validateCode($formData)) {
|
||||
$tracktype = new Application_Model_Tracktype($formData['tracktype_id']);
|
||||
if (empty($formData['tracktype_id'])) {
|
||||
$tracktype->setCode($formData['code']);
|
||||
}
|
||||
$tracktype->setTypeName($formData['type_name']);
|
||||
$tracktype->setDescription($formData['description']);
|
||||
$tracktype->setVisibility($formData['visibility']);
|
||||
$tracktype->save();
|
||||
|
||||
$form->reset();
|
||||
$this->view->form = $form;
|
||||
|
||||
if (strlen($formData['tracktype_id']) == 0) {
|
||||
$this->view->successMessage = "<div class='success'>"._("Track Type added successfully!")."</div>";
|
||||
} else {
|
||||
$this->view->successMessage = "<div class='success'>"._("Track Type updated successfully!")."</div>";
|
||||
}
|
||||
|
||||
$this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('tracktype/add-tracktype.phtml')));
|
||||
} else {
|
||||
$this->view->form = $form;
|
||||
$this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('tracktype/add-tracktype.phtml')));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
public function getTracktypeDataTableInfoAction()
|
||||
{
|
||||
$post = $this->getRequest()->getPost();
|
||||
$tracktypes = Application_Model_Tracktype::getTracktypesDataTablesInfo($post);
|
||||
|
||||
$this->_helper->json->sendJson($tracktypes);
|
||||
}
|
||||
|
||||
public function getTracktypeDataAction()
|
||||
{
|
||||
$id = $this->_getParam('id');
|
||||
$this->view->entries = Application_Model_Tracktype::GetTracktypeData($id);
|
||||
}
|
||||
|
||||
public function removeTracktypeAction()
|
||||
{
|
||||
// action body
|
||||
$delId = $this->_getParam('id');
|
||||
|
||||
$tracktype = new Application_Model_Tracktype($delId);
|
||||
|
||||
# Delete the track type
|
||||
$this->view->entries = $tracktype->delete();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,262 +0,0 @@
|
|||
<?php
|
||||
|
||||
class WhmcsLoginController extends Zend_Controller_Action
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$request = $this->getRequest();
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$username = "admin"; //This is just for appearance in your session. It shows up in the corner of the Airtime UI.
|
||||
$email = $_POST["email"];
|
||||
$password = $_POST["password"];
|
||||
|
||||
Application_Model_Locale::configureLocalization($request->getcookie('airtime_locale', 'en_CA'));
|
||||
if (Zend_Auth::getInstance()->hasIdentity())
|
||||
{
|
||||
$this->_redirect('showbuilder');
|
||||
}
|
||||
|
||||
$authAdapter = new WHMCS_Auth_Adapter($username, $email, $password);
|
||||
|
||||
$auth = Zend_Auth::getInstance();
|
||||
$result = $auth->authenticate($authAdapter);
|
||||
if ($result->isValid()) {
|
||||
//all info about this user from the login table omit only the password
|
||||
//$userInfo = $authAdapter->getResultRowObject(null, 'password');
|
||||
|
||||
//the default storage is a session with namespace Zend_Auth
|
||||
/*
|
||||
[id] => 1
|
||||
[login] => admin
|
||||
[pass] => hashed password
|
||||
[type] => A
|
||||
[first_name] =>
|
||||
[last_name] =>
|
||||
[lastlogin] =>
|
||||
[lastfail] =>
|
||||
[skype_contact] =>
|
||||
[jabber_contact] =>
|
||||
[email] => asdfasdf@asdasdf.com
|
||||
[cell_phone] =>
|
||||
[login_attempts] => 0
|
||||
*/
|
||||
|
||||
//Zend_Auth already does this for us, it's not needed:
|
||||
//$authStorage = $auth->getStorage();
|
||||
//$authStorage->write($result->getIdentity()); //$userInfo);
|
||||
|
||||
//set the user locale in case user changed it in when logging in
|
||||
//$locale = $form->getValue('locale');
|
||||
//Application_Model_Preference::SetUserLocale($locale);
|
||||
|
||||
$this->_redirect('showbuilder');
|
||||
}
|
||||
else {
|
||||
echo("Sorry, that username or password was incorrect.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface {
|
||||
private $username;
|
||||
private $password;
|
||||
private $email;
|
||||
|
||||
function __construct($username, $email, $password) {
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->email = $email;
|
||||
$this->identity = null;
|
||||
}
|
||||
|
||||
function authenticate() {
|
||||
list($credentialsValid, $clientId) = $this->validateCredentialsWithWHMCS($this->email, $this->password);
|
||||
if (!$credentialsValid)
|
||||
{
|
||||
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
|
||||
}
|
||||
if (!$this->verifyClientSubdomainOwnership($clientId))
|
||||
{
|
||||
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
|
||||
}
|
||||
|
||||
$identity = array();
|
||||
|
||||
//TODO: Get identity of the first admin user!
|
||||
|
||||
/*
|
||||
$identity["id"] = 1;
|
||||
$identity["type"] = "S";
|
||||
$identity["login"] = $this->username; //admin";
|
||||
$identity["email"] = $this->email;*/
|
||||
$identity = $this->getSuperAdminIdentity();
|
||||
if (is_null($identity)) {
|
||||
Logging::error("No super admin user found");
|
||||
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
|
||||
}
|
||||
$identity = (object)$identity; //Convert the array into an stdClass object
|
||||
|
||||
try {
|
||||
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity);
|
||||
} catch (Exception $e) {
|
||||
// exception occured
|
||||
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
|
||||
}
|
||||
}
|
||||
|
||||
private function getSuperAdminIdentity()
|
||||
{
|
||||
$firstSuperAdminUser = CcSubjsQuery::create()
|
||||
->filterByDbType('S')
|
||||
->orderByDbId()
|
||||
->findOne();
|
||||
if (!$firstSuperAdminUser) {
|
||||
//If there's no super admin users, get the first regular admin user!
|
||||
$firstSuperAdminUser = CcSubjsQuery::create()
|
||||
->filterByDbType('A')
|
||||
->orderByDbId()
|
||||
->findOne();
|
||||
if (!$firstSuperAdminUser) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
$identity["id"] = $firstSuperAdminUser->getDbId();
|
||||
$identity["type"] = "S"; //Super Admin
|
||||
$identity["login"] = $firstSuperAdminUser->getDbLogin();
|
||||
$identity["email"] = $this->email;
|
||||
return $identity;
|
||||
}
|
||||
|
||||
//Returns an array! Read the code carefully:
|
||||
private function validateCredentialsWithWHMCS($email, $password)
|
||||
{
|
||||
$client_postfields = array();
|
||||
$client_postfields["username"] = $_SERVER['WHMCS_USERNAME']; //WHMCS API username
|
||||
$client_postfields["password"] = md5($_SERVER['WHMCS_PASSWORD']); //WHMCS API password
|
||||
$client_postfields["action"] ="validatelogin";
|
||||
$client_postfields["responsetype"] = "json";
|
||||
|
||||
$client_postfields["email"] = $email;
|
||||
$client_postfields["password2"] = $password;
|
||||
|
||||
$query_string = "";
|
||||
foreach ($client_postfields as $k => $v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, WHMCS_API_URL);
|
||||
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); // WHMCS IP whitelist doesn't support IPv6
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
$jsondata = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach WHMCS server in " . __FUNCTION__ . ": "
|
||||
. curl_errno($ch) . ' - ' . curl_error($ch) . ' - ' . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
//die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$arr = json_decode($jsondata, true); # Decode JSON String
|
||||
|
||||
if ($arr["result"] != "success") {
|
||||
return array(false, -1);
|
||||
}
|
||||
$clientId = $arr["userid"];
|
||||
|
||||
return array(true, $clientId);
|
||||
}
|
||||
|
||||
function verifyClientSubdomainOwnership($clientId)
|
||||
{
|
||||
//Do a quick safety check to ensure the client ID we're authenticating
|
||||
//matches up to the owner of this instance.
|
||||
if ($clientId != Application_Model_Preference::GetClientId())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$client_postfields = array();
|
||||
$client_postfields["username"] = $_SERVER['WHMCS_USERNAME'];
|
||||
$client_postfields["password"] = md5($_SERVER['WHMCS_PASSWORD']);
|
||||
$client_postfields["action"] ="getclientsproducts";
|
||||
$client_postfields["responsetype"] = "json";
|
||||
|
||||
$client_postfields["clientid"] = $clientId;
|
||||
//$client_postfields["stats"] = "true";
|
||||
|
||||
$query_string = "";
|
||||
foreach ($client_postfields as $k => $v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, WHMCS_API_URL);
|
||||
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); // WHMCS IP whitelist doesn't support IPv6
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
$jsondata = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach WHMCS server in " . __FUNCTION__ . ": "
|
||||
. curl_errno($ch) . ' - ' . curl_error($ch) . ' - ' . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
//die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$arr = json_decode($jsondata, true); # Decode JSON String
|
||||
//$client_id = $arr["clientid"];
|
||||
//print_r($arr);
|
||||
if ($arr["result"] != "success") {
|
||||
die("Sorry, that email address or password was incorrect.");
|
||||
}
|
||||
|
||||
$doesAirtimeProductExist = false;
|
||||
$isAirtimeAccountSuspended = true;
|
||||
$airtimeProduct = null;
|
||||
|
||||
foreach ($arr["products"]["product"] as $product)
|
||||
{
|
||||
if (strpos($product["groupname"], "Airtime") === FALSE)
|
||||
{
|
||||
//Ignore non-Airtime products
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($product["status"] === "Active") || ($product["status"] === "Suspended")) {
|
||||
$airtimeProduct = $product;
|
||||
$subdomain = '';
|
||||
|
||||
foreach ($airtimeProduct['customfields']['customfield'] as $customField)
|
||||
{
|
||||
if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME)
|
||||
{
|
||||
$subdomain = $customField['value'];
|
||||
if (($subdomain . ".airtime.pro") === $_SERVER['SERVER_NAME'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE podcast_episodes DROP COLUMN IF EXISTS episode_title;
|
||||
ALTER TABLE podcast_episodes DROP COLUMN IF EXISTS episode_description;
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_blockcriteria DROP COLUMN IF EXISTS criteriagroup;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE podcast_episodes ALTER COLUMN episode_description TYPE VARCHAR(4096);
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_block ALTER COLUMN type SET DEFAULT 'static';
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_files DROP COLUMN IF EXISTS artwork;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE cc_files DROP COLUMN IF EXISTS track_type;
|
||||
|
||||
DROP TABLE IF EXISTS "cc_track_types" CASCADE;
|
|
@ -118,8 +118,6 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
|
|||
"error",
|
||||
"locale",
|
||||
"upgrade",
|
||||
'whmcs-login',
|
||||
"provisioning",
|
||||
"embed",
|
||||
"feeds"
|
||||
)))
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Zend_Controller_Plugin_ConversionTracking extends Zend_Controller_Plugin_Abstract
|
||||
{
|
||||
public function preDispatch(Zend_Controller_Request_Abstract $request)
|
||||
{
|
||||
if (!Zend_Session::isStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//If user is a super admin and old plan level is set to trial....
|
||||
if (Application_Common_GoogleAnalytics::didPaidConversionOccur($request))
|
||||
{
|
||||
//Redirect to Thank you page, unless the request was already going there...
|
||||
if ($request->getControllerName() != 'thank-you')
|
||||
{
|
||||
$request->setModuleName('default')
|
||||
->setControllerName('thank-you')
|
||||
->setActionName('index')
|
||||
->setDispatched(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -33,8 +33,6 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
|||
"auth",
|
||||
"error",
|
||||
"upgrade",
|
||||
'whmcs-login',
|
||||
"provisioning",
|
||||
"embed",
|
||||
"feeds"
|
||||
))
|
||||
|
@ -93,7 +91,7 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
|||
$userType = "";
|
||||
}
|
||||
$view->headScript()->appendScript("var userType = '$userType';");
|
||||
|
||||
|
||||
// Dropzone also accept file extensions and doesn't correctly extract certain mimetypes (eg. FLAC - try it),
|
||||
// so we append the file extensions to the list of mimetypes and that makes it work.
|
||||
$mimeTypes = FileDataHelper::getAudioMimeTypeArray();
|
||||
|
@ -141,6 +139,16 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
|||
$view->headScript()->appendScript("var PRODUCT_NAME = '" . PRODUCT_NAME . "';");
|
||||
$view->headScript()->appendScript("var USER_MANUAL_URL = '" . USER_MANUAL_URL . "';");
|
||||
$view->headScript()->appendScript("var COMPANY_NAME = '" . COMPANY_NAME . "';");
|
||||
//Each page refresh or tab open has uniqID, not to be used for security
|
||||
$view->headScript()->appendScript("var UNIQID = '" . uniqid() . "';");
|
||||
|
||||
$track_type_options = array();
|
||||
$track_types = Application_Model_Tracktype::getTracktypes();
|
||||
foreach ($track_types as $key => $tt) {
|
||||
$track_type_options[$tt['code']] = $tt['type_name'];
|
||||
}
|
||||
$ttarr = json_encode($track_type_options, JSON_FORCE_OBJECT);
|
||||
$view->headScript()->appendScript("var TRACKTYPES = " . $ttarr . ";");
|
||||
}
|
||||
|
||||
protected function _initHeadLink()
|
||||
|
@ -183,7 +191,7 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
|||
->appendFile($baseUrl . 'js/qtip/jquery.qtip.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'js/jplayer/jquery.jplayer.min.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'js/sprintf/sprintf-0.7-beta1.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'js/cookie/jquery.cookie.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'js/cookie/js.cookie.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'js/i18n/jquery.i18n.js?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'locale/general-translation-table?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
->appendFile($baseUrl . 'locale/datatables-translation-table?' . $CC_CONFIG['airtime_version'], 'text/javascript')
|
||||
|
@ -223,29 +231,12 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
|||
}
|
||||
|
||||
$view->headScript()->appendScript("var userType = '$userType';");
|
||||
if (LIBRETIME_ENABLE_LIVECHAT === true
|
||||
&& array_key_exists('REQUEST_URI', $_SERVER) //Doesn't exist for unit tests
|
||||
&& strpos($_SERVER['REQUEST_URI'], 'Dashboard/stream-player') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], 'audiopreview') === false
|
||||
&& $_SERVER['REQUEST_URI'] != "/") {
|
||||
$plan_level = strval(Application_Model_Preference::GetPlanLevel());
|
||||
// Since the Hobbyist plan doesn't come with Live Chat support, don't enable it
|
||||
if (Application_Model_Preference::GetLiveChatEnabled() && $plan_level !== 'hobbyist') {
|
||||
$client_id = strval(Application_Model_Preference::GetClientId());
|
||||
$station_url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
||||
$view->headScript()->appendScript("var livechat_client_id = '$client_id';\n" .
|
||||
"var livechat_plan_type = '$plan_level';\n" .
|
||||
"var livechat_station_url = 'http://$station_url';");
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/common/livechat.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _initViewHelpers()
|
||||
{
|
||||
$view = $this->_bootstrap->getResource('view');
|
||||
$view->addHelperPath(APPLICATION_PATH . 'views/helpers', 'Airtime_View_Helper');
|
||||
$view->assign('suspended', (Application_Model_Preference::getProvisioningStatus() == PROVISIONING_STATUS_SUSPENDED));
|
||||
}
|
||||
|
||||
protected function _initTitle()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_files ADD COLUMN artwork TYPE character varying(255);
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE podcast_episodes ADD COLUMN episode_title VARCHAR(4096);
|
||||
ALTER TABLE podcast_episodes ADD COLUMN episode_description VARCHAR(4096);
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_blockcriteria ADD COLUMN criteriagroup integer;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE podcast_episodes ALTER COLUMN episode_description TYPE text;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_block ALTER COLUMN type SET DEFAULT 'dynamic';
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE cc_files ADD COLUMN artwork VARCHAR(4096);
|
|
@ -0,0 +1,26 @@
|
|||
ALTER TABLE cc_files ADD COLUMN track_type VARCHAR(16);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "cc_track_types"
|
||||
(
|
||||
"id" serial NOT NULL,
|
||||
"code" VARCHAR(16) NOT NULL,
|
||||
"type_name" VARCHAR(64),
|
||||
"description" VARCHAR(255),
|
||||
"visibility" boolean DEFAULT true NOT NULL,
|
||||
CONSTRAINT "cc_track_types_pkey" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "cc_track_types_code_key" UNIQUE ("code")
|
||||
);
|
||||
|
||||
INSERT INTO cc_track_types VALUES (1, 'MUS', 'Music', 'This is used for tracks containing music.', true);
|
||||
INSERT INTO cc_track_types VALUES (2, 'SID', 'Station ID', 'This is used for Station IDs', true);
|
||||
INSERT INTO cc_track_types VALUES (3, 'INT', 'Show Intro', 'This can be used for organizing all the show introductions.', true);
|
||||
INSERT INTO cc_track_types VALUES (4, 'OUT', 'Show Outro', 'This can be used for organizing all the show outroductions.', true);
|
||||
INSERT INTO cc_track_types VALUES (5, 'SWP', 'Sweeper', 'This is used for segues between songs.', true);
|
||||
INSERT INTO cc_track_types VALUES (6, 'JIN', 'Jingle', 'A short song or tune, normally played during commercial breaks. Contains one or more hooks.', true);
|
||||
INSERT INTO cc_track_types VALUES (7, 'PRO', 'Promo', 'For promotional use.', true);
|
||||
INSERT INTO cc_track_types VALUES (8, 'SHO', 'Shout Out', 'A message of congratulation, greeting. support, or appreciation. ', true);
|
||||
INSERT INTO cc_track_types VALUES (9, 'NWS', 'News', 'This is used for noteworthy information, announcements.', true);
|
||||
INSERT INTO cc_track_types VALUES (10, 'COM', 'Commercial', 'This is used for commerical advertising.', true);
|
||||
INSERT INTO cc_track_types VALUES (11, 'ITV', 'Interview', 'This is used for radio interviews', true);
|
||||
INSERT INTO cc_track_types VALUES (12, 'VTR', 'Voice Tracking', 'Also referred as robojock or taped. Make announcements without actually being in the station.', true);
|
||||
|
|
@ -15,7 +15,7 @@ class Application_Form_AddShowAutoPlaylist extends Zend_Form_SubForm
|
|||
|
||||
// Add autoplaylist checkbox element
|
||||
$this->addElement('checkbox', 'add_show_has_autoplaylist', array(
|
||||
'label' => _('Auto Schedule Playlist ?'),
|
||||
'label' => _('Add Autoloading Playlist ?'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'decorators' => array('ViewHelper')
|
||||
|
@ -29,7 +29,7 @@ class Application_Form_AddShowAutoPlaylist extends Zend_Form_SubForm
|
|||
$this->addElement($autoPlaylistSelect);
|
||||
// Add autoplaylist checkbox element
|
||||
$this->addElement('checkbox', 'add_show_autoplaylist_repeat', array(
|
||||
'label' => _('Repeat AutoPlaylist Until Show is Full ?'),
|
||||
'label' => _('Repeat Playlist Until Show is Full ?'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'decorators' => array('ViewHelper')
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_AddTracktype extends Zend_Form
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator();
|
||||
|
||||
$this->setAttrib('id', 'tracktype_form');
|
||||
|
||||
$hidden = new Zend_Form_Element_Hidden('tracktype_id');
|
||||
$hidden->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($hidden);
|
||||
|
||||
$this->addElement('hash', 'csrf', array(
|
||||
'salt' => 'unique'
|
||||
));
|
||||
|
||||
$typeName = new Zend_Form_Element_Text('type_name');
|
||||
$typeName->setLabel(_('Type Name:'));
|
||||
$typeName->setAttrib('class', 'input_text');
|
||||
$typeName->addFilter('StringTrim');
|
||||
$this->addElement($typeName);
|
||||
|
||||
$code = new Zend_Form_Element_Text('code');
|
||||
$code->setLabel(_('Code:'));
|
||||
$code->setAttrib('class', 'input_text');
|
||||
$code->setAttrib('style', 'width: 40%');
|
||||
$code->setRequired(true);
|
||||
$code->addValidator($notEmptyValidator);
|
||||
$code->addFilter('StringTrim');
|
||||
$this->addElement($code);
|
||||
|
||||
$description = new Zend_Form_Element_Textarea('description');
|
||||
$description->setLabel(_('Description:'))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
new Zend_Validate_StringLength(array('max' => 200))
|
||||
));
|
||||
$description->setAttrib('class', 'input_text');
|
||||
$description->addFilter('StringTrim');
|
||||
$this->addElement($description);
|
||||
|
||||
$visibility = new Zend_Form_Element_Select('visibility');
|
||||
$visibility->setLabel(_('Visibility:'));
|
||||
$visibility->setAttrib('class', 'input_select');
|
||||
$visibility->setAttrib('style', 'width: 40%');
|
||||
$visibility->setMultiOptions(array(
|
||||
"0" => _("Disabled"),
|
||||
"1" => _("Enabled")
|
||||
));
|
||||
//$visibility->getValue();
|
||||
$visibility->setRequired(true);
|
||||
$this->addElement($visibility);
|
||||
|
||||
$saveBtn = new Zend_Form_Element_Button('save_tracktype');
|
||||
$saveBtn->setAttrib('class', 'btn right-floated');
|
||||
$saveBtn->setIgnore(true);
|
||||
$saveBtn->setLabel(_('Save'));
|
||||
$this->addElement($saveBtn);
|
||||
}
|
||||
|
||||
public function validateCode($data)
|
||||
{
|
||||
if (strlen($data['tracktype_id']) == 0) {
|
||||
$count = CcTracktypesQuery::create()->filterByDbCode($data['code'])->count();
|
||||
|
||||
if ($count != 0) {
|
||||
$this->getElement('code')->setErrors(array(_("Code is not unique.")));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_BillingClient extends Zend_Form
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
/*$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/
|
||||
$client = Billing::getClientDetails();
|
||||
$this->setAttrib("id", "clientdetails_form");
|
||||
|
||||
$notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator();
|
||||
$emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator();
|
||||
|
||||
$firstname = new Zend_Form_Element_Text('firstname');
|
||||
$firstname->setLabel(_pro('First Name:'))
|
||||
->setValue($client["firstname"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($firstname);
|
||||
|
||||
$lastname = new Zend_Form_Element_Text('lastname');
|
||||
$lastname->setLabel(_pro('Last Name:'))
|
||||
->setValue($client["lastname"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($lastname);
|
||||
|
||||
$companyname = new Zend_Form_Element_Text('companyname');
|
||||
$companyname->setLabel(_pro('Company Name:'))
|
||||
->setValue($client["companyname"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(false)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($companyname);
|
||||
|
||||
$email = new Zend_Form_Element_Text('email');
|
||||
$email->setLabel(_pro('Email Address:'))
|
||||
->setValue($client["email"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->setAttrib('readonly', 'readonly')
|
||||
->addValidator($emailValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($email);
|
||||
|
||||
$address1 = new Zend_Form_Element_Text('address1');
|
||||
$address1->setLabel(_pro('Address 1:'))
|
||||
->setValue($client["address1"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($address1);
|
||||
|
||||
$address2 = new Zend_Form_Element_Text('address2');
|
||||
$address2->setLabel(_pro('Address 2:'))
|
||||
->setValue($client["address2"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($address2);
|
||||
|
||||
$city = new Zend_Form_Element_Text('city');
|
||||
$city->setLabel(_pro('City:'))
|
||||
->setValue($client["city"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($city);
|
||||
|
||||
//TODO: get list from whmcs?
|
||||
$state = new Zend_Form_Element_Text('state');
|
||||
$state->setLabel(_pro('State/Region:'))
|
||||
->setValue($client["state"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($state);
|
||||
|
||||
$postcode = new Zend_Form_Element_Text('postcode');
|
||||
$postcode->setLabel(_pro('Zip Code / Postal Code:'))
|
||||
->setValue($client["postcode"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($postcode);
|
||||
|
||||
$locale = new Zend_Locale('en_US');
|
||||
$countries = $locale->getTranslationList('Territory', 'en', 2);
|
||||
asort($countries, SORT_LOCALE_STRING);
|
||||
|
||||
$country = new Zend_Form_Element_Select('country');
|
||||
$country->setLabel(_pro('Country:'))
|
||||
->setValue($client["country"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setMultiOptions($countries)
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($country);
|
||||
|
||||
$phonenumber = new Zend_Form_Element_Text('phonenumber');
|
||||
$phonenumber->setLabel(_pro('Phone Number:'))
|
||||
->setValue($client["phonenumber"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($phonenumber);
|
||||
|
||||
$securityqid = new Zend_Form_Element_Select('securityqid');
|
||||
$securityqid->setLabel(_pro('Please choose a security question:'))
|
||||
->setValue($client["securityqid"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->setMultiOptions(array(
|
||||
"1" => _("What is the name of your favorite childhood friend?"),
|
||||
"3" => _("What school did you attend for sixth grade?"),
|
||||
"4" => _("In what city did you meet your spouse/significant other?"),
|
||||
"5" => _("What street did you live on in third grade?"),
|
||||
"6" => _("What is the first name of the boy or girl that you first kissed?"),
|
||||
"7" => _("In what city or town was your first job?")));
|
||||
$this->addElement($securityqid);
|
||||
|
||||
$securityqans = new Zend_Form_Element_Text('securityqans');
|
||||
$securityqans->setLabel(_pro('Please enter an answer:'))
|
||||
->setValue($client["securityqans"])
|
||||
->setAttrib('class', 'input_text')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($securityqans);
|
||||
|
||||
foreach ($client["customfields"] as $field) {
|
||||
if ($field["id"] == "7") {
|
||||
$vatvalue = $field["value"];
|
||||
} elseif ($field["id"] == "71") {
|
||||
$subscribevalue = $field["value"];
|
||||
}
|
||||
}
|
||||
|
||||
$vat = new Zend_Form_Element_Text("7");
|
||||
$vat->setLabel(_pro('VAT/Tax ID (EU only)'))
|
||||
->setBelongsTo('customfields')
|
||||
->setValue($vatvalue)
|
||||
->setAttrib('class', 'input_text')
|
||||
//->setRequired(true)
|
||||
//->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($vat);
|
||||
|
||||
$subscribe = new Zend_Form_Element_Checkbox('71');
|
||||
$subscribe->setLabel(_pro('Subscribe to Sourcefabric newsletter'))
|
||||
->setValue($subscribevalue)
|
||||
->setBelongsTo('customfields')
|
||||
->setAttrib('class', 'billing-details-checkbox')
|
||||
->setRequired(true)
|
||||
->addValidator($notEmptyValidator)
|
||||
->addFilter('StringTrim');
|
||||
$this->addElement($subscribe);
|
||||
|
||||
$password = new Zend_Form_Element_Password('password2');
|
||||
$password->setLabel(_pro('Password:'));
|
||||
$password->setAttrib('class', 'input_text');
|
||||
$password->setValue("xxxxxx");
|
||||
$password->setRequired(true);
|
||||
$password->addFilter('StringTrim');
|
||||
$password->addValidator($notEmptyValidator);
|
||||
$this->addElement($password);
|
||||
|
||||
$passwordVerify = new Zend_Form_Element_Password('password2verify');
|
||||
$passwordVerify->setLabel(_pro('Verify Password:'));
|
||||
$passwordVerify->setAttrib('class', 'input_text');
|
||||
$passwordVerify->setValue("xxxxxx");
|
||||
$passwordVerify->setRequired(true);
|
||||
$passwordVerify->addFilter('StringTrim');
|
||||
//$passwordVerify->addValidator($notEmptyValidator);
|
||||
$passwordVerify->addValidator('Identical', false, array('token' => 'password2'));
|
||||
$passwordVerify->addValidator($notEmptyValidator);
|
||||
$this->addElement($passwordVerify);
|
||||
|
||||
$this->addElement('hash', 'csrf_client', array(
|
||||
'salt' => 'unique'
|
||||
));
|
||||
|
||||
$submit = new Zend_Form_Element_Submit("submit");
|
||||
$submit->setIgnore(true)
|
||||
->setLabel(_pro("Save"));
|
||||
$this->addElement($submit);
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
class Application_Form_BillingUpgradeDowngrade extends Zend_Form
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$this->addElement('hash', 'csrf_upgrade', array( //Needs a unique ID (csrf_upgrade) so it doesn't conflict with other tokens in subforms
|
||||
'salt' => 'unique'
|
||||
));
|
||||
|
||||
$productPrices = array();
|
||||
$productTypes = array();
|
||||
list($productPrices, $productTypes) = Billing::getProductPricesAndTypes();
|
||||
|
||||
$currentPlanProduct = Billing::getClientCurrentAirtimeProduct();
|
||||
$currentPlanProductId = $currentPlanProduct["pid"];
|
||||
|
||||
$currentPlanProductBillingCycle = $currentPlanProduct["billingcycle"];
|
||||
$pid = new Zend_Form_Element_Radio('newproductid');
|
||||
$pid->setLabel(_('Plan type:'))
|
||||
->setMultiOptions($productTypes)
|
||||
->setRequired(true)
|
||||
->setValue($currentPlanProductId);
|
||||
$this->addElement($pid);
|
||||
|
||||
//Logging::info(BillingController::getClientCurrentAirtimeProduct());
|
||||
$billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle');
|
||||
$billingCycleOptionMap = array('monthly' => 'Monthly', 'annually' => 'Annually (Holiday Promo)');
|
||||
if (!array_key_exists($currentPlanProductBillingCycle, $billingCycleOptionMap)) {
|
||||
$currentPlanProductBillingCycle = 'monthly';
|
||||
}
|
||||
$billingcycle->setLabel(_('Billing cycle:'))
|
||||
->setMultiOptions($billingCycleOptionMap)
|
||||
->setRequired(true)
|
||||
->setValue($currentPlanProductBillingCycle);
|
||||
|
||||
$this->addElement($billingcycle);
|
||||
|
||||
$paymentmethod = new Zend_Form_Element_Radio('paymentmethod');
|
||||
$paymentmethod->setLabel(_('Payment method:'))
|
||||
->setRequired(true)
|
||||
->setMultiOptions(array(
|
||||
'paypal' => _('PayPal'),
|
||||
'tco' => _('Credit Card via 2Checkout')))
|
||||
->setValue('paypal');
|
||||
$this->addElement($paymentmethod);
|
||||
|
||||
/*$submit = new Zend_Form_Element_Submit("submit");
|
||||
$submit->setIgnore(true)
|
||||
->setLabel(_("Save"));
|
||||
$this->addElement($submit);*/
|
||||
|
||||
$client = new Application_Form_BillingClient();
|
||||
$client->removeElement("password2");
|
||||
$client->removeElement("password2verify");
|
||||
$this->addSubForm($client, 'billing_client_info');
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
class Application_Form_EditAudioMD extends Zend_Form
|
||||
{
|
||||
|
||||
|
||||
public function init() {}
|
||||
|
||||
|
||||
public function startForm($p_id)
|
||||
{
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
@ -18,6 +18,34 @@ class Application_Form_EditAudioMD extends Zend_Form
|
|||
$file_id->setAttrib('class', 'obj_id');
|
||||
$this->addElement($file_id);
|
||||
|
||||
// Add artwork hidden field
|
||||
$artwork = new Zend_Form_Element_Hidden('artwork');
|
||||
$artwork->class = 'input_text artwork_'. $p_id;
|
||||
$artwork->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
new Zend_Validate_StringLength(array('max' => 2048))
|
||||
));
|
||||
$file_id->addDecorator('HtmlTag', array('tag' => 'div', 'style' => 'display:none'));
|
||||
$file_id->removeDecorator('Label');
|
||||
$file_id->setAttrib('class', 'artwork');
|
||||
$this->addElement($artwork);
|
||||
|
||||
// Set artwork hidden field
|
||||
$set_artwork = new Zend_Form_Element_Hidden('set_artwork');
|
||||
$set_artwork->class = 'input_text set_artwork_'. $p_id;
|
||||
$file_id->addDecorator('HtmlTag', array('tag' => 'div', 'style' => 'display:none'));
|
||||
$file_id->removeDecorator('Label');
|
||||
$file_id->setAttrib('class', 'set_artwork');
|
||||
$this->addElement($set_artwork);
|
||||
|
||||
// Remove artwork hidden field
|
||||
$remove_artwork = new Zend_Form_Element_Hidden('remove_artwork');
|
||||
$remove_artwork->class = 'input_text remove_artwork_'. $p_id;
|
||||
$file_id->addDecorator('HtmlTag', array('tag' => 'div', 'style' => 'display:none'));
|
||||
$file_id->removeDecorator('Label');
|
||||
$file_id->setAttrib('class', 'remove_artwork');
|
||||
$this->addElement($remove_artwork);
|
||||
|
||||
// Add title field
|
||||
$track_title = new Zend_Form_Element_Text('track_title');
|
||||
$track_title->class = 'input_text';
|
||||
|
@ -48,6 +76,35 @@ class Application_Form_EditAudioMD extends Zend_Form
|
|||
));
|
||||
$this->addElement($album_title);
|
||||
|
||||
|
||||
// Add album field
|
||||
$user_options = array();
|
||||
$users = Application_Model_User::getNonGuestUsers();
|
||||
|
||||
foreach ($users as $host) {
|
||||
$user_options[$host['index']] = $host['label'];
|
||||
}
|
||||
|
||||
$owner_id = new Zend_Form_Element_Select('owner_id');
|
||||
$owner_id->class = 'input_text';
|
||||
$owner_id->setLabel(_('Owner:'));
|
||||
$owner_id->setMultiOptions($user_options);
|
||||
$this->addelement($owner_id);
|
||||
|
||||
// Add track type dropdown
|
||||
$track_type_options = array();
|
||||
$track_types = Application_Model_Tracktype::getTracktypes();
|
||||
$track_type_options[""] = _('Select a Type');
|
||||
foreach ($track_types as $key => $tt) {
|
||||
$track_type_options[$tt['code']] = $tt['type_name'];
|
||||
}
|
||||
|
||||
$track_type = new Zend_Form_Element_Select('track_type');
|
||||
$track_type->class = 'input_text';
|
||||
$track_type->setLabel(_('Track Type:'));
|
||||
$track_type->setMultiOptions($track_type_options);
|
||||
$this->addelement($track_type);
|
||||
|
||||
// Description field
|
||||
$description = new Zend_Form_Element_Textarea('description');
|
||||
$description->class = 'input_text';
|
||||
|
@ -244,6 +301,9 @@ class Application_Form_EditAudioMD extends Zend_Form
|
|||
}
|
||||
}
|
||||
|
||||
public function removeOwnerEdit() {
|
||||
$this->removeElement('owner_id');
|
||||
}
|
||||
public function removeActionButtons()
|
||||
{
|
||||
$this->removeElement('editmdsave');
|
||||
|
|
|
@ -130,18 +130,6 @@ class Application_Form_EditUser extends Zend_Form
|
|||
$timezone->setValue($userTz == $stationTz ? null : $userTz);
|
||||
$timezone->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($timezone);
|
||||
|
||||
if (LIBRETIME_ENABLE_BILLING === true && Application_Model_User::getCurrentUser()->isSuperAdmin()) {
|
||||
$elemsToDisable = array($password, $passwordVerify, $email, $firstName, $lastName,
|
||||
$cellPhone, $skype, $jabber);
|
||||
foreach ($elemsToDisable as $element) {
|
||||
//$this->_redirect('billing/client');
|
||||
$element->setAttrib('disabled', 'disabled');
|
||||
$element->setAttrib('readonly', 'readonly');
|
||||
$element->setRequired(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function validateLogin($p_login, $p_userId) {
|
||||
|
|
|
@ -100,15 +100,33 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
|
|||
'value' => $defaultFadeOut,
|
||||
));
|
||||
|
||||
$tracktypeDefault = new Zend_Form_Element_Select("tracktypeDefault");
|
||||
$tracktypeDefault->setLabel(_("Track Type Upload Default"));
|
||||
$tracktypeDefault->setMultiOptions(Application_Model_Library::getTracktypes());
|
||||
$tracktypeDefault->setValue(Application_Model_Preference::GetTrackTypeDefault());
|
||||
$this->addElement($tracktypeDefault);
|
||||
|
||||
// add intro playlist select here
|
||||
$introPlaylistSelect = new Zend_Form_Element_Select("introPlaylistSelect");
|
||||
$introPlaylistSelect->setLabel(_("Intro Autoloading Playlist"));
|
||||
$introPlaylistSelect->setMultiOptions(Application_Model_Library::getPlaylistNames(true));
|
||||
$introPlaylistSelect->setValue(Application_Model_Preference::GetIntroPlaylist());
|
||||
$this->addElement($introPlaylistSelect);
|
||||
|
||||
$outroPlaylistSelect = new Zend_Form_Element_Select("outroPlaylistSelect");
|
||||
$outroPlaylistSelect->setLabel(_("Outro Autoloading Playlist"));
|
||||
$outroPlaylistSelect->setMultiOptions(Application_Model_Library::getPlaylistNames(true));
|
||||
$outroPlaylistSelect->setValue(Application_Model_Preference::GetOutroPlaylist());
|
||||
$this->addElement($outroPlaylistSelect);
|
||||
|
||||
$podcast_album_override = new Zend_Form_Element_Radio('podcastAlbumOverride');
|
||||
$podcast_album_override->setLabel(_('Podcast Album Override'));
|
||||
$podcast_album_override->setLabel(_('Overwrite Podcast Episode Metatags'));
|
||||
$podcast_album_override->setMultiOptions(array(
|
||||
_("Disabled"),
|
||||
_("Enabled"),
|
||||
));
|
||||
$podcast_album_override->setValue(Application_Model_Preference::GetPodcastAlbumOverride());
|
||||
$podcast_album_override->setDescription(_('Enabling this means that podcast tracks will always contain the podcast name in their album field.'));
|
||||
$podcast_album_override->setDescription(_('Enabling this feature will cause podcast episode tracks to have their Artist, Title, and Album metatags set from podcast feed values. Note that enabling this feature is recommended in order to ensure reliable scheduling of episodes via smartblocks.'));
|
||||
$podcast_album_override->setSeparator(' '); //No <br> between radio buttons
|
||||
$podcast_album_override->addDecorator('HtmlTag', array('tag' => 'dd',
|
||||
'id'=>"podcastAlbumOverride-element",
|
||||
|
@ -117,14 +135,13 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
|
|||
$this->addElement($podcast_album_override);
|
||||
|
||||
$podcast_auto_smartblock = new Zend_Form_Element_Radio('podcastAutoSmartblock');
|
||||
$podcast_auto_smartblock->setLabel(_('Podcast Automatic Smartblock and Playlist'));
|
||||
$podcast_auto_smartblock->setLabel(_('Generate a smartblock and a playlist upon creation of a new podcast'));
|
||||
$podcast_auto_smartblock->setMultiOptions(array(
|
||||
_("Disabled"),
|
||||
_("Enabled"),
|
||||
));
|
||||
$podcast_auto_smartblock->setValue(Application_Model_Preference::GetPodcastAutoSmartblock());
|
||||
$podcast_auto_smartblock->setDescription(_('Enabling this means that a smartblock and playlist matching the newest track of a
|
||||
podcast will be created when a new podcast is added. This depends upon the Podcast Album Override to work.'));
|
||||
$podcast_auto_smartblock->setDescription(_('If this option is enabled, a new smartblock and playlist matching the newest track of a podcast will be generated immediately upon creation of a new podcast. Note that the "Overwrite Podcast Episode Metatags" feature must also be enabled in order for smartblocks to reliably find episodes.'));
|
||||
$podcast_auto_smartblock->setSeparator(' '); //No <br> between radio buttons
|
||||
$podcast_auto_smartblock->addDecorator('HtmlTag', array('tag' => 'dd',
|
||||
'id'=>"podcastAutoSmartblock-element",
|
||||
|
@ -135,14 +152,14 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
|
|||
//TODO add and insert Podcast Smartblock and Playlist autogenerate options
|
||||
|
||||
$third_party_api = new Zend_Form_Element_Radio('thirdPartyApi');
|
||||
$third_party_api->setLabel(_('Public Airtime API'));
|
||||
$third_party_api->setLabel(_('Public LibreTime API'));
|
||||
$third_party_api->setDescription(_('Required for embeddable schedule widget.'));
|
||||
$third_party_api->setMultiOptions(array(
|
||||
_("Disabled"),
|
||||
_("Enabled"),
|
||||
));
|
||||
$third_party_api->setValue(Application_Model_Preference::GetAllow3rdPartyApi());
|
||||
$third_party_api->setDescription(_('Enabling this feature will allow Airtime to provide schedule data
|
||||
$third_party_api->setDescription(_('Enabling this feature will allow LibreTime to provide schedule data
|
||||
to external widgets that can be embedded in your website.'));
|
||||
$third_party_api->setSeparator(' '); //No <br> between radio buttons
|
||||
//$third_party_api->addDecorator(new Zend_Form_Decorator_Label(array('tag' => 'dd', 'class' => 'radio-inline-list')));
|
||||
|
|
|
@ -11,7 +11,7 @@ class Application_Form_Login extends Zend_Form
|
|||
$this->setMethod('post');
|
||||
|
||||
//If the request comes from an origin we consider safe, we disable the CSRF
|
||||
//token checking ONLY for the login page. We do this to allow logins from WHMCS to work.
|
||||
//token checking ONLY for the login page.
|
||||
$request = Zend_Controller_Front::getInstance()->getRequest();
|
||||
if ($request) {
|
||||
$refererUrl = $request->getHeader('referer');
|
||||
|
@ -71,10 +71,6 @@ class Application_Form_Login extends Zend_Form
|
|||
"locale" => Application_Model_Locale::getUserLocale()
|
||||
));
|
||||
|
||||
if (Application_Model_LoginAttempts::getAttempts($_SERVER['REMOTE_ADDR']) >= 3) {
|
||||
$this->addRecaptcha();
|
||||
}
|
||||
|
||||
// Add the submit button
|
||||
$this->addElement('submit', 'submit', array(
|
||||
'ignore' => true,
|
||||
|
@ -87,26 +83,6 @@ class Application_Form_Login extends Zend_Form
|
|||
|
||||
}
|
||||
|
||||
public function addRecaptcha()
|
||||
{
|
||||
$pubKey = '6Ld4JsISAAAAAIxUKT4IjjOGi3DHqdoH2zk6WkYG';
|
||||
$privKey = '6Ld4JsISAAAAAJynYlXdrE4hfTReTSxYFe5szdyv';
|
||||
|
||||
$params= array('ssl' => true);
|
||||
$recaptcha = new Zend_Service_ReCaptcha($pubKey, $privKey, $params);
|
||||
|
||||
$captcha = new Zend_Form_Element_Captcha('captcha',
|
||||
array(
|
||||
'label' => _('Type the characters you see in the picture below.'),
|
||||
'captcha' => 'ReCaptcha',
|
||||
'captchaOptions' => array(
|
||||
'captcha' => 'ReCaptcha',
|
||||
'service' => $recaptcha
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement($captcha);
|
||||
}
|
||||
|
||||
/**
|
||||
* tests if a string starts with a given string
|
||||
|
|
|
@ -75,6 +75,12 @@ class Application_Form_Player extends Zend_Form_SubForm
|
|||
|
||||
$previewLabel = new Zend_Form_Element_Text('player_preview_label');
|
||||
$previewLabel->setLabel(_("Preview:"));
|
||||
$previewLabel->setDecorators(array(
|
||||
'ViewHelper',
|
||||
'Errors',
|
||||
'Label'
|
||||
));
|
||||
$previewLabel->addDecorator('Label', array('class' => 'preview-label'));
|
||||
$this->addElement($previewLabel);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once 'customfilters/ImageSize.php';
|
||||
|
||||
class Application_Form_RegisterAirtime extends Zend_Form
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setAction(Application_Common_OsPath::getBaseDir().'showbuilder');
|
||||
$this->setMethod('post');
|
||||
|
||||
$country_list = Application_Model_Preference::GetCountryList();
|
||||
|
||||
$privacyChecked = false;
|
||||
if (Application_Model_Preference::GetPrivacyPolicyCheck() == 1) {
|
||||
$privacyChecked = true;
|
||||
}
|
||||
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' =>
|
||||
'form/register-dialog.phtml', 'privacyChecked'=>$privacyChecked)),
|
||||
|
||||
array('File', array('viewScript' => 'form/register-dialog.phtml',
|
||||
'placement' => false)))
|
||||
);
|
||||
|
||||
// Station Name
|
||||
$stnName = new Zend_Form_Element_Text("stnName");
|
||||
$stnName->setLabel(_("Station Name"))
|
||||
->setRequired(true)
|
||||
->setValue(Application_Model_Preference::GetStationName())
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($stnName);
|
||||
|
||||
// Phone number
|
||||
$this->addElement('text', 'Phone', array(
|
||||
'class' => 'input_text',
|
||||
'label' => _('Phone:'),
|
||||
'required' => false,
|
||||
'filters' => array('StringTrim'),
|
||||
'value' => Application_Model_Preference::GetPhone(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
//Email
|
||||
$this->addElement('text', 'Email', array(
|
||||
'class' => 'input_text',
|
||||
'label' => _('Email:'),
|
||||
'required' => false,
|
||||
'filters' => array('StringTrim'),
|
||||
'value' => Application_Model_Preference::GetEmail(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station Web Site
|
||||
$this->addElement('text', 'StationWebSite', array(
|
||||
'label' => _('Station Web Site:'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'value' => Application_Model_Preference::GetStationWebSite(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// county list dropdown
|
||||
$this->addElement('select', 'Country', array(
|
||||
'label' => _('Country:'),
|
||||
'required' => false,
|
||||
'value' => Application_Model_Preference::GetStationCountry(),
|
||||
'multiOptions' => $country_list,
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station city
|
||||
$this->addElement('text', 'City', array(
|
||||
'label' => _('City:'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'value' => Application_Model_Preference::GetStationCity(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station Description
|
||||
$description = new Zend_Form_Element_Textarea('Description');
|
||||
$description->class = 'input_text_area';
|
||||
$description->setLabel(_('Station Description:'))
|
||||
->setRequired(false)
|
||||
->setValue(Application_Model_Preference::GetStationDescription())
|
||||
->setDecorators(array('ViewHelper'))
|
||||
->setAttrib('ROWS','2')
|
||||
->setAttrib('COLS','58');
|
||||
$this->addElement($description);
|
||||
|
||||
// Station Logo
|
||||
$upload = new Zend_Form_Element_File('Logo');
|
||||
$upload->setLabel(_('Station Logo:'))
|
||||
->setRequired(false)
|
||||
->setDecorators(array('File'))
|
||||
->addValidator('Count', false, 1)
|
||||
->addValidator('Extension', false, 'jpg,jpeg,png,gif')
|
||||
->addFilter('ImageSize');
|
||||
$this->addElement($upload);
|
||||
|
||||
//enable support feedback
|
||||
$this->addElement('checkbox', 'SupportFeedback', array(
|
||||
'label' => _('Send support feedback'),
|
||||
'required' => false,
|
||||
'value' => 1,
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// checkbox for publicise
|
||||
$checkboxPublicise = new Zend_Form_Element_Checkbox("Publicise");
|
||||
$checkboxPublicise->setLabel(sprintf(_('Promote my station on %s'), COMPANY_SITE))
|
||||
->setRequired(false)
|
||||
->setDecorators(array('ViewHelper'))
|
||||
->setValue(Application_Model_Preference::GetPublicise());
|
||||
$this->addElement($checkboxPublicise);
|
||||
|
||||
// text area for sending detail
|
||||
$this->addElement('textarea', 'SendInfo', array(
|
||||
'class' => 'sending_textarea',
|
||||
'required' => false,
|
||||
'filters' => array('StringTrim'),
|
||||
'readonly' => true,
|
||||
'rows' => 5,
|
||||
'cols' => 61,
|
||||
'value' => Application_Model_Preference::GetSystemInfo(false, true),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
$privacyPolicyAnchorOpen = "<a id='link_to_privacy' href='" . PRIVACY_POLICY_URL
|
||||
. "' onclick='window.open(this.href); return false;'>";
|
||||
// checkbox for privacy policy
|
||||
$checkboxPrivacy = new Zend_Form_Element_Checkbox("Privacy");
|
||||
$checkboxPrivacy->setLabel(
|
||||
sprintf(_('By checking this box, I agree to %s\'s %sprivacy policy%s.'),
|
||||
COMPANY_NAME,
|
||||
$privacyPolicyAnchorOpen,
|
||||
"</a>"))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($checkboxPrivacy);
|
||||
}
|
||||
|
||||
// overriding isValid function
|
||||
public function isValid ($data)
|
||||
{
|
||||
$isValid = parent::isValid($data);
|
||||
if ($data['Publicise'] != 1) {
|
||||
$isValid = true;
|
||||
}
|
||||
if (isset($data["Privacy"])) {
|
||||
$checkPrivacy = $this->getElement('Privacy');
|
||||
if ($data["SupportFeedback"] == "1" && $data["Privacy"] != "1") {
|
||||
$checkPrivacy->addError(_("You have to agree to privacy policy."));
|
||||
$isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $isValid;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_ShowListenerStat extends Zend_Form_SubForm
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/daterange.phtml'))
|
||||
));
|
||||
|
||||
// Add start date element
|
||||
$startDate = new Zend_Form_Element_Text('his_date_start');
|
||||
$startDate->class = 'input_text';
|
||||
$startDate->setRequired(true)
|
||||
->setLabel(_('Date Start:'))
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startDate->setAttrib('alt', 'date');
|
||||
$this->addElement($startDate);
|
||||
|
||||
// Add start time element
|
||||
$startTime = new Zend_Form_Element_Text('his_time_start');
|
||||
$startTime->class = 'input_text';
|
||||
$startTime->setRequired(true)
|
||||
->setValue('00:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-2]?[0-9]:[0-5][0-9]$/', 'messages' => _('Invalid character entered')))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startTime->setAttrib('alt', 'time');
|
||||
$this->addElement($startTime);
|
||||
|
||||
// Add end date element
|
||||
$endDate = new Zend_Form_Element_Text('his_date_end');
|
||||
$endDate->class = 'input_text';
|
||||
$endDate->setRequired(true)
|
||||
->setLabel(_('Date End:'))
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endDate->setAttrib('alt', 'date');
|
||||
$this->addElement($endDate);
|
||||
|
||||
// Add end time element
|
||||
$endTime = new Zend_Form_Element_Text('his_time_end');
|
||||
$endTime->class = 'input_text';
|
||||
$endTime->setRequired(true)
|
||||
->setValue('01:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-2]?[0-9]:[0-5][0-9]$/', 'messages' => _('Invalid character entered')))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endTime->setAttrib('alt', 'time');
|
||||
$this->addElement($endTime);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
private $timePeriodCriteriaOptions;
|
||||
private $sortOptions;
|
||||
private $limitOptions;
|
||||
private $isOrNotCriteriaOptions;
|
||||
private $trackTypeOptions;
|
||||
|
||||
/* We need to know if the criteria value will be a string
|
||||
* or numeric value in order to populate the modifier
|
||||
|
@ -42,7 +44,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
"track_title" => "s",
|
||||
"track_number" => "n",
|
||||
"info_url" => "s",
|
||||
"year" => "n"
|
||||
"year" => "n",
|
||||
"track_type" => "tt"
|
||||
);
|
||||
|
||||
private function getCriteriaOptions($option = null)
|
||||
|
@ -68,6 +71,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
"mtime" => _("Last Modified"),
|
||||
"lptime" => _("Last Played"),
|
||||
"length" => _("Length"),
|
||||
"track_type" => _("Track Type"),
|
||||
"mime" => _("Mime"),
|
||||
"mood" => _("Mood"),
|
||||
"owner_id" => _("Owner"),
|
||||
|
@ -159,7 +163,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$this->limitOptions = array(
|
||||
"hours" => _("hours"),
|
||||
"minutes" => _("minutes"),
|
||||
"items" => _("items")
|
||||
"items" => _("items"),
|
||||
"remaining" => _("time remaining in show")
|
||||
);
|
||||
}
|
||||
return $this->limitOptions;
|
||||
|
@ -170,28 +175,53 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$this->sortOptions = array(
|
||||
"random" => _("Randomly"),
|
||||
"newest" => _("Newest"),
|
||||
"oldest" => _("Oldest")
|
||||
"oldest" => _("Oldest"),
|
||||
"mostrecentplay" => _("Most recently played"),
|
||||
"leastrecentplay" => _("Least recently played")
|
||||
);
|
||||
}
|
||||
return $this->sortOptions;
|
||||
}
|
||||
|
||||
private function getIsNotOptions()
|
||||
{
|
||||
if (!isset($this->isOrNotCriteriaOptions)) {
|
||||
$this->isOrNotCriteriaOptions = array(
|
||||
"0" => _("Select modifier"),
|
||||
"is" => _("is"),
|
||||
"is not" => _("is not")
|
||||
);
|
||||
}
|
||||
return $this->isOrNotCriteriaOptions;
|
||||
}
|
||||
|
||||
private function getTracktypeOptions()
|
||||
{
|
||||
if (!isset($this->trackTypeOptions)) {
|
||||
$tracktypes = Application_Model_Tracktype::getTracktypes();
|
||||
$names[] = _("Select Track Type");
|
||||
foreach($tracktypes as $arr => $a){
|
||||
$names[$a["code"]] = $tracktypes[$arr]["type_name"];
|
||||
}
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* converts UTC timestamp citeria into user timezone strings.
|
||||
*/
|
||||
private function convertTimestamps(&$criteria)
|
||||
{
|
||||
$columns = array("utime", "mtime", "lptime");
|
||||
|
||||
|
||||
foreach ($columns as $column) {
|
||||
|
||||
|
||||
if (isset($criteria[$column])) {
|
||||
|
||||
|
||||
foreach ($criteria[$column] as &$constraint) {
|
||||
// convert to appropriate timezone timestamps only if the modifier is not a relative time
|
||||
if (!in_array($constraint['modifier'], array('before','after','between'))) {
|
||||
|
@ -223,7 +253,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
{
|
||||
// load type
|
||||
$out = CcBlockQuery::create()->findPk($p_blockId);
|
||||
if ($out->getDbType() == "static") {
|
||||
if ($out->getDbType() == "dynamic") {
|
||||
$blockType = 0;
|
||||
} else {
|
||||
$blockType = 1;
|
||||
|
@ -233,15 +263,17 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$spType->setLabel(_('Type:'))
|
||||
->setDecorators(array('viewHelper'))
|
||||
->setMultiOptions(array(
|
||||
'static' => _('Static'),
|
||||
'dynamic' => _('Dynamic')
|
||||
'dynamic' => _('Dynamic'),
|
||||
'static' => _('Static')
|
||||
|
||||
))
|
||||
->setValue($blockType);
|
||||
$this->addElement($spType);
|
||||
|
||||
$bl = new Application_Model_Block($p_blockId);
|
||||
$storedCrit = $bl->getCriteria();
|
||||
|
||||
$storedCrit = $bl->getCriteriaGrouped();
|
||||
Logging::info($storedCrit);
|
||||
|
||||
//need to convert criteria to be displayed in the user's timezone if there's some timestamp type.
|
||||
self::convertTimestamps($storedCrit["crit"]);
|
||||
|
||||
|
@ -261,181 +293,223 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
if (isset($storedCrit["crit"])) {
|
||||
$criteriaKeys = array_keys($storedCrit["crit"]);
|
||||
}
|
||||
//the way the everything is currently built it setups 25 smartblock criteria forms and then disables them
|
||||
//but this creates 29 elements
|
||||
$numElements = count($this->getCriteriaOptions());
|
||||
// loop through once for each potential criteria option ie album, composer, track
|
||||
// criteria from different groups are separated already by the getCriteriaGrouped call
|
||||
|
||||
for ($i = 0; $i < $numElements; $i++) {
|
||||
$criteriaType = "";
|
||||
|
||||
// if there is a criteria found then count the number of rows for this specific criteria ie > 1 track title
|
||||
// need to refactor this to maintain separation based upon criteria grouping
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
//Logging::info($criteriaKeys[$i]);
|
||||
Logging::info($storedCrit["crit"][$criteriaKeys[$i]]);
|
||||
$critCount = count($storedCrit["crit"][$criteriaKeys[$i]]);
|
||||
} else {
|
||||
$critCount = 1;
|
||||
}
|
||||
// the challenge is that we need to increment the element for a new group
|
||||
// within the same criteria but not the reference point i in the array
|
||||
// and for these secondary groups they will have a differe$storedCrit["crit"][$criteriaKeys[$i]]nt j reference point
|
||||
// store the number of items with the same key in the ModRowMap
|
||||
$modRowMap[$i] = $critCount;
|
||||
|
||||
// store the number of items with the same key in the ModRowMap
|
||||
$modRowMap[$i] = $critCount;
|
||||
|
||||
/* Loop through all criteria with the same field
|
||||
* Ex: all criteria for 'Album'
|
||||
*/
|
||||
for ($j = 0; $j < $critCount; $j++) {
|
||||
/****************** CRITERIA ***********/
|
||||
// hide the criteria drop down select on any rows after the first
|
||||
if ($j > 0) {
|
||||
$invisible = ' sp-invisible';
|
||||
} else {
|
||||
$invisible = '';
|
||||
}
|
||||
|
||||
$criteria = new Zend_Form_Element_Select("sp_criteria_field_".$i."_".$j);
|
||||
$criteria->setAttrib('class', 'input_select sp_input_select'.$invisible)
|
||||
->setValue('Select criteria')
|
||||
->setDecorators(array('viewHelper'))
|
||||
->setMultiOptions($this->getCriteriaOptions());
|
||||
// if this isn't the first criteria and there isn't an entry for it already disable it
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteria->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
// add the numbering to the form ie the i loop for each specific criteria and
|
||||
// the j loop starts at 0 and grows for each item matching the same criteria
|
||||
// look up the criteria type using the criteriaTypes function from above based upon the criteria value
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
$criteriaType = $this->criteriaTypes[$storedCrit["crit"][$criteriaKeys[$i]][$j]["criteria"]];
|
||||
$criteria->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["criteria"]);
|
||||
}
|
||||
$this->addElement($criteria);
|
||||
|
||||
|
||||
/****************** MODIFIER ***********/
|
||||
// every element has an optional modifier dropdown select
|
||||
|
||||
$criteriaModifers = new Zend_Form_Element_Select("sp_criteria_modifier_".$i."_".$j);
|
||||
$criteriaModifers->setValue('Select modifier')
|
||||
->setAttrib('class', 'input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteriaModifers->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
// determine the modifier based upon criteria type which is looked up based upon an array
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
if ($criteriaType == "s") {
|
||||
$criteriaModifers->setMultiOptions($this->getStringCriteriaOptions());
|
||||
}
|
||||
elseif ($criteriaType == "d") {
|
||||
$criteriaModifers->setMultiOptions($this->getDateTimeCriteriaOptions());
|
||||
}
|
||||
else {
|
||||
$criteriaModifers->setMultiOptions($this->getNumericCriteriaOptions());
|
||||
}
|
||||
$criteriaModifers->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["modifier"]);
|
||||
} else {
|
||||
$criteriaModifers->setMultiOptions(array('0' => _('Select modifier')));
|
||||
}
|
||||
$this->addElement($criteriaModifers);
|
||||
|
||||
/****************** VALUE ***********/
|
||||
/* The challenge here is that datetime */
|
||||
$criteriaValue = new Zend_Form_Element_Text("sp_criteria_value_".$i."_".$j);
|
||||
$criteriaValue->setAttrib('class', 'input_text sp_input_text')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteriaValue->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
/*
|
||||
* Need to parse relative dates in a special way to populate select box down below
|
||||
*/
|
||||
// this is used below to test whether the datetime select should be shown or hidden
|
||||
$relativeDateTime = false;
|
||||
$modifierTest = (string)$storedCrit["crit"][$criteriaKeys[$i]][$j]["modifier"];
|
||||
if(isset($criteriaType) && $criteriaType == "d" &&
|
||||
preg_match('/before|after|between/', $modifierTest) == 1) {
|
||||
// set relativeDatetime boolean to true so that the datetime select is displayed below
|
||||
$relativeDateTime = true;
|
||||
// the criteria value will be a number followed by time unit and ago so set input to number part
|
||||
$criteriaValue->setValue(filter_var($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"], FILTER_SANITIZE_NUMBER_INT));
|
||||
/* Loop through all criteria with the same field
|
||||
* Ex: all criteria for 'Album'
|
||||
*/
|
||||
for ($j = 0; $j < $critCount; $j++) {
|
||||
/****************** CRITERIA ***********/
|
||||
// hide the criteria drop down select on any rows after the first
|
||||
if ($j > 0) {
|
||||
$invisible = ' sp-invisible';
|
||||
} else {
|
||||
$criteriaValue->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
$invisible = '';
|
||||
}
|
||||
}
|
||||
$this->addElement($criteriaValue);
|
||||
|
||||
|
||||
/****************** DATETIME SELECT *************/
|
||||
$criteriaDatetimeSelect = new Zend_Form_Element_Select("sp_criteria_datetime_select_".$i."_".$j);
|
||||
$criteriaDatetimeSelect->setAttrib('class','input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if (isset($criteriaKeys[$i]) && $relativeDateTime) {
|
||||
$criteriaDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
}
|
||||
else {
|
||||
$criteriaDatetimeSelect->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
// check if the value is stored and it is a relative datetime field
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"])
|
||||
&& isset($criteriaType) && $criteriaType == "d" &&
|
||||
preg_match('/before|after|between/', $modifierTest) == 1) {
|
||||
// need to remove any leading numbers stored in the database
|
||||
$dateTimeSelectValue = preg_replace('/[0-9]+/', '', $storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
// need to strip white from front and ago from the end to match with the value of the time unit select dropdown
|
||||
$dateTimeSelectValue = trim(preg_replace('/\W\w+\s*(\W*)$/', '$1', $dateTimeSelectValue));
|
||||
$criteriaDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
$criteriaDatetimeSelect->setValue($dateTimeSelectValue);
|
||||
$criteriaDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
}
|
||||
else {
|
||||
$criteriaDatetimeSelect->setMultiOptions(array('0' => _('Select unit of time')));
|
||||
$criteriaDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
|
||||
}
|
||||
|
||||
$this->addElement($criteriaDatetimeSelect);
|
||||
|
||||
/****************** EXTRA ***********/
|
||||
$criteriaExtra = new Zend_Form_Element_Text("sp_criteria_extra_".$i."_".$j);
|
||||
$criteriaExtra->setAttrib('class', 'input_text sp_extra_input_text')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"])) {
|
||||
// need to check if this is a relative date time value
|
||||
if(isset($criteriaType) && $criteriaType == "d" && $modifierTest == 'between') {
|
||||
// the criteria value will be a number followed by time unit and ago so set input to number part
|
||||
$criteriaExtra->setValue(filter_var($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"], FILTER_SANITIZE_NUMBER_INT));
|
||||
$criteria = new Zend_Form_Element_Select("sp_criteria_field_" . $i . "_" . $j);
|
||||
$criteria->setAttrib('class', 'input_select sp_input_select' . $invisible)
|
||||
->setValue('Select criteria')
|
||||
->setDecorators(array('viewHelper'))
|
||||
->setMultiOptions($this->getCriteriaOptions());
|
||||
// if this isn't the first criteria and there isn't an entry for it already disable it
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteria->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
else {
|
||||
$criteriaExtra->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"]);
|
||||
// add the numbering to the form ie the i loop for each specific criteria and
|
||||
// the j loop starts at 0 and grows for each item matching the same criteria
|
||||
// look up the criteria type using the criteriaTypes function from above based upon the criteria value
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
$criteriaType = $this->criteriaTypes[$storedCrit["crit"][$criteriaKeys[$i]][$j]["criteria"]];
|
||||
$criteria->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["criteria"]);
|
||||
}
|
||||
$criteriaValue->setAttrib('class', 'input_text sp_extra_input_text');
|
||||
} else {
|
||||
$criteriaExtra->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
$this->addElement($criteriaExtra);
|
||||
/****************** DATETIME SELECT EXTRA **********/
|
||||
$this->addElement($criteria);
|
||||
|
||||
$criteriaExtraDatetimeSelect = new Zend_Form_Element_Select("sp_criteria_extra_datetime_select_".$i."_".$j);
|
||||
$criteriaExtraDatetimeSelect->setAttrib('class','input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"])
|
||||
&& $modifierTest == 'between') {
|
||||
// need to remove the leading numbers stored in the database
|
||||
$extraDateTimeSelectValue = preg_replace('/[0-9]+/', '', $storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"]);
|
||||
// need to strip white from front and ago from the end to match with the value of the time unit select dropdown
|
||||
$extraDateTimeSelectValue = trim(preg_replace('/\W\w+\s*(\W*)$/', '$1', $extraDateTimeSelectValue));
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
// Logging::info('THIS IS-'.$extraDateTimeSelectValue.'-IT');
|
||||
$criteriaExtraDatetimeSelect->setValue($extraDateTimeSelectValue);
|
||||
$criteriaExtraDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
/****************** MODIFIER ***********/
|
||||
// every element has an optional modifier dropdown select
|
||||
|
||||
} else {
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions(array('0' => _('Select unit of time')));
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
$criteriaExtraDatetimeSelect->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
$this->addElement($criteriaExtraDatetimeSelect);
|
||||
}//for
|
||||
$criteriaModifers = new Zend_Form_Element_Select("sp_criteria_modifier_" . $i . "_" . $j);
|
||||
$criteriaModifers->setValue('Select modifier')
|
||||
->setAttrib('class', 'input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteriaModifers->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
// determine the modifier based upon criteria type which is looked up based upon an array
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
if ($criteriaType == "s") {
|
||||
$criteriaModifers->setMultiOptions($this->getStringCriteriaOptions());
|
||||
} elseif ($criteriaType == "d") {
|
||||
$criteriaModifers->setMultiOptions($this->getDateTimeCriteriaOptions());
|
||||
} elseif ($criteriaType == "tt") {
|
||||
$criteriaModifers->setMultiOptions($this->getIsNotOptions());
|
||||
} else {
|
||||
$criteriaModifers->setMultiOptions($this->getNumericCriteriaOptions());
|
||||
}
|
||||
$criteriaModifers->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["modifier"]);
|
||||
} else {
|
||||
$criteriaModifers->setMultiOptions(array('0' => _('Select modifier')));
|
||||
}
|
||||
$this->addElement($criteriaModifers);
|
||||
|
||||
/****************** VALUE ***********/
|
||||
/* The challenge here is that datetime */
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
$modifierTest = (string)$storedCrit["crit"][$criteriaKeys[$i]][$j]["modifier"];
|
||||
if (isset($criteriaType) && $criteriaType == "tt" &&
|
||||
preg_match('/is|is not/', $modifierTest) == 1) {
|
||||
|
||||
$criteriaValue = new Zend_Form_Element_Select("sp_criteria_value_" . $i . "_" . $j);
|
||||
$criteriaValue->setAttrib('class', 'input_select sp_input_select')->setDecorators(array('viewHelper'));
|
||||
|
||||
if (isset($criteriaKeys[$i]) ) { //do if $relativeTT above
|
||||
$criteriaValue->setAttrib('enabled', 'enabled');
|
||||
} else {
|
||||
$criteriaValue->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
} else {
|
||||
$criteriaValue = new Zend_Form_Element_Text("sp_criteria_value_" . $i . "_" . $j);
|
||||
$criteriaValue->setAttrib('class', 'input_text sp_input_text')->setDecorators(array('viewHelper'));
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteriaValue->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
$criteriaValue = new Zend_Form_Element_Text("sp_criteria_value_" . $i . "_" . $j);
|
||||
$criteriaValue->setAttrib('class', 'input_text sp_input_text')->setDecorators(array('viewHelper'));
|
||||
if ($i != 0 && !isset($criteriaKeys[$i])) {
|
||||
$criteriaValue->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
if (isset($criteriaKeys[$i])) {
|
||||
/*
|
||||
* Need to parse relative dates in a special way to populate select box down below
|
||||
*/
|
||||
// this is used below to test whether the datetime select should be shown or hidden
|
||||
$relativeDateTime = false;
|
||||
$modifierTest = (string)$storedCrit["crit"][$criteriaKeys[$i]][$j]["modifier"];
|
||||
if (isset($criteriaType) && $criteriaType == "d" &&
|
||||
preg_match('/before|after|between/', $modifierTest) == 1) {
|
||||
// set relativeDatetime boolean to true so that the datetime select is displayed below
|
||||
$relativeDateTime = true;
|
||||
$criteriaValue->setValue(filter_var($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"], FILTER_SANITIZE_NUMBER_INT));
|
||||
} elseif (isset($criteriaType) && $criteriaType == "tt" &&
|
||||
preg_match('/is|is not/', $modifierTest) == 1) {
|
||||
// set relativeDatetime boolean to true so that the datetime select is displayed below
|
||||
$relativeDateTime = false;
|
||||
|
||||
$tracktypeSelectValue = preg_replace('/[0-9]+/', '', $storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
$tracktypeSelectValue = trim(preg_replace('/\W\w+\s*(\W*)$/', '$1', $tracktypeSelectValue));
|
||||
$criteriaValue->setMultiOptions($this->getTracktypeOptions());
|
||||
|
||||
if ($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]){
|
||||
$criteriaValue->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
} else {
|
||||
$criteriaValue->setMultiOptions(array('0' => _('Select track type')));
|
||||
$criteriaValue->setMultiOptions($this->getTracktypeOptions());
|
||||
$criteriaValue->setValue($tracktypeSelectValue);
|
||||
}
|
||||
$criteriaValue->setAttrib('enabled', 'enabled');
|
||||
} else {
|
||||
$criteriaValue->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
}
|
||||
}
|
||||
$this->addElement($criteriaValue);
|
||||
|
||||
|
||||
/****************** DATETIME SELECT *************/
|
||||
$criteriaDatetimeSelect = new Zend_Form_Element_Select("sp_criteria_datetime_select_" . $i . "_" . $j);
|
||||
$criteriaDatetimeSelect->setAttrib('class', 'input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if (isset($criteriaKeys[$i]) && $relativeDateTime) {
|
||||
$criteriaDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
} else {
|
||||
$criteriaDatetimeSelect->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
// check if the value is stored and it is a relative datetime field
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["value"])
|
||||
&& isset($criteriaType) && $criteriaType == "d" &&
|
||||
preg_match('/before|after|between/', $modifierTest) == 1) {
|
||||
// need to remove any leading numbers stored in the database
|
||||
$dateTimeSelectValue = preg_replace('/[0-9]+/', '', $storedCrit["crit"][$criteriaKeys[$i]][$j]["value"]);
|
||||
// need to strip white from front and ago from the end to match with the value of the time unit select dropdown
|
||||
$dateTimeSelectValue = trim(preg_replace('/\W\w+\s*(\W*)$/', '$1', $dateTimeSelectValue));
|
||||
$criteriaDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
$criteriaDatetimeSelect->setValue($dateTimeSelectValue);
|
||||
$criteriaDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
} else {
|
||||
$criteriaDatetimeSelect->setMultiOptions(array('0' => _('Select unit of time')));
|
||||
$criteriaDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
|
||||
}
|
||||
|
||||
$this->addElement($criteriaDatetimeSelect);
|
||||
|
||||
/****************** EXTRA ***********/
|
||||
$criteriaExtra = new Zend_Form_Element_Text("sp_criteria_extra_" . $i . "_" . $j);
|
||||
$criteriaExtra->setAttrib('class', 'input_text sp_extra_input_text')
|
||||
->setDecorators(array('viewHelper'));
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"])) {
|
||||
// need to check if this is a relative date time value
|
||||
if (isset($criteriaType) && $criteriaType == "d" && $modifierTest == 'between') {
|
||||
// the criteria value will be a number followed by time unit and ago so set input to number part
|
||||
$criteriaExtra->setValue(filter_var($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"], FILTER_SANITIZE_NUMBER_INT));
|
||||
} else {
|
||||
$criteriaExtra->setValue($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"]);
|
||||
}
|
||||
$criteriaValue->setAttrib('class', 'input_text sp_extra_input_text');
|
||||
} else {
|
||||
$criteriaExtra->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
$this->addElement($criteriaExtra);
|
||||
/****************** DATETIME SELECT EXTRA **********/
|
||||
|
||||
$criteriaExtraDatetimeSelect = new Zend_Form_Element_Select("sp_criteria_extra_datetime_select_" . $i . "_" . $j);
|
||||
$criteriaExtraDatetimeSelect->setAttrib('class', 'input_select sp_input_select')
|
||||
->setDecorators(array('viewHelper'));
|
||||
|
||||
if (isset($criteriaKeys[$i]) && isset($storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"])
|
||||
&& $modifierTest == 'between') {
|
||||
// need to remove the leading numbers stored in the database
|
||||
$extraDateTimeSelectValue = preg_replace('/[0-9]+/', '', $storedCrit["crit"][$criteriaKeys[$i]][$j]["extra"]);
|
||||
// need to strip white from front and ago from the end to match with the value of the time unit select dropdown
|
||||
$extraDateTimeSelectValue = trim(preg_replace('/\W\w+\s*(\W*)$/', '$1', $extraDateTimeSelectValue));
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
// Logging::info('THIS IS-'.$extraDateTimeSelectValue.'-IT');
|
||||
$criteriaExtraDatetimeSelect->setValue($extraDateTimeSelectValue);
|
||||
$criteriaExtraDatetimeSelect->setAttrib('enabled', 'enabled');
|
||||
|
||||
} else {
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions(array('0' => _('Select unit of time')));
|
||||
$criteriaExtraDatetimeSelect->setMultiOptions($this->getTimePeriodCriteriaOptions());
|
||||
$criteriaExtraDatetimeSelect->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
$this->addElement($criteriaExtraDatetimeSelect);
|
||||
}//for
|
||||
}//for
|
||||
|
||||
$repeatTracks = new Zend_Form_Element_Checkbox('sp_repeat_tracks');
|
||||
|
@ -446,6 +520,14 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
}
|
||||
$this->addElement($repeatTracks);
|
||||
|
||||
$overflowTracks = new Zend_Form_Element_Checkbox('sp_overflow_tracks');
|
||||
$overflowTracks->setDecorators(array('viewHelper'))
|
||||
->setLabel(_('Allow last track to exceed time limit:'));
|
||||
if (isset($storedCrit["overflow_tracks"])) {
|
||||
$overflowTracks->setChecked($storedCrit["overflow_tracks"]["value"] == 1);
|
||||
}
|
||||
$this->addElement($overflowTracks);
|
||||
|
||||
$sort = new Zend_Form_Element_Select('sp_sort_options');
|
||||
$sort->setAttrib('class', 'sp_input_select')
|
||||
->setDecorators(array('viewHelper'))
|
||||
|
@ -455,7 +537,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$sort->setValue($storedCrit["sort"]["value"]);
|
||||
}
|
||||
$this->addElement($sort);
|
||||
|
||||
|
||||
$limit = new Zend_Form_Element_Select('sp_limit_options');
|
||||
$limit->setAttrib('class', 'sp_input_select')
|
||||
->setDecorators(array('viewHelper'))
|
||||
|
@ -477,25 +559,16 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$limitValue->setValue(1);
|
||||
}
|
||||
|
||||
//getting block content candidate count that meets criteria
|
||||
$bl = new Application_Model_Block($p_blockId);
|
||||
if ($p_isValid) {
|
||||
$files = $bl->getListofFilesMeetCriteria();
|
||||
$showPoolCount = true;
|
||||
} else {
|
||||
$files = null;
|
||||
$showPoolCount = false;
|
||||
}
|
||||
|
||||
$generate = new Zend_Form_Element_Button('generate_button');
|
||||
$generate->setAttrib('class', 'sp-button btn');
|
||||
$generate->setAttrib('title', _('Generate playlist content and save criteria'));
|
||||
$generate->setIgnore(true);
|
||||
if ($blockType == 0) {
|
||||
$generate->setLabel(_('Generate'));
|
||||
$generate->setLabel(_('Preview'));
|
||||
}
|
||||
else {
|
||||
$generate->setLabel(_('Preview'));
|
||||
$generate->setLabel(_('Generate'));
|
||||
}
|
||||
$generate->setDecorators(array('viewHelper'));
|
||||
$this->addElement($generate);
|
||||
|
@ -510,7 +583,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/smart-block-criteria.phtml', "openOption"=> $openSmartBlockOption,
|
||||
'criteriasLength' => count($this->getCriteriaOptions()), 'modRowMap' => $modRowMap))
|
||||
'criteriasLength' => $numElements, 'modRowMap' => $modRowMap))
|
||||
));
|
||||
}
|
||||
/*
|
||||
|
@ -523,7 +596,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
public function preValidation($params)
|
||||
{
|
||||
$data = Application_Model_Block::organizeSmartPlaylistCriteria($params['data']);
|
||||
// add elelments that needs to be added
|
||||
// add elements that needs to be added
|
||||
// set multioption for modifier according to criteria_field
|
||||
$modRowMap = array();
|
||||
if (!isset($data['criteria'])) {
|
||||
|
@ -546,6 +619,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
$eleMod->setMultiOptions($this->getNumericCriteriaOptions());
|
||||
} elseif ($criteriaType == "d") {
|
||||
$eleMod->setMultiOptions($this->getDateTimeCriteriaOptions());
|
||||
} elseif ($criteriaType == "tt") {
|
||||
$eleMod->setMultiOptions($this->getIsNotOptions());
|
||||
} else {
|
||||
$eleMod->setMultiOptions(array('0' => _('Select modifier')));
|
||||
}
|
||||
|
@ -605,6 +680,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
}
|
||||
elseif ($criteriaType == "d") {
|
||||
$criteriaModifers->setMultiOptions($this->getDateTimeCriteriaOptions());
|
||||
} elseif ($criteriaType == "tt") {
|
||||
$criteriaModifers->setMultiOptions($this->getIsNotOptions());
|
||||
} else {
|
||||
$criteriaModifers->setMultiOptions(array('0' => _('Select modifier')));
|
||||
}
|
||||
|
@ -715,7 +792,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
|
|||
"sample_rate" => "DbSampleRate",
|
||||
"track_title" => "DbTrackTitle",
|
||||
"track_number" => "DbTrackNumber",
|
||||
"year" => "DbYear"
|
||||
"year" => "DbYear",
|
||||
"track_type" => "DbTrackType"
|
||||
);
|
||||
|
||||
// things we need to check
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_SupportSettings extends Zend_Form
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$country_list = Application_Model_Preference::GetCountryList();
|
||||
$notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator();
|
||||
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/support-setting.phtml')),
|
||||
array('File', array('viewScript' => 'form/support-setting.phtml', 'placement' => false)))
|
||||
);
|
||||
|
||||
//Station name
|
||||
$this->addElement('text', 'stationName', array(
|
||||
'class' => 'input_text',
|
||||
'label' => _('Station Name'),
|
||||
'required' => true,
|
||||
'filters' => array('StringTrim'),
|
||||
'validators' => array($notEmptyValidator),
|
||||
'value' => Application_Model_Preference::GetStationName(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Phone number
|
||||
$this->addElement('text', 'Phone', array(
|
||||
'class' => 'input_text',
|
||||
'label' => _('Phone:'),
|
||||
'required' => false,
|
||||
'filters' => array('StringTrim'),
|
||||
'value' => Application_Model_Preference::GetPhone(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
//Email
|
||||
$this->addElement('text', 'Email', array(
|
||||
'class' => 'input_text',
|
||||
'label' => _('Email:'),
|
||||
'required' => false,
|
||||
'filters' => array('StringTrim'),
|
||||
'value' => Application_Model_Preference::GetEmail(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station Web Site
|
||||
$this->addElement('text', 'StationWebSite', array(
|
||||
'label' => _('Station Web Site:'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'value' => Application_Model_Preference::GetStationWebSite(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// county list dropdown
|
||||
$this->addElement('select', 'Country', array(
|
||||
'label' => _('Country:'),
|
||||
'required' => false,
|
||||
'value' => Application_Model_Preference::GetStationCountry(),
|
||||
'multiOptions' => $country_list,
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station city
|
||||
$this->addElement('text', 'City', array(
|
||||
'label' => _('City:'),
|
||||
'required' => false,
|
||||
'class' => 'input_text',
|
||||
'value' => Application_Model_Preference::GetStationCity(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// Station Description
|
||||
$description = new Zend_Form_Element_Textarea('Description');
|
||||
$description->class = 'input_text_area';
|
||||
$description->setLabel(_('Station Description:'))
|
||||
->setRequired(false)
|
||||
->setValue(Application_Model_Preference::GetStationDescription())
|
||||
->setDecorators(array('ViewHelper'))
|
||||
->setAttrib('ROWS','2')
|
||||
->setAttrib('COLS','58');
|
||||
$this->addElement($description);
|
||||
|
||||
//enable support feedback
|
||||
$this->addElement('checkbox', 'SupportFeedback', array(
|
||||
'label' => _('Send support feedback'),
|
||||
'required' => false,
|
||||
'value' => Application_Model_Preference::GetSupportFeedback(),
|
||||
'decorators' => array(
|
||||
'ViewHelper'
|
||||
)
|
||||
));
|
||||
|
||||
// checkbox for publicise
|
||||
$checkboxPublicise = new Zend_Form_Element_Checkbox("Publicise");
|
||||
$checkboxPublicise->setLabel(sprintf(_('Promote my station on %s'), COMPANY_SITE))
|
||||
->setRequired(false)
|
||||
->setDecorators(array('ViewHelper'))
|
||||
->setValue(Application_Model_Preference::GetPublicise());
|
||||
if (Application_Model_Preference::GetSupportFeedback() == '0') {
|
||||
$checkboxPublicise->setAttrib("disabled", "disabled");
|
||||
}
|
||||
$this->addElement($checkboxPublicise);
|
||||
|
||||
// checkbox for privacy policy
|
||||
$checkboxPrivacy = new Zend_Form_Element_Checkbox("Privacy");
|
||||
$checkboxPrivacy->setLabel(
|
||||
sprintf(_('By checking this box, I agree to %s\'s %sprivacy policy%s.'),
|
||||
COMPANY_NAME,
|
||||
$privacyPolicyAnchorOpen,
|
||||
"</a>"))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($checkboxPrivacy);
|
||||
|
||||
// submit button
|
||||
$submit = new Zend_Form_Element_Submit("submit");
|
||||
$submit->class = 'btn right-floated';
|
||||
$submit->setIgnore(true)
|
||||
->setLabel(_("Save"))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($submit);
|
||||
}
|
||||
|
||||
// overriding isValid function
|
||||
public function isValid ($data)
|
||||
{
|
||||
$isValid = parent::isValid($data);
|
||||
if (isset($data["Privacy"])) {
|
||||
$checkPrivacy = $this->getElement('Privacy');
|
||||
if ($data["SupportFeedback"] == "1" && $data["Privacy"] != "1") {
|
||||
$checkPrivacy->addError(_("You have to agree to privacy policy."));
|
||||
$isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $isValid;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
<title><?php echo _("Audio Player")?></title>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"><?php echo $this->layout()->content ?></div>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<title></title>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"><?php echo $this->layout()->content ?></div>
|
||||
|
|
|
@ -5,31 +5,16 @@
|
|||
<?php echo $this->headTitle() ?>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
<?php $baseUrl = Application_Common_OsPath::getBaseDir(); ?>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (LIBRETIME_ENABLE_GOOGLE_ANALYTICS === true): ?>
|
||||
<!-- Google Tag Manager -->
|
||||
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-55N6NH"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-55N6NH');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
<?php endif; ?>
|
||||
<?php echo $this->partial('partialviews/trialBox.phtml', array("is_trial"=>$this->isTrial(), "trial_remain"=> $this->trialRemaining())) ?>
|
||||
|
||||
<div id="Panel" class="sticky">
|
||||
<?php if ($this->suspended && $this->isTrial()) : ?>
|
||||
<?php echo $this->partial('partialviews/suspendedtrial.phtml'); ?>
|
||||
<?php elseif ($this->suspended && !$this->isTrial()) : ?>
|
||||
<?php echo $this->partial('partialviews/suspended.phtml'); ?>
|
||||
<?php else : ?>
|
||||
|
||||
<?php echo $this->versionNotify();
|
||||
<?php
|
||||
/*
|
||||
NOTE: Temporarily disabled version notification to avoid confusion,
|
||||
Users can check current version in Settings > Status.
|
||||
*/
|
||||
//echo $this->versionNotify();
|
||||
$sss = $this->SourceSwitchStatus();
|
||||
$scs = $this->SourceConnectionStatus();
|
||||
?>
|
||||
|
@ -51,8 +36,6 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
parseSwitchStatus(schedulePreLoaded.switch_status);
|
||||
|
||||
</script>
|
||||
|
||||
<?php endif; //suspended ?>
|
||||
</div>
|
||||
|
||||
<div id="media_type_nav"> <!-- class="content-pane" -->
|
||||
|
@ -92,7 +75,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
<div id="nav">
|
||||
<?php echo $this->navigation()->menu(); ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="btn-group">
|
||||
<a href="<?php echo $this->baseUrl . '/login/logout'; ?>">
|
||||
<button id="add_media_btn" class="btn btn-small dashboard-btn btn-danger">
|
||||
|
@ -196,18 +179,10 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
<div id="whatsnew_video">
|
||||
<iframe width="560" height="315" src="<?php echo UI_REVAMP_EMBED_URL ?>" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
<h2><?php echo _("Airtime Pro has a new look!"); ?></h2>
|
||||
<p><?php echo _("Your favorite features are now even easier to use - and we've even
|
||||
added a few new ones! Check out the video above or read on to find out more."); ?></p>
|
||||
<ul>
|
||||
<li><?php echo _("Our new Dashboard view now has a powerful tabbed editing interface, so updating your tracks and playlists
|
||||
is easier than ever."); ?></li>
|
||||
<li><?php echo _("We've streamlined the Airtime interface to make navigation easier. With the most important tools
|
||||
just a click away, you'll be on air and hands-free in no time."); ?></li>
|
||||
<li><?php echo _("Got a huge music library? No problem! With the new Upload page, you can drag and drop whole folders to our private cloud."); ?></li>
|
||||
<li><?php echo _("The new Airtime is smoother, sleeker, and faster - on even more devices! We're committed to improving the Airtime
|
||||
experience, no matter how you're connected."); ?></li>
|
||||
</ul>
|
||||
<h2><?php echo _("Welcome to LibreTime"); ?></h2>
|
||||
<p><?php echo _("LibreTime is free software for radio stations built by a community.
|
||||
You can find out more information at LibreTime.org. We are built as a fork of Airtime.
|
||||
If you have any questions you can also go to https://discourse.libretime.org and ask them."); ?></p>
|
||||
</div>
|
||||
<button id="whatsnew_close" class="btn btn-new">OK, got it!</button>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<title><?php echo _("Live stream") ?></title>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"><?php echo $this->layout()->content ?></div>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<?php echo $this->headTitle() ?>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class SentryLogger
|
|||
//FIXME: This doesn't seem to be working...
|
||||
'processorOptions' => array(
|
||||
'Raven_SanitizeDataProcessor' => array(
|
||||
'fields_re' => '/(authorization|password|passwd|user_token|secret|WHMCS_|SESSION)/i',
|
||||
'fields_re' => '/(authorization|password|passwd|user_token|secret|SESSION)/i',
|
||||
'values_re' => '/^(?:\d[ -]*?){13,16}$/'
|
||||
)
|
||||
)
|
||||
|
@ -128,4 +128,4 @@ class SentryLogger
|
|||
return $extraData;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ class Application_Model_Block implements Application_Model_LibraryEditable
|
|||
"sample_rate" => "DbSampleRate",
|
||||
"track_title" => "DbTrackTitle",
|
||||
"track_number" => "DbTrackNumber",
|
||||
"year" => "DbYear"
|
||||
"year" => "DbYear",
|
||||
"track_type" => "DbTrackType"
|
||||
);
|
||||
|
||||
public function __construct($id=null, $con=null)
|
||||
|
@ -232,12 +233,12 @@ SQL;
|
|||
foreach ($rows as &$row) {
|
||||
|
||||
$clipSec = Application_Common_DateHelper::playlistTimeToSeconds($row['length']);
|
||||
|
||||
|
||||
$row['trackSec'] = $clipSec;
|
||||
|
||||
|
||||
$row['cueInSec'] = Application_Common_DateHelper::playlistTimeToSeconds($row['cuein']);
|
||||
$row['cueOutSec'] = Application_Common_DateHelper::playlistTimeToSeconds($row['cueout']);
|
||||
|
||||
|
||||
$trackoffset = $row['trackoffset'];
|
||||
$offset += $clipSec;
|
||||
$offset -= $trackoffset;
|
||||
|
@ -254,7 +255,7 @@ SQL;
|
|||
$fades = $this->getFadeInfo($row['position']);
|
||||
$row['fadein'] = $fades[0];
|
||||
$row['fadeout'] = $fades[1];
|
||||
|
||||
|
||||
// format the cues in format 00:00:00(.0)
|
||||
// we need to add the '.0' for cues and not fades
|
||||
// because propel takes care of this for us
|
||||
|
@ -361,10 +362,12 @@ SQL;
|
|||
{
|
||||
$result = CcBlockcriteriaQuery::create()->filterByDbBlockId($this->id)
|
||||
->filterByDbCriteria('limit')->findOne();
|
||||
$modifier = $result->getDbModifier();
|
||||
$value = $result->getDbValue();
|
||||
if ($result) {
|
||||
$modifier = $result->getDbModifier();
|
||||
$value = $result->getDbValue();
|
||||
return array($value, $modifier);
|
||||
}
|
||||
|
||||
return array($value, $modifier);
|
||||
}
|
||||
|
||||
// this function returns sum of all track length under this block.
|
||||
|
@ -486,7 +489,7 @@ SQL;
|
|||
Logging::info("Adding to block");
|
||||
Logging::info("at position {$pos}");
|
||||
}
|
||||
|
||||
|
||||
foreach ($p_items as $ac) {
|
||||
//Logging::info("Adding audio file {$ac[0]}");
|
||||
try {
|
||||
|
@ -675,7 +678,7 @@ SQL;
|
|||
|
||||
return array($fadeIn, $fadeOut);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* create a crossfade from item in cc_playlist_contents with $id1 to item $id2.
|
||||
*
|
||||
|
@ -686,11 +689,11 @@ SQL;
|
|||
public function createCrossfade($id1, $fadeOut, $id2, $fadeIn, $offset)
|
||||
{
|
||||
$this->con->beginTransaction();
|
||||
|
||||
|
||||
if (!isset($offset)) {
|
||||
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if (isset($id1)) {
|
||||
$this->changeFadeInfo($id1, null, $fadeOut);
|
||||
|
@ -698,9 +701,9 @@ SQL;
|
|||
if (isset($id2)) {
|
||||
$this->changeFadeInfo($id2, $fadeIn, null, $offset);
|
||||
}
|
||||
|
||||
|
||||
$this->con->commit();
|
||||
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->con->rollback();
|
||||
throw $e;
|
||||
|
@ -744,20 +747,20 @@ SQL;
|
|||
':fade_in' => $fadeIn,
|
||||
':clip_length' => $clipLength
|
||||
);
|
||||
|
||||
|
||||
$result = Application_Common_Database::prepareAndExecute($sql, $params, 'column');
|
||||
if ($result) {
|
||||
//"Fade In can't be larger than overall playlength.";
|
||||
$fadeIn = $clipLength;
|
||||
}
|
||||
$row->setDbFadein($fadeIn);
|
||||
|
||||
|
||||
if (!is_null($offset)) {
|
||||
$row->setDbTrackOffset($offset);
|
||||
Logging::info("Setting offset {$offset} on item {$id}");
|
||||
$row->save($this->con);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (!is_null($fadeOut)) {
|
||||
|
||||
|
@ -766,7 +769,7 @@ SQL;
|
|||
':fade_out' => $fadeOut,
|
||||
':clip_length' => $clipLength
|
||||
);
|
||||
|
||||
|
||||
$result = Application_Common_Database::prepareAndExecute($sql, $params, 'column');
|
||||
if ($result) {
|
||||
//"Fade Out can't be larger than overall playlength.";
|
||||
|
@ -907,7 +910,7 @@ SQL;
|
|||
|
||||
$row->setDbCuein($cueIn);
|
||||
$row->setDBCliplength($cliplength);
|
||||
|
||||
|
||||
} elseif (!is_null($cueOut)) {
|
||||
|
||||
if ($cueOut === "") {
|
||||
|
@ -1014,8 +1017,8 @@ SQL;
|
|||
public static function getBlockCount()
|
||||
{
|
||||
$sql = 'SELECT count(*) as cnt FROM cc_playlist';
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(),
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(),
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
return $res;
|
||||
|
@ -1062,7 +1065,7 @@ SQL;
|
|||
CcBlockQuery::create()->findPKs($p_ids)->delete();
|
||||
$updateIsPlaylistFlag = true;
|
||||
}
|
||||
|
||||
|
||||
if ($updateIsPlaylistFlag) {
|
||||
// update is_playlist flag in cc_files
|
||||
Application_Model_StoredFile::setIsPlaylist(
|
||||
|
@ -1158,10 +1161,10 @@ SQL;
|
|||
{
|
||||
$data = $this->organizeSmartPlaylistCriteria($p_criteria);
|
||||
// saving dynamic/static flag
|
||||
$blockType = $data['etc']['sp_type'] == 0 ? 'static':'dynamic';
|
||||
$blockType = $data['etc']['sp_type'] == 0 ? 'dynamic':'static';
|
||||
$this->saveType($blockType);
|
||||
$this->storeCriteriaIntoDb($data);
|
||||
|
||||
|
||||
// if the block is dynamic, put null to the length
|
||||
// as it cannot be calculated
|
||||
if ($blockType == 'dynamic') {
|
||||
|
@ -1196,15 +1199,17 @@ SQL;
|
|||
if (isset($p_criteriaData['criteria'])) {
|
||||
$critKeys = array_keys($p_criteriaData['criteria']);
|
||||
for ($i = 0; $i < count($critKeys); $i++) {
|
||||
// in order to maintain separation of different criteria to preserve AND statements for criteria
|
||||
// that might contradict itself we group them based upon their original position on the form
|
||||
$criteriaGroup = $i;
|
||||
foreach ($p_criteriaData['criteria'][$critKeys[$i]] as $d) {
|
||||
// Logging::info($d);
|
||||
$field = $d['sp_criteria_field'];
|
||||
$value = $d['sp_criteria_value'];
|
||||
$modifier = $d['sp_criteria_modifier'];
|
||||
if (isset($d['sp_criteria_extra'])) { $extra = $d['sp_criteria_extra']; }
|
||||
if (isset($d['sp_criteria_datetime_select'])) { $datetimeunit = $d['sp_criteria_datetime_select']; }
|
||||
if (isset($d['sp_criteria_extra_datetime_select'])) {$extradatetimeunit = $d['sp_criteria_extra_datetime_select'];}
|
||||
|
||||
|
||||
if ($field == 'utime' || $field == 'mtime' || $field == 'lptime') {
|
||||
// if the date isn't relative we want to convert the value to a specific UTC date
|
||||
if (!(in_array($modifier,array('before','after','between')))) {
|
||||
|
@ -1216,7 +1221,7 @@ SQL;
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$qry = new CcBlockcriteria();
|
||||
$qry->setDbCriteria($field)
|
||||
->setDbModifier($d['sp_criteria_modifier'])
|
||||
|
@ -1224,7 +1229,7 @@ SQL;
|
|||
->setDbBlockId($this->id);
|
||||
|
||||
if (isset($d['sp_criteria_extra'])) {
|
||||
|
||||
|
||||
if ($field == 'utime' || $field == 'mtime' || $field == 'lptime') {
|
||||
// if the date isn't relative we want to convert the value to a specific UTC date
|
||||
if (!(in_array($modifier,array('before','after','between')))) {
|
||||
|
@ -1235,9 +1240,14 @@ SQL;
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$qry->setDbExtra($extra);
|
||||
}
|
||||
// save the criteria group so separation via new modifiers AND can be preserved vs. lumping
|
||||
// them all into a single or later on
|
||||
if (isset($criteriaGroup)) {
|
||||
$qry->setDbCriteriaGroup($criteriaGroup);
|
||||
}
|
||||
$qry->save();
|
||||
}
|
||||
}
|
||||
|
@ -1260,15 +1270,24 @@ SQL;
|
|||
->setDbValue($p_criteriaData['etc']['sp_limit_value'])
|
||||
->setDbBlockId($this->id)
|
||||
->save();
|
||||
|
||||
|
||||
// insert repeate track option
|
||||
|
||||
|
||||
// insert repeat track option
|
||||
$qry = new CcBlockcriteria();
|
||||
$qry->setDbCriteria("repeat_tracks")
|
||||
->setDbModifier("N/A")
|
||||
->setDbValue($p_criteriaData['etc']['sp_repeat_tracks'])
|
||||
->setDbBlockId($this->id)
|
||||
->save();
|
||||
|
||||
// insert overflow track option
|
||||
$qry = new CcBlockcriteria();
|
||||
$qry->setDbCriteria("overflow_tracks")
|
||||
->setDbModifier("N/A")
|
||||
->setDbValue($p_criteriaData['etc']['sp_overflow_tracks'])
|
||||
->setDbBlockId($this->id)
|
||||
->save();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1310,12 +1329,17 @@ SQL;
|
|||
}
|
||||
}
|
||||
|
||||
public function getListOfFilesUnderLimit()
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
public function getListOfFilesUnderLimit($show = null)
|
||||
{
|
||||
$info = $this->getListofFilesMeetCriteria();
|
||||
$info = $this->getListofFilesMeetCriteria($show);
|
||||
$files = $info['files'];
|
||||
$limit = $info['limit'];
|
||||
$repeat = $info['repeat_tracks'];
|
||||
$overflow = $info['overflow_tracks'];
|
||||
|
||||
$insertList = array();
|
||||
$totalTime = 0;
|
||||
|
@ -1324,25 +1348,35 @@ SQL;
|
|||
// this moves the pointer to the first element in the collection
|
||||
$files->getFirst();
|
||||
$iterator = $files->getIterator();
|
||||
|
||||
|
||||
$isBlockFull = false;
|
||||
|
||||
|
||||
while ($iterator->valid()) {
|
||||
|
||||
|
||||
$id = $iterator->current()->getDbId();
|
||||
$fileLength = $iterator->current()->getCueLength();
|
||||
$length = Application_Common_DateHelper::calculateLengthInSeconds($fileLength);
|
||||
// need to check to determine if the track will make the playlist exceed the totalTime before adding it
|
||||
// this can be quite processor consuming so as a workaround I used the totalItems limit to prevent the
|
||||
// algorithm from parsing too many items.
|
||||
$projectedTime = $totalTime + $length;
|
||||
if ($projectedTime > $limit['time']) {
|
||||
$totalItems++;
|
||||
}
|
||||
else {
|
||||
// if the block is setup to allow the overflow of tracks this will add the next track even if it becomes
|
||||
// longer than the time limit
|
||||
if ($overflow == 1) {
|
||||
$insertList[] = array('id' => $id, 'length' => $length);
|
||||
$totalTime += $length;
|
||||
$totalItems++;
|
||||
}
|
||||
// otherwise we need to check to determine if the track will make the playlist exceed the totalTime before
|
||||
// adding it this could loop through a lot of tracks so I used the totalItems limit to prevent
|
||||
// the algorithm from parsing too many items.
|
||||
|
||||
else {
|
||||
$projectedTime = $totalTime + $length;
|
||||
if ($projectedTime > $limit['time']) {
|
||||
$totalItems++;
|
||||
}
|
||||
else {
|
||||
$insertList[] = array('id' => $id, 'length' => $length);
|
||||
$totalTime += $length;
|
||||
$totalItems++;
|
||||
}
|
||||
}
|
||||
if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) {
|
||||
$isBlockFull = true;
|
||||
|
@ -1351,19 +1385,35 @@ SQL;
|
|||
|
||||
$iterator->next();
|
||||
}
|
||||
|
||||
|
||||
$sizeOfInsert = count($insertList);
|
||||
|
||||
|
||||
// if block is not full and repeat_track is check, fill up more
|
||||
// additionally still don't overflow the limit
|
||||
while (!$isBlockFull && $repeat == 1 && $sizeOfInsert > 0) {
|
||||
Logging::debug("adding repeated tracks.");
|
||||
Logging::debug("total time = " . $totalTime);
|
||||
|
||||
|
||||
$randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert));
|
||||
$insertList[] = $insertList[$randomEleKey];
|
||||
$totalTime += $insertList[$randomEleKey]['length'];
|
||||
$totalItems++;
|
||||
|
||||
// this will also allow the overflow of tracks so that time limited smart blocks will schedule until they
|
||||
// are longer than the time limit rather than never scheduling past the time limit
|
||||
if ($overflow == 1) {
|
||||
$insertList[] = $insertList[$randomEleKey];
|
||||
$totalTime += $insertList[$randomEleKey]['length'];
|
||||
$totalItems++;
|
||||
}
|
||||
else {
|
||||
$projectedTime = $totalTime + $insertList[$randomEleKey]['length'];
|
||||
if ($projectedTime > $limit['time']) {
|
||||
$totalItems++;
|
||||
}
|
||||
else {
|
||||
$insertList[] = $insertList[$randomEleKey];
|
||||
$totalTime += $insertList[$randomEleKey]['length'];
|
||||
$totalItems++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) {
|
||||
break;
|
||||
}
|
||||
|
@ -1402,6 +1452,7 @@ SQL;
|
|||
"mtime" => _("Last Modified"),
|
||||
"lptime" => _("Last Played"),
|
||||
"length" => _("Length"),
|
||||
"track_type" => _("Track Type"),
|
||||
"mime" => _("Mime"),
|
||||
"mood" => _("Mood"),
|
||||
"owner_id" => _("Owner"),
|
||||
|
@ -1439,8 +1490,9 @@ SQL;
|
|||
foreach ($out as $crit) {
|
||||
$criteria = $crit->getDbCriteria();
|
||||
$modifier = $crit->getDbModifier();
|
||||
$value = htmlspecialchars($crit->getDbValue());
|
||||
$value = $crit->getDbValue();
|
||||
$extra = $crit->getDbExtra();
|
||||
$criteriagroup = $crit->getDbCriteriaGroup();
|
||||
|
||||
if ($criteria == "limit") {
|
||||
$storedCrit["limit"] = array(
|
||||
|
@ -1449,6 +1501,8 @@ SQL;
|
|||
"display_modifier"=>_($modifier));
|
||||
} else if($criteria == "repeat_tracks") {
|
||||
$storedCrit["repeat_tracks"] = array("value"=>$value);
|
||||
} else if($criteria == "overflow_tracks") {
|
||||
$storedCrit["overflow_tracks"] = array("value"=>$value);
|
||||
} else if($criteria == "sort") {
|
||||
$storedCrit["sort"] = array("value"=>$value);
|
||||
} else {
|
||||
|
@ -1457,6 +1511,7 @@ SQL;
|
|||
"value"=>$value,
|
||||
"modifier"=>$modifier,
|
||||
"extra"=>$extra,
|
||||
"criteria_group"=>$criteriagroup,
|
||||
"display_name"=>$criteriaOptions[$criteria],
|
||||
"display_modifier"=>$modifierOptions[$modifier]);
|
||||
}
|
||||
|
@ -1466,18 +1521,126 @@ SQL;
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses each row in the database for the criteria associated with this block and renders human readable labels.
|
||||
* Returns it as an array with each criteria_name and modifier_name added based upon options array lookup.
|
||||
* Maintains original separation of similar criteria that were separated by and statements
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public function getCriteriaGrouped()
|
||||
{
|
||||
$criteriaOptions = array(
|
||||
0 => _("Select criteria"),
|
||||
"album_title" => _("Album"),
|
||||
"bit_rate" => _("Bit Rate (Kbps)"),
|
||||
"bpm" => _("BPM"),
|
||||
"composer" => _("Composer"),
|
||||
"conductor" => _("Conductor"),
|
||||
"copyright" => _("Copyright"),
|
||||
"cuein" => _("Cue In"),
|
||||
"cueout" => _("Cue Out"),
|
||||
"description" => _("Description"),
|
||||
"artist_name" => _("Creator"),
|
||||
"encoded_by" => _("Encoded By"),
|
||||
"genre" => _("Genre"),
|
||||
"isrc_number" => _("ISRC"),
|
||||
"label" => _("Label"),
|
||||
"language" => _("Language"),
|
||||
"utime" => _("Upload Time"),
|
||||
"mtime" => _("Last Modified"),
|
||||
"lptime" => _("Last Played"),
|
||||
"length" => _("Length"),
|
||||
"track_type" => _("Track Type"),
|
||||
"mime" => _("Mime"),
|
||||
"mood" => _("Mood"),
|
||||
"owner_id" => _("Owner"),
|
||||
"replay_gain" => _("Replay Gain"),
|
||||
"sample_rate" => _("Sample Rate (kHz)"),
|
||||
"track_title" => _("Title"),
|
||||
"track_number" => _("Track Number"),
|
||||
"utime" => _("Uploaded"),
|
||||
"info_url" => _("Website"),
|
||||
"year" => _("Year")
|
||||
);
|
||||
|
||||
$modifierOptions = array(
|
||||
"0" => _("Select modifier"),
|
||||
"contains" => _("contains"),
|
||||
"does not contain" => _("does not contain"),
|
||||
"is" => _("is"),
|
||||
"is not" => _("is not"),
|
||||
"starts with" => _("starts with"),
|
||||
"ends with" => _("ends with"),
|
||||
"before" => _("before"),
|
||||
"after" => _("after"),
|
||||
"between" => _("between"),
|
||||
"is" => _("is"),
|
||||
"is not" => _("is not"),
|
||||
"is greater than" => _("is greater than"),
|
||||
"is less than" => _("is less than"),
|
||||
"is in the range" => _("is in the range")
|
||||
);
|
||||
|
||||
// Load criteria from db
|
||||
$out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id);
|
||||
$storedCrit = array();
|
||||
|
||||
foreach ($out as $crit) {
|
||||
$criteria = $crit->getDbCriteria();
|
||||
$modifier = $crit->getDbModifier();
|
||||
$value = $crit->getDbValue();
|
||||
$extra = $crit->getDbExtra();
|
||||
$criteriagroup = $crit->getDbCriteriaGroup();
|
||||
|
||||
if ($criteria == "limit") {
|
||||
$storedCrit["limit"] = array(
|
||||
"value"=>$value,
|
||||
"modifier"=>$modifier,
|
||||
"display_modifier"=>_($modifier));
|
||||
} else if($criteria == "repeat_tracks") {
|
||||
$storedCrit["repeat_tracks"] = array("value"=>$value);
|
||||
} else if($criteria == "overflow_tracks") {
|
||||
$storedCrit["overflow_tracks"] = array("value"=>$value);
|
||||
} else if($criteria == "sort") {
|
||||
$storedCrit["sort"] = array("value"=>$value);
|
||||
} else {
|
||||
$storedCrit["crit"][$criteria . $criteriagroup][] = array(
|
||||
"criteria"=>$criteria,
|
||||
"value"=>$value,
|
||||
"modifier"=>$modifier,
|
||||
"extra"=>$extra,
|
||||
"display_name"=>$criteriaOptions[$criteria],
|
||||
"display_modifier"=>$modifierOptions[$modifier]);
|
||||
}
|
||||
}
|
||||
return $storedCrit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// this function return list of propel object
|
||||
public function getListofFilesMeetCriteria()
|
||||
public function getListofFilesMeetCriteria($showLimit = null)
|
||||
{
|
||||
$storedCrit = $this->getCriteria();
|
||||
|
||||
$qry = CcFilesQuery::create();
|
||||
$qry->useFkOwnerQuery("subj", "left join");
|
||||
|
||||
//Logging::info($storedCrit);
|
||||
if (isset($storedCrit["crit"])) {
|
||||
foreach ($storedCrit["crit"] as $crit) {
|
||||
$i = 0;
|
||||
$prevgroup = null;
|
||||
$group = null;
|
||||
// now we need to sort based upon extra which contains the and grouping from the form
|
||||
usort($crit, function($a, $b) {
|
||||
return $a['criteria_group'] - $b['criteria_group'];
|
||||
});
|
||||
// we need to run the following loop separately for each criteria group inside of each array
|
||||
foreach ($crit as $criteria) {
|
||||
$group = $criteria['criteria_group'];
|
||||
$spCriteria = $criteria['criteria'];
|
||||
$spCriteriaModifier = $criteria['modifier'];
|
||||
|
||||
|
@ -1494,9 +1657,9 @@ SQL;
|
|||
} elseif ($spCriteria == "bit_rate" || $spCriteria == 'sample_rate') {
|
||||
// multiply 1000 because we store only number value
|
||||
// e.g 192kps is stored as 192000
|
||||
$spCriteriaValue = $criteria['value']*1000;
|
||||
$spCriteriaValue = $criteria['value'] * 1000;
|
||||
if (isset($criteria['extra'])) {
|
||||
$spCriteriaExtra = $criteria['extra']*1000;
|
||||
$spCriteriaExtra = $criteria['extra'] * 1000;
|
||||
}
|
||||
/*
|
||||
* If user is searching for an exact match of length we need to
|
||||
|
@ -1520,7 +1683,6 @@ SQL;
|
|||
} else {
|
||||
$spCriteriaValue = ($criteria['value']);
|
||||
}
|
||||
|
||||
$spCriteriaExtra = $criteria['extra'];
|
||||
}
|
||||
|
||||
|
@ -1555,25 +1717,33 @@ SQL;
|
|||
// Logging::info($tdt);
|
||||
$spCriteriaValue = "$spCriteria >= '$fdt' AND $spCriteria <= '$tdt'";
|
||||
}
|
||||
// logging::info('before');
|
||||
// logging::info($spCriteriaModifier);
|
||||
|
||||
$spCriteriaModifier = self::$modifier2CriteriaMap[$spCriteriaModifier];
|
||||
|
||||
// logging::info('after');
|
||||
// logging::info($spCriteriaModifier);
|
||||
|
||||
try {
|
||||
if ($spCriteria == "owner_id") {
|
||||
$spCriteria = "subj.login";
|
||||
}
|
||||
if ($i > 0) {
|
||||
if ($i > 0 && $prevgroup == $group) {
|
||||
$qry->addOr($spCriteria, $spCriteriaValue, $spCriteriaModifier);
|
||||
} else {
|
||||
$qry->add($spCriteria, $spCriteriaValue, $spCriteriaModifier);
|
||||
$qry->addAnd($spCriteria, $spCriteriaValue, $spCriteriaModifier);
|
||||
}
|
||||
|
||||
// only add this NOT LIKE null if you aren't also matching on another criteria
|
||||
if ($i == 0) {
|
||||
if ($spCriteriaModifier == Criteria::NOT_ILIKE || $spCriteriaModifier == Criteria::NOT_EQUAL) {
|
||||
$qry->addOr($spCriteria, null, Criteria::ISNULL);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Logging::info($e);
|
||||
}
|
||||
$prevgroup = $group;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
@ -1582,6 +1752,7 @@ SQL;
|
|||
// check if file exists
|
||||
$qry->add("file_exists", "true", Criteria::EQUAL);
|
||||
$qry->add("hidden", "false", Criteria::EQUAL);
|
||||
|
||||
$sortTracks = 'random';
|
||||
if (isset($storedCrit['sort'])) {
|
||||
$sortTracks = $storedCrit['sort']['value'];
|
||||
|
@ -1592,6 +1763,13 @@ SQL;
|
|||
else if ($sortTracks == 'oldest') {
|
||||
$qry->addAscendingOrderByColumn('utime');
|
||||
}
|
||||
// these sort additions are needed to override the default postgres NULL sort behavior
|
||||
else if ($sortTracks == 'mostrecentplay') {
|
||||
$qry->addDescendingOrderByColumn('(lptime IS NULL), lptime');
|
||||
}
|
||||
else if ($sortTracks == 'leastrecentplay') {
|
||||
$qry->addAscendingOrderByColumn('(lptime IS NOT NULL), lptime');
|
||||
}
|
||||
else if ($sortTracks == 'random') {
|
||||
$qry->addAscendingOrderByColumn('random()');
|
||||
} else {
|
||||
|
@ -1600,11 +1778,20 @@ SQL;
|
|||
|
||||
// construct limit restriction
|
||||
$limits = array();
|
||||
|
||||
if (isset($storedCrit['limit'])) {
|
||||
if ($storedCrit['limit']['modifier'] == "items") {
|
||||
$limits['time'] = 1440 * 60;
|
||||
$limits['items'] = $storedCrit['limit']['value'];
|
||||
} elseif (($storedCrit['limit']['modifier'] == "remaining") ){
|
||||
// show will be null unless being called inside a show instance
|
||||
if (!(is_null($showLimit))) {
|
||||
$limits['time'] = $showLimit;
|
||||
$limits['items'] = null;
|
||||
}
|
||||
else {
|
||||
$limits['time'] = 60 * 60;
|
||||
$limits['items'] = null;
|
||||
}
|
||||
} else {
|
||||
$limits['time'] = $storedCrit['limit']['modifier'] == "hours" ?
|
||||
intval(floatval($storedCrit['limit']['value']) * 60 * 60) :
|
||||
|
@ -1612,22 +1799,29 @@ SQL;
|
|||
$limits['items'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$repeatTracks = 0;
|
||||
$overflowTracks = 0;
|
||||
|
||||
if (isset($storedCrit['repeat_tracks'])) {
|
||||
$repeatTracks = $storedCrit['repeat_tracks']['value'];
|
||||
}
|
||||
|
||||
|
||||
if (isset($storedCrit['overflow_tracks'])) {
|
||||
$overflowTracks = $storedCrit['overflow_tracks']['value'];
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
$out = $qry->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)->find();
|
||||
|
||||
return array("files"=>$out, "limit"=>$limits, "repeat_tracks"=> $repeatTracks, "count"=>$out->count());
|
||||
return array("files"=>$out, "limit"=>$limits, "repeat_tracks"=> $repeatTracks, "overflow_tracks"=> $overflowTracks, "count"=>$out->count());
|
||||
} catch (Exception $e) {
|
||||
Logging::info($e);
|
||||
}
|
||||
|
||||
}
|
||||
public static function organizeSmartPlaylistCriteria($p_criteria)
|
||||
{
|
||||
{
|
||||
$fieldNames = array('sp_criteria_field', 'sp_criteria_modifier', 'sp_criteria_value', 'sp_criteria_extra', 'sp_criteria_datetime_select', 'sp_criteria_extra_datetime_select');
|
||||
$output = array();
|
||||
foreach ($p_criteria as $ele) {
|
||||
|
@ -1666,7 +1860,6 @@ SQL;
|
|||
$output['etc'][$ele['name']] = $ele['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
public static function getAllBlockFiles()
|
||||
|
@ -1675,9 +1868,9 @@ SQL;
|
|||
SELECT distinct(file_id)
|
||||
FROM cc_blockcontents
|
||||
SQL;
|
||||
|
||||
|
||||
$files = Application_Common_Database::prepareAndExecute($sql, array());
|
||||
|
||||
|
||||
$real_files = array();
|
||||
foreach ($files as $f) {
|
||||
$real_files[] = $f['file_id'];
|
||||
|
|
|
@ -70,6 +70,7 @@ class Application_Model_Dashboard
|
|||
*/
|
||||
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
}
|
||||
|
@ -87,6 +88,7 @@ class Application_Model_Dashboard
|
|||
}
|
||||
} else {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"],
|
||||
"media_item_played"=>$row[0]["media_item_played"],
|
||||
|
@ -110,6 +112,7 @@ class Application_Model_Dashboard
|
|||
return null;
|
||||
} else {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
}
|
||||
|
@ -128,6 +131,7 @@ class Application_Model_Dashboard
|
|||
|
||||
if ($row[0]["starts"] <= $showInstance->getShowInstanceStart()) {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
} else {
|
||||
|
|
|
@ -56,4 +56,15 @@ class Application_Model_Library
|
|||
|
||||
return $playlistNames;
|
||||
}
|
||||
|
||||
public static function getTracktypes()
|
||||
{
|
||||
$track_type_options = array(NULL => _("None"));
|
||||
$track_types = Application_Model_Tracktype::getTracktypes();
|
||||
foreach ($track_types as $key => $tt) {
|
||||
$track_type_options[$tt['code']] = $tt['type_name'];
|
||||
}
|
||||
|
||||
return $track_type_options;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ group by mount_name
|
|||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
|
||||
$out = array();
|
||||
|
||||
foreach ($data as $d) {
|
||||
$jump = intval($d['count']/1000);
|
||||
$jump = max(1, $jump);
|
||||
|
@ -36,7 +36,7 @@ WHERE (temp.rownum%:p4) = :p5;
|
|||
SQL;
|
||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end, 'p3'=>$d['mount_name'], 'p4'=>$jump, 'p5'=>$remainder));
|
||||
|
||||
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
|
||||
|
@ -51,6 +51,7 @@ SQL;
|
|||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
$enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds();
|
||||
$enabledOut = array();
|
||||
|
||||
|
@ -77,6 +78,68 @@ SQL;
|
|||
|
||||
return $enabledOut;
|
||||
}
|
||||
// this will currently log the average number of listeners to a specific show during a certain range
|
||||
public static function getShowDataPointsWithinRange($p_start, $p_end, $show_id) {
|
||||
$showData = [];
|
||||
$ccShow = CcShowQuery::create()->findPk($show_id);
|
||||
$showName = $ccShow->getDbName();
|
||||
|
||||
|
||||
// this query selects all show instances that aired in this date range that match the show_id
|
||||
$sql = <<<SQL
|
||||
SELECT id, starts, ends FROM cc_show_instances WHERE show_id =:p1
|
||||
AND starts >=:p2 AND ends <=:p3
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$show_id,'p2'=>$p_start, 'p3'=>$p_end));
|
||||
foreach ($data as $d) {
|
||||
$sql = <<<SQL
|
||||
SELECT timestamp, SUM(listener_count) AS listeners
|
||||
FROM cc_listener_count AS lc
|
||||
INNER JOIN cc_timestamp AS ts ON (lc.timestamp_id = ts.ID)
|
||||
INNER JOIN cc_mount_name AS mn ON (lc.mount_name_id = mn.ID)
|
||||
WHERE (ts.timestamp >=:p1 AND ts.timestamp <=:p2)
|
||||
GROUP BY timestamp
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$d['starts'], 'p2'=>$d['ends']));
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
if (sizeof($data) > 0) {
|
||||
$t = new DateTime($data[0]['timestamp'], $utcTimezone);
|
||||
$t->setTimezone($displayTimezone);
|
||||
// tricking javascript so it thinks the server timezone is in UTC
|
||||
$average_listeners = array_sum(array_column($data, 'listeners')) / sizeof($data);
|
||||
$max_num_listeners = max(array_column($data, 'listeners'));
|
||||
$entry = array("show" => $showName, "time" => $t->format( 'Y-m-d H:i:s')
|
||||
, "average_number_of_listeners" => $average_listeners,
|
||||
"maximum_number_of_listeners" => $max_num_listeners);
|
||||
array_push($showData, $entry);
|
||||
}
|
||||
}
|
||||
return($showData);
|
||||
}
|
||||
public static function getAllShowDataPointsWithinRange($p_start, $p_end) {
|
||||
// this query selects the id of all show instances that aired in this date range
|
||||
$all_show_data = [];
|
||||
$sql = <<<SQL
|
||||
SELECT show_id FROM cc_show_instances
|
||||
WHERE starts >=:p1 AND ends <=:p2
|
||||
GROUP BY show_id
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
|
||||
foreach($data as $show_id) {
|
||||
$all_show_data = array_merge(self::getShowDataPointsWithinRange($p_start,$p_end,$show_id['show_id']), $all_show_data);
|
||||
}
|
||||
/* option to sort by number of listeners currently commented out
|
||||
usort($all_show_data, function($a, $b) {
|
||||
return $a['average_number_of_listeners'] - $b['average_number_of_listeners'];
|
||||
});
|
||||
*/
|
||||
return $all_show_data;
|
||||
}
|
||||
|
||||
public static function insertDataPoints($p_dataPoints) {
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class Application_Model_Preference
|
||||
{
|
||||
|
||||
|
||||
private static function getUserId()
|
||||
{
|
||||
//pass in true so the check is made with the autoloader
|
||||
|
@ -13,10 +13,10 @@ class Application_Model_Preference
|
|||
$auth = Zend_Auth::getInstance();
|
||||
$userId = $auth->getIdentity()->id;
|
||||
}
|
||||
|
||||
|
||||
return $userId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param boolean $isUserValue is true when we are setting a value for the current user
|
||||
|
@ -32,7 +32,7 @@ class Application_Model_Preference
|
|||
/* Comment this out while we reevaluate it in favor of a unique constraint
|
||||
static::_lock($con); */
|
||||
$userId = self::getUserId();
|
||||
|
||||
|
||||
if ($isUserValue && is_null($userId)) {
|
||||
throw new Exception("User id can't be null for a user preference {$key}.");
|
||||
}
|
||||
|
@ -40,10 +40,10 @@ class Application_Model_Preference
|
|||
//Check if key already exists
|
||||
$sql = "SELECT valstr FROM cc_pref"
|
||||
." WHERE keystr = :key";
|
||||
|
||||
|
||||
$paramMap = array();
|
||||
$paramMap[':key'] = $key;
|
||||
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if ($isUserValue) {
|
||||
$sql .= " AND subjid = :id";
|
||||
|
@ -52,8 +52,8 @@ class Application_Model_Preference
|
|||
|
||||
$sql .= " FOR UPDATE";
|
||||
|
||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||
$paramMap,
|
||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||
$paramMap,
|
||||
Application_Common_Database::ROW_COUNT,
|
||||
PDO::FETCH_ASSOC,
|
||||
$con);
|
||||
|
@ -64,7 +64,7 @@ class Application_Model_Preference
|
|||
throw new Exception("Invalid number of results returned. Should be ".
|
||||
"0 or 1, but is '$result' instead");
|
||||
} else if ($result == 1) {
|
||||
|
||||
|
||||
// result found
|
||||
if (!$isUserValue) {
|
||||
// system pref
|
||||
|
@ -76,11 +76,11 @@ class Application_Model_Preference
|
|||
$sql = "UPDATE cc_pref"
|
||||
. " SET valstr = :value"
|
||||
. " WHERE keystr = :key AND subjid = :id";
|
||||
|
||||
|
||||
$paramMap[':id'] = $userId;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
// result not found
|
||||
if (!$isUserValue) {
|
||||
// system pref
|
||||
|
@ -90,17 +90,17 @@ class Application_Model_Preference
|
|||
// user pref
|
||||
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
|
||||
." VALUES (:id, :key, :value)";
|
||||
|
||||
|
||||
$paramMap[':id'] = $userId;
|
||||
}
|
||||
}
|
||||
$paramMap[':key'] = $key;
|
||||
$paramMap[':value'] = $value;
|
||||
|
||||
Application_Common_Database::prepareAndExecute($sql,
|
||||
Application_Common_Database::prepareAndExecute($sql,
|
||||
$paramMap,
|
||||
Application_Common_Database::EXECUTE,
|
||||
PDO::FETCH_ASSOC,
|
||||
PDO::FETCH_ASSOC,
|
||||
$con);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
@ -141,7 +141,7 @@ class Application_Model_Preference
|
|||
private static function getValue($key, $isUserValue = false, $forceDefault = false)
|
||||
{
|
||||
try {
|
||||
|
||||
|
||||
$userId = null;
|
||||
if ($isUserValue) {
|
||||
//This is nested in here because so we can still use getValue() when the session hasn't started yet.
|
||||
|
@ -154,10 +154,10 @@ class Application_Model_Preference
|
|||
//Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_pref"
|
||||
." WHERE keystr = :key";
|
||||
|
||||
|
||||
$paramMap = array();
|
||||
$paramMap[':key'] = $key;
|
||||
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if ($isUserValue) {
|
||||
$sql .= " AND subjid = :id";
|
||||
|
@ -174,7 +174,7 @@ class Application_Model_Preference
|
|||
} else {
|
||||
$sql = "SELECT valstr FROM cc_pref"
|
||||
." WHERE keystr = :key";
|
||||
|
||||
|
||||
$paramMap = array();
|
||||
$paramMap[':key'] = $key;
|
||||
|
||||
|
@ -183,14 +183,14 @@ class Application_Model_Preference
|
|||
$sql .= " AND subjid = :id";
|
||||
$paramMap[':id'] = $userId;
|
||||
}
|
||||
|
||||
|
||||
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
|
||||
|
||||
$res = ($result !== false) ? $result : "";
|
||||
}
|
||||
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::info("Could not connect to database: ".$e);
|
||||
|
@ -201,10 +201,11 @@ class Application_Model_Preference
|
|||
public static function GetHeadTitle()
|
||||
{
|
||||
$title = self::getValue("station_name");
|
||||
if (strlen($title) > 0)
|
||||
$title .= " - ";
|
||||
if (empty($title)) {
|
||||
$title = PRODUCT_NAME;
|
||||
}
|
||||
|
||||
return $title.PRODUCT_NAME;
|
||||
return $title;
|
||||
}
|
||||
|
||||
public static function SetHeadTitle($title, $view=null)
|
||||
|
@ -257,55 +258,55 @@ class Application_Model_Preference
|
|||
return new DateTime($date, new DateTimeZone("UTC"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function SetDefaultCrossfadeDuration($duration)
|
||||
{
|
||||
self::setValue("default_crossfade_duration", $duration);
|
||||
}
|
||||
|
||||
|
||||
public static function GetDefaultCrossfadeDuration()
|
||||
{
|
||||
$duration = self::getValue("default_crossfade_duration");
|
||||
|
||||
|
||||
if ($duration === "") {
|
||||
// the default value of the fade is 00.5
|
||||
return "0";
|
||||
}
|
||||
|
||||
|
||||
return $duration;
|
||||
}
|
||||
|
||||
|
||||
public static function SetDefaultFadeIn($fade)
|
||||
{
|
||||
self::setValue("default_fade_in", $fade);
|
||||
}
|
||||
|
||||
|
||||
public static function GetDefaultFadeIn()
|
||||
{
|
||||
$fade = self::getValue("default_fade_in");
|
||||
|
||||
|
||||
if ($fade === "") {
|
||||
// the default value of the fade is 00.5
|
||||
return "0.5";
|
||||
}
|
||||
|
||||
|
||||
return $fade;
|
||||
}
|
||||
|
||||
|
||||
public static function SetDefaultFadeOut($fade)
|
||||
{
|
||||
self::setValue("default_fade_out", $fade);
|
||||
}
|
||||
|
||||
|
||||
public static function GetDefaultFadeOut()
|
||||
{
|
||||
$fade = self::getValue("default_fade_out");
|
||||
|
||||
|
||||
if ($fade === "") {
|
||||
// the default value of the fade is 0.5
|
||||
return "0.5";
|
||||
}
|
||||
|
||||
|
||||
return $fade;
|
||||
}
|
||||
|
||||
|
@ -369,7 +370,7 @@ class Application_Model_Preference
|
|||
{
|
||||
self::setValue("podcast_album_override", $bool);
|
||||
}
|
||||
|
||||
|
||||
public static function GetPodcastAlbumOverride()
|
||||
{
|
||||
$val = self::getValue("podcast_album_override");
|
||||
|
@ -387,6 +388,36 @@ class Application_Model_Preference
|
|||
return $val === '1' ? true : false;
|
||||
}
|
||||
|
||||
public static function SetTrackTypeDefault($tracktype)
|
||||
{
|
||||
self::setValue("tracktype_default", $tracktype);
|
||||
}
|
||||
|
||||
public static function GetTrackTypeDefault()
|
||||
{
|
||||
return self::getValue("tracktype_default");
|
||||
}
|
||||
|
||||
public static function GetIntroPlaylist()
|
||||
{
|
||||
return self::getValue("intro_playlist");
|
||||
}
|
||||
|
||||
public static function GetOutroPlaylist()
|
||||
{
|
||||
return self::getValue("outro_playlist");
|
||||
}
|
||||
|
||||
|
||||
public static function SetIntroPlaylist($playlist)
|
||||
{
|
||||
self::setValue("intro_playlist", $playlist);
|
||||
}
|
||||
|
||||
public static function SetOutroPlaylist($playlist)
|
||||
{
|
||||
self::setValue("outro_playlist", $playlist);
|
||||
}
|
||||
|
||||
public static function SetPhone($phone)
|
||||
{
|
||||
|
@ -506,7 +537,7 @@ class Application_Model_Preference
|
|||
|
||||
public static function GetUserTimezone()
|
||||
{
|
||||
$timezone = self::getValue("user_timezone", true);
|
||||
$timezone = self::getValue("user_timezone", true);
|
||||
if (!$timezone) {
|
||||
return self::GetDefaultTimezone();
|
||||
} else {
|
||||
|
@ -518,7 +549,7 @@ class Application_Model_Preference
|
|||
public static function GetTimezone()
|
||||
{
|
||||
$userId = self::getUserId();
|
||||
|
||||
|
||||
if (!is_null($userId)) {
|
||||
return self::GetUserTimezone();
|
||||
} else {
|
||||
|
@ -560,7 +591,7 @@ class Application_Model_Preference
|
|||
public static function GetLocale()
|
||||
{
|
||||
$userId = self::getUserId();
|
||||
|
||||
|
||||
if (!is_null($userId)) {
|
||||
return self::GetUserLocale();
|
||||
} else {
|
||||
|
@ -591,7 +622,7 @@ class Application_Model_Preference
|
|||
return $image;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function SetUniqueId($id)
|
||||
{
|
||||
self::setValue("uniqueId", $id);
|
||||
|
@ -605,7 +636,7 @@ class Application_Model_Preference
|
|||
public static function GetCountryList()
|
||||
{
|
||||
$sql = "SELECT * FROM cc_country";
|
||||
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array());
|
||||
|
||||
$out = array();
|
||||
|
@ -661,7 +692,7 @@ class Application_Model_Preference
|
|||
$url = $systemInfoArray["AIRTIME_VERSION_URL"];
|
||||
$index = strpos($url,'/api/');
|
||||
$url = substr($url, 0, $index);
|
||||
|
||||
|
||||
$headerInfo = get_headers(trim($url),1);
|
||||
$outputArray['WEB_SERVER'] = $headerInfo['Server'][0];
|
||||
}
|
||||
|
@ -672,8 +703,6 @@ class Application_Model_Preference
|
|||
$outputArray['NUM_OF_SCHEDULED_PLAYLISTS'] = Application_Model_Schedule::getSchduledPlaylistCount();
|
||||
$outputArray['NUM_OF_PAST_SHOWS'] = Application_Model_ShowInstance::GetShowInstanceCount(gmdate(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$outputArray['UNIQUE_ID'] = self::GetUniqueId();
|
||||
$outputArray['SAAS'] = self::GetPlanLevel();
|
||||
$outputArray['TRIAL_END_DATE'] = self::GetTrialEndingDate();
|
||||
$outputArray['INSTALL_METHOD'] = self::GetInstallMethod();
|
||||
$outputArray['NUM_OF_STREAMS'] = self::GetNumOfStreams();
|
||||
$outputArray['STREAM_INFO'] = Application_Model_StreamSetting::getStreamInfoForDataCollection();
|
||||
|
@ -682,9 +711,6 @@ class Application_Model_Preference
|
|||
|
||||
$outputString = "\n";
|
||||
foreach ($outputArray as $key => $out) {
|
||||
if ($key == 'TRIAL_END_DATE' && ($out != '' || $out != 'NULL')) {
|
||||
continue;
|
||||
}
|
||||
if ($key == "STREAM_INFO") {
|
||||
$outputString .= $key." :\n";
|
||||
foreach ($out as $s_info) {
|
||||
|
@ -692,8 +718,6 @@ class Application_Model_Preference
|
|||
$outputString .= "\t".strtoupper($k)." : ".$v."\n";
|
||||
}
|
||||
}
|
||||
} elseif ($key == "SAAS") {
|
||||
$outputString .= $key.' : '.$out."\n";
|
||||
} else {
|
||||
$outputString .= $key.' : '.$out."\n";
|
||||
}
|
||||
|
@ -808,47 +832,6 @@ class Application_Model_Preference
|
|||
return self::getValue("max_bitrate");
|
||||
}
|
||||
|
||||
public static function SetPlanLevel($plan)
|
||||
{
|
||||
$oldPlanLevel = self::GetPlanLevel();
|
||||
self::setValue("plan_level", $plan);
|
||||
//We save the old plan level temporarily to facilitate conversion tracking
|
||||
self::setValue("old_plan_level", $oldPlanLevel);
|
||||
}
|
||||
|
||||
public static function GetPlanLevel()
|
||||
{
|
||||
$plan = self::getValue("plan_level");
|
||||
if (trim($plan) == '') {
|
||||
$plan = 'disabled';
|
||||
}
|
||||
|
||||
return $plan;
|
||||
}
|
||||
|
||||
public static function GetOldPlanLevel()
|
||||
{
|
||||
$oldPlan = self::getValue("old_plan_level");
|
||||
return $oldPlan;
|
||||
}
|
||||
|
||||
/** Clearing the old plan level indicates a change in your plan has been tracked (Google Analytics) */
|
||||
public static function ClearOldPlanLevel()
|
||||
{
|
||||
self::setValue("old_plan_level", '');
|
||||
}
|
||||
|
||||
|
||||
public static function SetTrialEndingDate($date)
|
||||
{
|
||||
self::setValue("trial_end_date", $date);
|
||||
}
|
||||
|
||||
public static function GetTrialEndingDate()
|
||||
{
|
||||
return self::getValue("trial_end_date");
|
||||
}
|
||||
|
||||
public static function SetEnableStreamConf($bool)
|
||||
{
|
||||
self::setValue("enable_stream_conf", $bool);
|
||||
|
@ -909,13 +892,13 @@ class Application_Model_Preference
|
|||
$versions[] = $item->get_title();
|
||||
}
|
||||
$latest = $versions;
|
||||
self::setValue('latest_version', json_encode($latest));
|
||||
self::setValue('latest_version_nextcheck', strtotime('+1 week'));
|
||||
if (empty($latest)) {
|
||||
return $config['airtime_version'];
|
||||
} else {
|
||||
return $latest;
|
||||
return array($config['airtime_version']);
|
||||
}
|
||||
|
||||
self::setValue('latest_version', json_encode($latest));
|
||||
return $latest;
|
||||
}
|
||||
|
||||
public static function SetLatestVersion($version)
|
||||
|
@ -988,24 +971,6 @@ class Application_Model_Preference
|
|||
Logging::warn("Attempting to set client_id to invalid value: $id");
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetLiveChatEnabled()
|
||||
{
|
||||
$liveChat = self::getValue("live_chat", false);
|
||||
if (is_null($liveChat) || $liveChat == "" || $liveChat == "1") { //Defaults to on
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function SetLiveChatEnabled($toggle)
|
||||
{
|
||||
if (is_bool($toggle)) {
|
||||
self::setValue("live_chat", $toggle ? "1" : "0");
|
||||
} else {
|
||||
Logging::warn("Attempting to set live_chat to invalid value: $toggle. Must be a bool.");
|
||||
}
|
||||
}
|
||||
|
||||
/* User specific preferences start */
|
||||
|
||||
|
@ -1215,11 +1180,11 @@ class Application_Model_Preference
|
|||
$today = mktime(0, 0, 0, gmdate("m"), gmdate("d"), gmdate("Y"));
|
||||
$remindDate = Application_Model_Preference::GetRemindMeDate();
|
||||
$retVal = false;
|
||||
|
||||
|
||||
if (is_null($remindDate) || ($remindDate != -1 && $today >= $remindDate)) {
|
||||
$retVal = true;
|
||||
}
|
||||
|
||||
|
||||
return $retVal;
|
||||
}
|
||||
|
||||
|
@ -1236,12 +1201,12 @@ class Application_Model_Preference
|
|||
}
|
||||
|
||||
$ds = unserialize($v);
|
||||
|
||||
|
||||
|
||||
|
||||
if (is_null($ds) || !is_array($ds)) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
if (!array_key_exists('ColReorder', $ds)) {
|
||||
return $id;
|
||||
}
|
||||
|
@ -1318,37 +1283,37 @@ class Application_Model_Preference
|
|||
public static function SetEnableReplayGain($value) {
|
||||
self::setValue("enable_replay_gain", $value, false);
|
||||
}
|
||||
|
||||
|
||||
public static function GetEnableReplayGain() {
|
||||
return self::getValue("enable_replay_gain", false);
|
||||
}
|
||||
|
||||
|
||||
public static function getReplayGainModifier() {
|
||||
$rg_modifier = self::getValue("replay_gain_modifier");
|
||||
|
||||
|
||||
if ($rg_modifier === "")
|
||||
return "0";
|
||||
|
||||
|
||||
return $rg_modifier;
|
||||
}
|
||||
|
||||
|
||||
public static function setReplayGainModifier($rg_modifier)
|
||||
{
|
||||
self::setValue("replay_gain_modifier", $rg_modifier, true);
|
||||
}
|
||||
|
||||
|
||||
public static function SetHistoryItemTemplate($value) {
|
||||
self::setValue("history_item_template", $value);
|
||||
}
|
||||
|
||||
|
||||
public static function GetHistoryItemTemplate() {
|
||||
return self::getValue("history_item_template");
|
||||
}
|
||||
|
||||
|
||||
public static function SetHistoryFileTemplate($value) {
|
||||
self::setValue("history_file_template", $value);
|
||||
}
|
||||
|
||||
|
||||
public static function GetHistoryFileTemplate() {
|
||||
return self::getValue("history_file_template");
|
||||
}
|
||||
|
@ -1374,18 +1339,6 @@ class Application_Model_Preference
|
|||
self::setDiskUsage($currentDiskUsage + $filesize);
|
||||
}
|
||||
|
||||
|
||||
public static function setProvisioningStatus($status)
|
||||
{
|
||||
//See constants.php for the list of valid values. eg. PROVISIONING_STATUS_ACTIVE
|
||||
self::setValue("provisioning_status", $status);
|
||||
}
|
||||
|
||||
public static function getProvisioningStatus()
|
||||
{
|
||||
return self::getValue("provisioning_status");
|
||||
}
|
||||
|
||||
public static function setTuneinEnabled($value)
|
||||
{
|
||||
self::setValue("tunein_enabled", $value);
|
||||
|
@ -1536,7 +1489,7 @@ class Application_Model_Preference
|
|||
{
|
||||
self::setValue("whats_new_dialog_viewed", $value, true);
|
||||
}
|
||||
|
||||
|
||||
public static function getAutoPlaylistPollLock() {
|
||||
return self::getValue("autoplaylist_poll_lock");
|
||||
}
|
||||
|
@ -1613,11 +1566,6 @@ class Application_Model_Preference
|
|||
* @return int either 0 (public) or 1 (private)
|
||||
*/
|
||||
public static function getStationPodcastPrivacy() {
|
||||
if (LIBRETIME_ENABLE_BILLING === true && !Billing::isStationPodcastAllowed()) {
|
||||
// return private setting
|
||||
return 1;
|
||||
}
|
||||
|
||||
return self::getValue("station_podcast_privacy");
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,10 @@ SQL;
|
|||
$utcNow = new DateTime("now", new DateTimeZone("UTC"));
|
||||
|
||||
$shows = Application_Model_Show::getPrevCurrentNext($utcNow, $utcTimeEnd, $showsToRetrieve);
|
||||
$currentShowID = count($shows['currentShow'])>0?$shows['currentShow']['instance_id']:null;
|
||||
$currentShowID = null;
|
||||
if (is_array($shows['currentShow']) && count($shows['currentShow'])>0) {
|
||||
$currentShowID = $shows['currentShow']['instance_id'];
|
||||
}
|
||||
$source = self::_getSource();
|
||||
$results = Application_Model_Schedule::getPreviousCurrentNextMedia($utcNow, $currentShowID, self::_getSource());
|
||||
|
||||
|
@ -269,8 +272,10 @@ SQL;
|
|||
$previousFile = CcFilesQuery::create()
|
||||
->filterByDbId($previousMediaFileId)
|
||||
->findOne();
|
||||
$previousMediaName = $previousFile->getDbArtistName() . " - " . $previousFile->getDbTrackTitle();
|
||||
$previousMetadata = CcFiles::sanitizeResponse($previousFile);
|
||||
if (isset($previousFile)) {
|
||||
$previousMediaName = $previousFile->getDbArtistName() . " - " . $previousFile->getDbTrackTitle();
|
||||
$previousMetadata = CcFiles::sanitizeResponse($previousFile);
|
||||
}
|
||||
} else if (isset($previousMediaStreamId)) {
|
||||
$previousMediaName = null;
|
||||
$previousMediaType = "webstream";
|
||||
|
|
|
@ -84,7 +84,7 @@ final class Application_Model_Scheduler
|
|||
*
|
||||
* @param array $items, an array containing pks of cc_schedule items.
|
||||
*/
|
||||
private function validateRequest($items, $addRemoveAction=false)
|
||||
private function validateRequest($items, $addRemoveAction=false, $cancelShow=false)
|
||||
{
|
||||
//$items is where tracks get inserted (they are schedule locations)
|
||||
|
||||
|
@ -168,8 +168,10 @@ final class Application_Model_Scheduler
|
|||
* Does the afterItem belong to a show that is linked AND
|
||||
* currently playing?
|
||||
* If yes, throw an exception
|
||||
* unless it is a cancel show action then we don't check because otherwise
|
||||
* ongoing linked shows can't be cancelled
|
||||
*/
|
||||
if ($addRemoveAction) {
|
||||
if ($addRemoveAction && !$cancelShow) {
|
||||
$ccShow = $instance->getCcShow();
|
||||
if ($ccShow->isLinked()) {
|
||||
//get all the linked shows instances and check if
|
||||
|
@ -207,13 +209,17 @@ final class Application_Model_Scheduler
|
|||
/*
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @param $show
|
||||
*
|
||||
* @return $files
|
||||
*/
|
||||
private function retrieveMediaFiles($id, $type)
|
||||
private function retrieveMediaFiles($id, $type, $show)
|
||||
{
|
||||
$files = array();
|
||||
// if there is a show we need to set a show limit to pass to smart blocks in case they use time remaining
|
||||
$showInstance = new Application_Model_ShowInstance($show);
|
||||
$showLimit = $showInstance->getSecondsRemaining();
|
||||
|
||||
$files = array();
|
||||
if ($type === "audioclip") {
|
||||
$file = CcFilesQuery::create()->findPK($id, $this->con);
|
||||
|
||||
|
@ -241,7 +247,8 @@ final class Application_Model_Scheduler
|
|||
} elseif ($type === "playlist") {
|
||||
$pl = new Application_Model_Playlist($id);
|
||||
$contents = $pl->getContents();
|
||||
|
||||
// because the time remaining is not updated until after the schedule inserts we need to track it for
|
||||
// the entire add vs. querying on the smartblock level
|
||||
foreach ($contents as $plItem) {
|
||||
if ($plItem['type'] == 0) {
|
||||
$data["id"] = $plItem['item_id'];
|
||||
|
@ -278,7 +285,7 @@ final class Application_Model_Scheduler
|
|||
} else {
|
||||
$defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn();
|
||||
$defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut();
|
||||
$dynamicFiles = $bl->getListOfFilesUnderLimit();
|
||||
$dynamicFiles = $bl->getListOfFilesUnderLimit($showLimit);
|
||||
foreach ($dynamicFiles as $f) {
|
||||
$fileId = $f['id'];
|
||||
$file = CcFilesQuery::create()->findPk($fileId);
|
||||
|
@ -301,6 +308,9 @@ final class Application_Model_Scheduler
|
|||
}
|
||||
}
|
||||
}
|
||||
// if this is a playlist it might contain multiple time remaining smart blocks
|
||||
// since the schedule isn't updated until after this insert we need to keep tally
|
||||
$showLimit -= $this->timeLengthOfFiles($files);
|
||||
}
|
||||
} elseif ($type == "stream") {
|
||||
//need to return
|
||||
|
@ -337,7 +347,7 @@ final class Application_Model_Scheduler
|
|||
} else {
|
||||
$defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn();
|
||||
$defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut();
|
||||
$dynamicFiles = $bl->getListOfFilesUnderLimit();
|
||||
$dynamicFiles = $bl->getListOfFilesUnderLimit($showLimit);
|
||||
foreach ($dynamicFiles as $f) {
|
||||
$fileId = $f['id'];
|
||||
$file = CcFilesQuery::create()->findPk($fileId);
|
||||
|
@ -788,11 +798,14 @@ final class Application_Model_Scheduler
|
|||
Logging::debug(floatval($pend) - floatval($pstart));
|
||||
}
|
||||
|
||||
// passing $schedule["instance"] so that the instance being scheduled
|
||||
// can be used to determine the remaining time
|
||||
// in the case of a fill remaining time smart block
|
||||
if (is_null($filesToInsert)) {
|
||||
$filesToInsert = array();
|
||||
foreach ($mediaItems as $media) {
|
||||
$filesToInsert = array_merge($filesToInsert,
|
||||
$this->retrieveMediaFiles($media["id"], $media["type"]));
|
||||
$this->retrieveMediaFiles($media["id"], $media["type"], $schedule["instance"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,8 +868,14 @@ final class Application_Model_Scheduler
|
|||
|
||||
// default fades are in seconds
|
||||
// we need to convert to '00:00:00' format
|
||||
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
|
||||
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
|
||||
// added a check to only run the conversion if they are in seconds format
|
||||
// otherwise php > 7.1 throws errors
|
||||
if (is_numeric($file['fadein'])) {
|
||||
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
|
||||
}
|
||||
if (is_numeric($file['fadeout'])) {
|
||||
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
|
||||
}
|
||||
|
||||
switch ($file["type"]) {
|
||||
case 0:
|
||||
|
@ -984,6 +1003,7 @@ final class Application_Model_Scheduler
|
|||
$this->calculateCrossfades($instanceId);
|
||||
}
|
||||
}//for each instance
|
||||
|
||||
}//for each schedule location
|
||||
|
||||
$endProfile = microtime(true);
|
||||
|
@ -1189,7 +1209,7 @@ final class Application_Model_Scheduler
|
|||
|
||||
try {
|
||||
|
||||
$this->validateRequest($scheduledItems, true);
|
||||
$this->validateRequest($scheduledItems, true, true);
|
||||
|
||||
$scheduledIds = array();
|
||||
foreach ($scheduledItems as $item) {
|
||||
|
@ -1285,6 +1305,20 @@ final class Application_Model_Scheduler
|
|||
throw $e;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This is used to determine the duration of a files array
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function timeLengthOfFiles($files) {
|
||||
$timeLength = 0;
|
||||
foreach ($files as $file) {
|
||||
$timeLength += Application_Common_DateHelper::playlistTimeToSeconds($file['cliplength']);
|
||||
$timeLength += $file['fadein'];
|
||||
$timeLength += $file['fadeout'];
|
||||
}
|
||||
return $timeLength;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for cancelling the current show instance.
|
||||
|
|
|
@ -242,9 +242,30 @@ SQL;
|
|||
array(array("id" => $lastid, "instance" => $id, "timestamp" => $ts)),
|
||||
array(array("id" => $pl_id, "type" => "playlist"))
|
||||
);
|
||||
// doing this to update the database schedule so that subsequent adds will work.
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$this->_showInstance->updateScheduleStatus($con);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a playlist as the first item of the current show.
|
||||
*
|
||||
* @param int $plId
|
||||
* Playlist ID.
|
||||
*/
|
||||
public function addPlaylistToShowStart($pl_id, $checkUserPerm = true)
|
||||
{
|
||||
$ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
|
||||
$id = $this->_showInstance->getDbId();
|
||||
$scheduler = new Application_Model_Scheduler($checkUserPerm);
|
||||
$scheduler->scheduleAfter(
|
||||
array(array("id" => 0, "instance" => $id, "timestamp" => $ts)),
|
||||
array(array("id" => $pl_id, "type" => "playlist"))
|
||||
);
|
||||
// doing this to update the database schedule so that subsequent adds will work.
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$this->_showInstance->updateScheduleStatus($con);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -476,6 +497,12 @@ SQL;
|
|||
return intval($ends->format('U')) - intval($starts->format('U'));
|
||||
}
|
||||
|
||||
// should return the amount of seconds remaining to be scheduled in a show instance
|
||||
public function getSecondsRemaining()
|
||||
{
|
||||
return ($this->getDurationSecs() - $this->getTimeScheduledSecs());
|
||||
}
|
||||
|
||||
public function getPercentScheduled()
|
||||
{
|
||||
$durationSeconds = $this->getDurationSecs();
|
||||
|
|
|
@ -53,7 +53,9 @@ class Application_Model_StoredFile
|
|||
"owner_id" => "DbOwnerId",
|
||||
"cuein" => "DbCueIn",
|
||||
"cueout" => "DbCueOut",
|
||||
"description" => "DbDescription"
|
||||
"description" => "DbDescription",
|
||||
"artwork" => "DbArtwork",
|
||||
"track_type" => "DbTrackType"
|
||||
);
|
||||
|
||||
function __construct($file, $con) {
|
||||
|
@ -172,39 +174,36 @@ class Application_Model_StoredFile
|
|||
$this->_file->$method(null);
|
||||
}
|
||||
} else {
|
||||
$owner = $this->_file->getFkOwner();
|
||||
// if owner_id is already set we don't want to set it again.
|
||||
if (!$owner) { // no owner detected, we try to assign one.
|
||||
// if MDATA_OWNER_ID is not set then we default to the
|
||||
// first admin user we find
|
||||
if (!array_key_exists('owner_id', $p_md)) {
|
||||
//$admins = Application_Model_User::getUsers(array('A'));
|
||||
$admins = array_merge(Application_Model_User::getUsersOfType('A')->getData(),
|
||||
Application_Model_User::getUsersOfType('S')->getData());
|
||||
if (count($admins) > 0) { // found admin => pick first one
|
||||
$owner = $admins[0];
|
||||
// in order to edit the owner of a file we see if owner_id exists in the track form metadata otherwise
|
||||
// we determine it via the algorithm below
|
||||
if (!array_key_exists('owner_id', $p_md)) {
|
||||
$owner = $this->_file->getFkOwner();
|
||||
// if owner_id is already set we don't want to set it again.
|
||||
if (!$owner) { // no owner detected, we try to assign one.
|
||||
// if MDATA_OWNER_ID is not set then we default to the
|
||||
// first admin user we find
|
||||
if (!array_key_exists('owner_id', $p_md)) {
|
||||
//$admins = Application_Model_User::getUsers(array('A'));
|
||||
$admins = array_merge(Application_Model_User::getUsersOfType('A')->getData(),
|
||||
Application_Model_User::getUsersOfType('S')->getData());
|
||||
if (count($admins) > 0) { // found admin => pick first one
|
||||
$owner = $admins[0];
|
||||
}
|
||||
} // get the user by id and set it like that
|
||||
else {
|
||||
$user = CcSubjsQuery::create()
|
||||
->findPk($p_md['owner_id']);
|
||||
if ($user) {
|
||||
$owner = $user;
|
||||
}
|
||||
}
|
||||
if ($owner) {
|
||||
$this->_file->setDbOwnerId($owner->getDbId());
|
||||
} else {
|
||||
Logging::info("Could not find suitable owner for file
|
||||
'" . $p_md['filepath'] . "'");
|
||||
}
|
||||
}
|
||||
// get the user by id and set it like that
|
||||
else {
|
||||
$user = CcSubjsQuery::create()
|
||||
->findPk($p_md['owner_id']);
|
||||
if ($user) {
|
||||
$owner = $user;
|
||||
}
|
||||
}
|
||||
if ($owner) {
|
||||
$this->_file->setDbOwnerId( $owner->getDbId() );
|
||||
} else {
|
||||
Logging::info("Could not find suitable owner for file
|
||||
'".$p_md['filepath']."'");
|
||||
}
|
||||
}
|
||||
# We don't want to process owner_id in bulk because we already
|
||||
# processed it in the code above. This is done because owner_id
|
||||
# needs special handling
|
||||
if (array_key_exists('owner_id', $p_md)) {
|
||||
unset($p_md['owner_id']);
|
||||
}
|
||||
foreach ($p_md as $dbColumn => $mdValue) {
|
||||
// don't blank out name, defaults to original filename on first
|
||||
|
@ -212,7 +211,7 @@ class Application_Model_StoredFile
|
|||
if ($dbColumn == "track_title" && (is_null($mdValue) || $mdValue == "")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Bpm gets POSTed as a string type. With Propel 1.6 this value
|
||||
// was casted to an integer type before saving it to the db. But
|
||||
// Propel 1.7 does not do this
|
||||
|
@ -355,8 +354,8 @@ SQL;
|
|||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Check if the file (on disk) corresponding to this class exists or not.
|
||||
* @return boolean true if the file exists, false otherwise.
|
||||
*/
|
||||
|
@ -418,11 +417,11 @@ SQL;
|
|||
|
||||
//Update the user's disk usage
|
||||
Application_Model_Preference::updateDiskUsage(-1 * $filesize);
|
||||
|
||||
|
||||
//Explicitly update any playlist's and block's length that contain
|
||||
//the file getting deleted
|
||||
self::updateBlockAndPlaylistLength($this->_file->getDbId());
|
||||
|
||||
|
||||
//delete the file record from cc_files (and cloud_file, if applicable)
|
||||
$this->_file->delete();
|
||||
}
|
||||
|
@ -430,7 +429,7 @@ SQL;
|
|||
/*
|
||||
* This function is meant to be called when a file is getting
|
||||
* deleted from the library. It re-calculates the length of
|
||||
* all blocks and playlists that contained the deleted file.
|
||||
* all blocks and playlists that contained the deleted file.
|
||||
*/
|
||||
private static function updateBlockAndPlaylistLength($fileId)
|
||||
{
|
||||
|
@ -474,7 +473,7 @@ SQL;
|
|||
public function getFilePaths()
|
||||
{
|
||||
assert($this->_file);
|
||||
|
||||
|
||||
return $this->_file->getURLsForTrackPreviewOrDownload();
|
||||
}
|
||||
|
||||
|
@ -531,7 +530,7 @@ SQL;
|
|||
{
|
||||
return $baseUrl."api/get-media/file/".$this->getId();
|
||||
}
|
||||
|
||||
|
||||
public function getResourceId()
|
||||
{
|
||||
return $this->_file->getResourceId();
|
||||
|
@ -548,7 +547,7 @@ SQL;
|
|||
}
|
||||
return $filesize;
|
||||
}
|
||||
|
||||
|
||||
public static function Insert($md, $con)
|
||||
{
|
||||
// save some work by checking if filepath is given right away
|
||||
|
@ -595,17 +594,17 @@ SQL;
|
|||
|
||||
if (isset($p_id)) {
|
||||
$p_id = intval($p_id);
|
||||
|
||||
|
||||
$storedFile = CcFilesQuery::create()->findPK($p_id, $con);
|
||||
if (is_null($storedFile)) {
|
||||
throw new Exception("Could not recall file with id: ".$p_id);
|
||||
}
|
||||
|
||||
|
||||
//Attempt to get the cloud file object and return it. If no cloud
|
||||
//file object is found then we are dealing with a regular stored
|
||||
//object so return that
|
||||
$cloudFile = CloudFileQuery::create()->findOneByCcFileId($p_id);
|
||||
|
||||
|
||||
if (is_null($cloudFile)) {
|
||||
return self::createWithFile($storedFile, $con);
|
||||
} else {
|
||||
|
@ -674,7 +673,7 @@ SQL;
|
|||
"bit_rate", "sample_rate", "isrc_number", "encoded_by", "label",
|
||||
"copyright", "mime", "language", "filepath", "owner_id",
|
||||
"conductor", "replay_gain", "lptime", "is_playlist", "is_scheduled",
|
||||
"cuein", "cueout", "description" );
|
||||
"cuein", "cueout", "description", "artwork", "track_type" );
|
||||
}
|
||||
|
||||
public static function searchLibraryFiles($datatables)
|
||||
|
@ -696,49 +695,49 @@ SQL;
|
|||
$blSelect[] = "BL.id AS ".$key;
|
||||
$fileSelect[] = "FILES.id AS $key";
|
||||
$streamSelect[] = "ws.id AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "track_title") {
|
||||
$plSelect[] = "name AS ".$key;
|
||||
$blSelect[] = "name AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "name AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "ftype") {
|
||||
$plSelect[] = "'playlist'::varchar AS ".$key;
|
||||
$blSelect[] = "'block'::varchar AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "'stream'::varchar AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "artist_name") {
|
||||
$plSelect[] = "login AS ".$key;
|
||||
$blSelect[] = "login AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "login AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "owner_id") {
|
||||
$plSelect[] = "login AS ".$key;
|
||||
$blSelect[] = "login AS ".$key;
|
||||
$fileSelect[] = "sub.login AS $key";
|
||||
$streamSelect[] = "login AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "replay_gain") {
|
||||
$plSelect[] = "NULL::NUMERIC AS ".$key;
|
||||
$blSelect[] = "NULL::NUMERIC AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "NULL::NUMERIC AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "lptime") {
|
||||
$plSelect[] = "NULL::TIMESTAMP AS ".$key;
|
||||
$blSelect[] = "NULL::TIMESTAMP AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = $key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "is_scheduled" || $key === "is_playlist") {
|
||||
$plSelect[] = "NULL::boolean AS ".$key;
|
||||
$blSelect[] = "NULL::boolean AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "NULL::boolean AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "cuein" || $key === "cueout") {
|
||||
$plSelect[] = "NULL::INTERVAL AS ".$key;
|
||||
$blSelect[] = "NULL::INTERVAL AS ".$key;
|
||||
|
@ -758,7 +757,7 @@ SQL;
|
|||
$blSelect[] = $key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = $key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "year") {
|
||||
$plSelect[] = "EXTRACT(YEAR FROM utime)::varchar AS ".$key;
|
||||
$blSelect[] = "EXTRACT(YEAR FROM utime)::varchar AS ".$key;
|
||||
|
@ -771,13 +770,13 @@ SQL;
|
|||
$blSelect[] = "NULL::int AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "NULL::int AS ".$key;
|
||||
}
|
||||
}
|
||||
elseif ($key === "filepath") {
|
||||
$plSelect[] = "NULL::VARCHAR AS ".$key;
|
||||
$blSelect[] = "NULL::VARCHAR AS ".$key;
|
||||
$fileSelect[] = $key;
|
||||
$streamSelect[] = "url AS ".$key;
|
||||
}
|
||||
}
|
||||
else if ($key == "mime") {
|
||||
$plSelect[] = "NULL::VARCHAR AS ".$key;
|
||||
$blSelect[] = "NULL::VARCHAR AS ".$key;
|
||||
|
@ -831,7 +830,10 @@ SQL;
|
|||
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$fp = $storDir->getDirectory();
|
||||
|
||||
foreach ($results['aaData'] as &$row) {
|
||||
$row['id'] = intval($row['id']);
|
||||
|
||||
|
@ -865,6 +867,9 @@ SQL;
|
|||
$formatter = new BitrateFormatter($row['bit_rate']);
|
||||
$row['bit_rate'] = $formatter->format();
|
||||
|
||||
$get_artwork = FileDataHelper::getArtworkData($row['artwork'], 32, $fp);
|
||||
$row['artwork_data'] = $get_artwork;
|
||||
|
||||
// for audio preview
|
||||
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
|
||||
|
||||
|
@ -877,7 +882,7 @@ SQL;
|
|||
|
||||
$len_formatter = new LengthFormatter($row_length);
|
||||
$row['length'] = $len_formatter->format();
|
||||
|
||||
|
||||
//convert mtime and utime to localtime
|
||||
$row['mtime'] = new DateTime($row['mtime'], $utcTimezone);
|
||||
$row['mtime']->setTimeZone($displayTimezone);
|
||||
|
@ -885,7 +890,7 @@ SQL;
|
|||
$row['utime'] = new DateTime($row['utime'], $utcTimezone);
|
||||
$row['utime']->setTimeZone($displayTimezone);
|
||||
$row['utime'] = $row['utime']->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
|
||||
//need to convert last played to localtime if it exists.
|
||||
if (isset($row['lptime'])) {
|
||||
$row['lptime'] = new DateTime($row['lptime'], $utcTimezone);
|
||||
|
@ -907,16 +912,16 @@ SQL;
|
|||
}
|
||||
|
||||
/**
|
||||
* Copy a newly uploaded audio file from its temporary upload directory
|
||||
* on the local disk (like /tmp) over to Airtime's "stor" directory,
|
||||
* Copy a newly uploaded audio file from its temporary upload directory
|
||||
* on the local disk (like /tmp) over to Airtime's "stor" directory,
|
||||
* which is where all ingested music/media live.
|
||||
*
|
||||
*
|
||||
* This is done in PHP here on the web server rather than in airtime_analyzer because
|
||||
* the airtime_analyzer might be running on a different physical computer than the web server,
|
||||
* and it probably won't have access to the web server's /tmp folder. The stor/organize directory
|
||||
* is, however, both accessible to the machines running airtime_analyzer and the web server
|
||||
* is, however, both accessible to the machines running airtime_analyzer and the web server
|
||||
* on Airtime Pro.
|
||||
*
|
||||
*
|
||||
* The file is actually copied to "stor/organize", which is a staging directory where files go
|
||||
* before they're processed by airtime_analyzer, which then moves them to "stor/imported" in the final
|
||||
* step.
|
||||
|
@ -939,11 +944,11 @@ SQL;
|
|||
throw new Exception("Failed to create organize directory.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (chmod($audio_file, 0644) === false) {
|
||||
Logging::info("Warning: couldn't change permissions of $audio_file to 0644");
|
||||
}
|
||||
|
||||
|
||||
// Did all the checks for real, now trying to copy
|
||||
$audio_stor = Application_Common_OsPath::join($stor, "organize",
|
||||
$originalFilename);
|
||||
|
@ -979,7 +984,7 @@ SQL;
|
|||
}
|
||||
return $audio_stor;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pass the file through Liquidsoap and test if it is readable. Return True if readable, and False otherwise.
|
||||
*/
|
||||
|
@ -1160,7 +1165,7 @@ SQL;
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Updates the is_scheduled flag to false for tracks that are no longer
|
||||
* scheduled in the future. We do this by checking the difference between
|
||||
* all files scheduled in the future and all files with is_scheduled = true.
|
||||
|
@ -1174,15 +1179,15 @@ SQL;
|
|||
$futureScheduledFilesSelectCriteria->add(CcSchedulePeer::ENDS, gmdate(DEFAULT_TIMESTAMP_FORMAT), Criteria::GREATER_THAN);
|
||||
$stmt = CcSchedulePeer::doSelectStmt($futureScheduledFilesSelectCriteria);
|
||||
$filesScheduledInFuture = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
|
||||
|
||||
$filesCurrentlySetWithIsScheduledSelectCriteria = new Criteria();
|
||||
$filesCurrentlySetWithIsScheduledSelectCriteria->addSelectColumn(CcFilesPeer::ID);
|
||||
$filesCurrentlySetWithIsScheduledSelectCriteria->add(CcFilesPeer::IS_SCHEDULED, true);
|
||||
$stmt = CcFilesPeer::doSelectStmt($filesCurrentlySetWithIsScheduledSelectCriteria);
|
||||
$filesCurrentlySetWithIsScheduled = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
|
||||
|
||||
$diff = array_diff($filesCurrentlySetWithIsScheduled, $filesScheduledInFuture);
|
||||
|
||||
|
||||
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
|
||||
$selectCriteria = new Criteria();
|
||||
$selectCriteria->add(CcFilesPeer::ID, $diff, Criteria::IN);
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Tracktype
|
||||
{
|
||||
private $_tracktypeInstance;
|
||||
|
||||
public function __construct($tracktypeId)
|
||||
{
|
||||
if (empty($tracktypeId)) {
|
||||
$this->_tracktypeInstance = $this->createTracktype();
|
||||
} else {
|
||||
$this->_tracktypeInstance = CcTracktypesQuery::create()->findPK($tracktypeId);
|
||||
|
||||
if (is_null($this->_tracktypeInstance)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->_tracktypeInstance->getDbId();
|
||||
}
|
||||
|
||||
public function setCode($code)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbCode($code);
|
||||
}
|
||||
|
||||
public function setTypeName($typeName)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbTypeName($typeName);
|
||||
}
|
||||
|
||||
public function setDescription($description)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbDescription($description);
|
||||
}
|
||||
|
||||
public function setVisibility($visibility)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbVisibility($visibility);
|
||||
}
|
||||
|
||||
public function getCode()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbCode();
|
||||
}
|
||||
|
||||
public function getTypeName()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbTypeName();
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbDescription();
|
||||
}
|
||||
|
||||
public function getVisibility()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbVisibility();
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->_tracktypeInstance->save();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if (!$this->_tracktypeInstance->isDeleted()) {
|
||||
$this->_tracktypeInstance->delete();
|
||||
}
|
||||
}
|
||||
|
||||
private function createTracktype()
|
||||
{
|
||||
$tracktype = new CcTracktypes();
|
||||
|
||||
return $tracktype;
|
||||
}
|
||||
|
||||
public static function getTracktypes($search=null)
|
||||
{
|
||||
return Application_Model_Tracktype::getTracktypesData(array(true), $search);
|
||||
}
|
||||
|
||||
public static function getTracktypesData(array $visible, $search=null)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql_gen = "SELECT id, code, type_name, description FROM cc_track_types ";
|
||||
|
||||
$visibility = array();
|
||||
$params = array();
|
||||
for ($i=0; $i<count($visible); $i++) {
|
||||
$p = ":visibility{$i}";
|
||||
$visibility[] = "visibility = $p";
|
||||
$params[$p] = $visible[$i];
|
||||
}
|
||||
|
||||
$sql_type = join(" OR ", $visibility);
|
||||
|
||||
$sql = $sql_gen ." WHERE (". $sql_type.") ";
|
||||
|
||||
$sql .= " AND code ILIKE :search";
|
||||
$params[":search"] = "%$search%";
|
||||
|
||||
$sql = $sql ." ORDER BY id";
|
||||
|
||||
return Application_Common_Database::prepareAndExecute($sql, $params, "all");
|
||||
}
|
||||
|
||||
public static function getTracktypeCount()
|
||||
{
|
||||
$sql_gen = "SELECT count(*) AS cnt FROM cc_track_types";
|
||||
|
||||
$query = Application_Common_Database::prepareAndExecute($sql_gen, array(),
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
return ($query !== false) ? $query : null;
|
||||
}
|
||||
|
||||
public static function getTracktypesDataTablesInfo($datatables)
|
||||
{
|
||||
|
||||
$con = Propel::getConnection(CcTracktypesPeer::DATABASE_NAME);
|
||||
|
||||
$displayColumns = array("id", "code", "type_name", "description", "visibility");
|
||||
$fromTable = "cc_track_types";
|
||||
$tracktypename = "";
|
||||
|
||||
$res = Application_Model_Datatables::findEntries($con, $displayColumns, $fromTable, $datatables);
|
||||
|
||||
foreach($res['aaData'] as $key => &$record){
|
||||
if ($record['code'] == $tracktypename) {
|
||||
$record['delete'] = "self";
|
||||
} else {
|
||||
$record['delete'] = "";
|
||||
}
|
||||
$record = array_map('htmlspecialchars', $record);
|
||||
}
|
||||
|
||||
$res['aaData'] = array_values($res['aaData']);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getTracktypeData($id)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT code, type_name, description, visibility, id
|
||||
FROM cc_track_types
|
||||
WHERE id = :id
|
||||
SQL;
|
||||
return Application_Common_Database::prepareAndExecute($sql, array(
|
||||
":id" => $id), 'single');
|
||||
}
|
||||
|
||||
}
|
|
@ -325,6 +325,11 @@ class Application_Model_User
|
|||
return Application_Model_User::getUsers(array('H'), $search);
|
||||
}
|
||||
|
||||
public static function getNonGuestUsers($search=null)
|
||||
{
|
||||
return Application_Model_User::getUsers(array('H','A','S','P'), $search);
|
||||
}
|
||||
|
||||
public static function getUsersDataTablesInfo($datatables)
|
||||
{
|
||||
|
||||
|
|
|
@ -146,10 +146,18 @@ class CcFiles extends BaseCcFiles {
|
|||
|
||||
self::validateFileArray($fileArray);
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$importedStorageDir = $storDir->getDirectory() . "imported/" . self::getOwnerId() . "/";
|
||||
$importedDbPath = "imported/" . self::getOwnerId() . "/";
|
||||
$artwork = FileDataHelper::saveArtworkData($filePath, $originalFilename, $importedStorageDir, $importedDbPath);
|
||||
$trackType = FileDataHelper::saveTrackType();
|
||||
|
||||
$file->fromArray($fileArray);
|
||||
$file->setDbOwnerId(self::getOwnerId());
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setDbTrackTitle($originalFilename);
|
||||
$file->setDbArtwork($artwork);
|
||||
$file->setDbTrackType($trackType);
|
||||
$file->setDbUtime($now);
|
||||
$file->setDbHidden(true);
|
||||
$file->save();
|
||||
|
@ -319,13 +327,13 @@ class CcFiles extends BaseCcFiles {
|
|||
{
|
||||
$cuein = $this->getDbCuein();
|
||||
$cueout = $this->getDbCueout();
|
||||
|
||||
|
||||
$cueinSec = Application_Common_DateHelper::calculateLengthInSeconds($cuein);
|
||||
$cueoutSec = Application_Common_DateHelper::calculateLengthInSeconds($cueout);
|
||||
$lengthSec = bcsub($cueoutSec, $cueinSec, 6);
|
||||
|
||||
|
||||
$length = Application_Common_DateHelper::secondsToPlaylistTime($lengthSec);
|
||||
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
|
@ -342,7 +350,7 @@ class CcFiles extends BaseCcFiles {
|
|||
return $this->getDbFileExists() && !$this->getDbHidden();
|
||||
}
|
||||
|
||||
public function reassignTo($user)
|
||||
public function reassignTo($user)
|
||||
{
|
||||
$this->setDbOwnerId( $user->getDbId() );
|
||||
$this->save();
|
||||
|
@ -408,6 +416,21 @@ class CcFiles extends BaseCcFiles {
|
|||
return Application_Common_OsPath::join($directory, $filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the artwork's absolute file path stored on disk.
|
||||
*/
|
||||
public function getAbsoluteArtworkPath()
|
||||
{
|
||||
$music_dir = Application_Model_MusicDir::getDirByPK($this->getDbDirectory());
|
||||
if (!$music_dir) {
|
||||
throw new Exception("Invalid music_dir for file " . $this->getDbId() . " in database.");
|
||||
}
|
||||
$directory = $music_dir->getDirectory();
|
||||
$filepath = $this->getDbArtwork();
|
||||
|
||||
return Application_Common_OsPath::join($directory, $filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Strips out fields from incoming request data that should never be modified
|
||||
|
@ -495,23 +518,29 @@ class CcFiles extends BaseCcFiles {
|
|||
{
|
||||
return is_file($this->getAbsoluteFilePath());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Deletes the file from the stor directory on disk.
|
||||
*/
|
||||
public function deletePhysicalFile()
|
||||
{
|
||||
$filepath = $this->getAbsoluteFilePath();
|
||||
$artworkpath = $this->getAbsoluteArtworkPath();
|
||||
if (file_exists($filepath)) {
|
||||
unlink($filepath);
|
||||
// also delete related images (dataURI and jpeg files)
|
||||
foreach (glob("$artworkpath*", GLOB_NOSORT) as $filename) {
|
||||
unlink($filename);
|
||||
}
|
||||
unlink($artworkpath);
|
||||
} else {
|
||||
throw new Exception("Could not locate file ".$filepath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This function refers to the file's Amazon S3 resource id.
|
||||
* Returns null because cc_files are stored on local disk.
|
||||
*/
|
||||
|
@ -519,10 +548,10 @@ class CcFiles extends BaseCcFiles {
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function getCcFileId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
|
||||
} // CcFiles
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_track_types' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcTracktypes extends BaseCcTracktypes {
|
||||
|
||||
} // CcTracktypes
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_track_types' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcTracktypesPeer extends BaseCcTracktypesPeer {
|
||||
|
||||
} // CcTracktypesPeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_track_types' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcTracktypesQuery extends BaseCcTracktypesQuery {
|
||||
|
||||
} // CcTracktypesQuery
|
|
@ -1,251 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'imported_podcast' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class ImportedPodcast extends BaseImportedPodcast
|
||||
{
|
||||
// These fields should never be modified with POST/PUT data
|
||||
private static $privateFields = array(
|
||||
"id",
|
||||
"url",
|
||||
"type",
|
||||
"owner"
|
||||
);
|
||||
|
||||
/** Creates a Podcast object from the given podcast URL.
|
||||
* This is used by our Podcast REST API
|
||||
*
|
||||
* @param $data An array containing the URL for a Podcast object.
|
||||
*
|
||||
* @return array - Podcast Array with a full list of episodes
|
||||
* @throws Exception
|
||||
* @throws InvalidPodcastException
|
||||
* @throws PodcastLimitReachedException
|
||||
*/
|
||||
public static function create($data)
|
||||
{
|
||||
if (Application_Service_PodcastService::podcastLimitReached()) {
|
||||
throw new PodcastLimitReachedException();
|
||||
}
|
||||
|
||||
$rss = Application_Service_PodcastService::getPodcastFeed($data["url"]);
|
||||
if (!$rss) {
|
||||
throw new InvalidPodcastException();
|
||||
}
|
||||
|
||||
// Ensure we are only creating Podcast with the given URL, and excluding
|
||||
// any extra data fields that may have been POSTED
|
||||
$podcastArray = array();
|
||||
$podcastArray["url"] = $data["url"];
|
||||
|
||||
$podcastArray["title"] = $rss->get_title();
|
||||
$podcastArray["description"] = $rss->get_description();
|
||||
$podcastArray["link"] = $rss->get_link();
|
||||
$podcastArray["language"] = $rss->get_language();
|
||||
$podcastArray["copyright"] = $rss->get_copyright();
|
||||
$podcastArray["creator"] = $rss->get_author()->get_name();
|
||||
$podcastArray["category"] = $rss->get_categories();
|
||||
|
||||
$itunesChannel = "http://www.itunes.com/dtds/podcast-1.0.dtd";
|
||||
|
||||
$itunesSubtitle = $rss->get_channel_tags($itunesChannel, 'subtitle');
|
||||
$podcastArray["itunes_subtitle"] = isset($itunesSubtitle[0]["data"]) ? $itunesSubtitle[0]["data"] : "";
|
||||
|
||||
$itunesCategory = $rss->get_channel_tags($itunesChannel, 'category');
|
||||
$categoryArray = array();
|
||||
foreach ($itunesCategory as $c => $data) {
|
||||
foreach ($data["attribs"] as $attrib) {
|
||||
array_push($categoryArray, $attrib["text"]);
|
||||
}
|
||||
}
|
||||
$podcastArray["itunes_category"] = implode(",", $categoryArray);
|
||||
|
||||
$itunesAuthor = $rss->get_channel_tags($itunesChannel, 'author');
|
||||
$podcastArray["itunes_author"] = isset($itunesAuthor[0]["data"]) ? $itunesAuthor[0]["data"] : "";
|
||||
|
||||
$itunesSummary = $rss->get_channel_tags($itunesChannel, 'summary');
|
||||
$podcastArray["itunes_summary"] = isset($itunesSummary[0]["data"]) ? $itunesSummary[0]["data"] : "";
|
||||
|
||||
$itunesKeywords = $rss->get_channel_tags($itunesChannel, 'keywords');
|
||||
$podcastArray["itunes_keywords"] = isset($itunesKeywords[0]["data"]) ? $itunesKeywords[0]["data"] : "";
|
||||
|
||||
$itunesExplicit = $rss->get_channel_tags($itunesChannel, 'explicit');
|
||||
$podcastArray["itunes_explicit"] = isset($itunesExplicit[0]["data"]) ? $itunesExplicit[0]["data"] : "";
|
||||
|
||||
self::validatePodcastMetadata($podcastArray);
|
||||
|
||||
try {
|
||||
$podcast = new ImportedPodcast();
|
||||
$podcast->fromArray($podcastArray, BasePeer::TYPE_FIELDNAME);
|
||||
$podcast->setDbOwner(self::getOwnerId());
|
||||
$podcast->setDbType(IMPORTED_PODCAST);
|
||||
$podcast->save();
|
||||
|
||||
return self::_generatePodcastArray($podcast, $rss);
|
||||
} catch(Exception $e) {
|
||||
$podcast->delete();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a Podcast's rss feed and returns all its episodes with
|
||||
* the Podcast object
|
||||
*
|
||||
* @param $podcastId
|
||||
*
|
||||
* @throws PodcastNotFoundException
|
||||
* @throws InvalidPodcastException
|
||||
* @return array - Podcast Array with a full list of episodes
|
||||
*/
|
||||
public static function getPodcastById($podcastId)
|
||||
{
|
||||
$podcast = PodcastQuery::create()->findPk($podcastId);
|
||||
if (!$podcast) {
|
||||
throw new PodcastNotFoundException();
|
||||
}
|
||||
|
||||
$rss = Application_Service_PodcastService::getPodcastFeed($podcast->getDbUrl());
|
||||
if (!$rss) {
|
||||
throw new InvalidPodcastException();
|
||||
}
|
||||
|
||||
return self::_generatePodcastArray($podcast, $rss);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a podcast object and a SimplePie feed object,
|
||||
* generate a data array to pass back to the front-end
|
||||
*
|
||||
* @param Podcast $podcast Podcast model object
|
||||
* @param SimplePie $rss SimplePie feed object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function _generatePodcastArray($podcast, $rss) {
|
||||
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
$podcastArray["episodes"] = array();
|
||||
foreach ($rss->get_items() as $item) {
|
||||
/** @var SimplePie_Item $item */
|
||||
array_push($podcastArray["episodes"], array(
|
||||
"guid" => $item->get_id(),
|
||||
"title" => $item->get_title(),
|
||||
"author" => $item->get_author()->get_name(),
|
||||
"description" => $item->get_description(),
|
||||
"pub_date" => $item->get_date("Y-m-d H:i:s"),
|
||||
"link" => $item->get_link(),
|
||||
"enclosure" => $item->get_enclosure()
|
||||
));
|
||||
}
|
||||
|
||||
return $podcastArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a Podcast object with the given metadata
|
||||
*
|
||||
* @param $podcastId
|
||||
* @param $data
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @throws PodcastNotFoundException
|
||||
*/
|
||||
public static function updateFromArray($podcastId, $data)
|
||||
{
|
||||
$podcast = PodcastQuery::create()->findPk($podcastId);
|
||||
if (!$podcast) {
|
||||
throw new PodcastNotFoundException();
|
||||
}
|
||||
|
||||
self::removePrivateFields($data);
|
||||
self::validatePodcastMetadata($data);
|
||||
|
||||
$podcast->fromArray($data, BasePeer::TYPE_FIELDNAME);
|
||||
$podcast->save();
|
||||
|
||||
return $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a Podcast and its podcast episodes
|
||||
*
|
||||
* @param $podcastId
|
||||
* @throws Exception
|
||||
* @throws PodcastNotFoundException
|
||||
*/
|
||||
public static function deleteById($podcastId)
|
||||
{
|
||||
$podcast = PodcastQuery::create()->findPk($podcastId);
|
||||
if ($podcast) {
|
||||
$podcast->delete();
|
||||
} else {
|
||||
throw new PodcastNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the podcast metadata to fit the table's column max size
|
||||
*
|
||||
* @param $podcastArray
|
||||
*/
|
||||
private static function validatePodcastMetadata(&$podcastArray)
|
||||
{
|
||||
$podcastTable = PodcastPeer::getTableMap();
|
||||
|
||||
foreach ($podcastArray as $key => &$value) {
|
||||
try {
|
||||
// Make sure column exists in table
|
||||
$columnMaxSize = $podcastTable->getColumn($key)->getSize();
|
||||
} catch (PropelException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen($value) > $columnMaxSize) {
|
||||
$value = substr($value, 0, $podcastTable->getColumn($key)->getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function removePrivateFields(&$data)
|
||||
{
|
||||
foreach (self::$privateFields as $key) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO move this somewhere where it makes sense
|
||||
private static function getOwnerId()
|
||||
{
|
||||
try {
|
||||
if (Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$service_user = new Application_Service_UserService();
|
||||
return $service_user->getCurrentUser()->getDbId();
|
||||
} else {
|
||||
$defaultOwner = CcSubjsQuery::create()
|
||||
->filterByDbType('A')
|
||||
->orderByDbId()
|
||||
->findOne();
|
||||
if (!$defaultOwner) {
|
||||
// what to do if there is no admin user?
|
||||
// should we handle this case?
|
||||
return null;
|
||||
}
|
||||
return $defaultOwner->getDbId();
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ class CcBlockTableMap extends TableMap
|
|||
$this->addForeignKey('creator_id', 'DbCreatorId', 'INTEGER', 'cc_subjs', 'id', false, null, null);
|
||||
$this->addColumn('description', 'DbDescription', 'VARCHAR', false, 512, null);
|
||||
$this->addColumn('length', 'DbLength', 'VARCHAR', false, null, '00:00:00');
|
||||
$this->addColumn('type', 'DbType', 'VARCHAR', false, 7, 'static');
|
||||
$this->addColumn('type', 'DbType', 'VARCHAR', false, 7, 'dynamic');
|
||||
// validators
|
||||
} // initialize()
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class CcBlockcriteriaTableMap extends TableMap
|
|||
$this->addColumn('modifier', 'DbModifier', 'VARCHAR', true, 16, null);
|
||||
$this->addColumn('value', 'DbValue', 'VARCHAR', true, 512, null);
|
||||
$this->addColumn('extra', 'DbExtra', 'VARCHAR', false, 512, null);
|
||||
$this->addColumn('criteriagroup', 'DbCriteriaGroup', 'INTEGER', false, null, null);
|
||||
$this->addForeignKey('block_id', 'DbBlockId', 'INTEGER', 'cc_block', 'id', true, null, null);
|
||||
// validators
|
||||
} // initialize()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue