├── .gitignore ├── bc-mapi-cache.php ├── README.md └── bc-mapi.php /.gitignore: -------------------------------------------------------------------------------- 1 | /Icon.png -------------------------------------------------------------------------------- /bc-mapi-cache.php: -------------------------------------------------------------------------------- 1 | 12 | * 13 | * Permission is hereby granted, free of charge, to any person obtaining a 14 | * copy of this software and associated documentation files (the �Software�), 15 | * to deal in the Software without restriction, including without limitation 16 | * the rights to use, copy, modify, alter, merge, publish, distribute, 17 | * sublicense, and/or sell copies of the Software, and to permit persons to 18 | * whom the Software is furnished to do so, subject to the following conditions: 19 | * 20 | * 1. The permission granted herein does not extend to commercial use of 21 | * the Software by entities primarily engaged in providing online video and 22 | * related services. 23 | * 24 | * 2. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, SUITABILITY, TITLE, 27 | * NONINFRINGEMENT, OR THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 28 | * SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 29 | * CLAIM, DAMAGES OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF 30 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 31 | * THE SOFTWARE OR THE USE, INABILITY TO USE, OR OTHER DEALINGS IN THE SOFTWARE. 32 | * 33 | * 3. NONE OF THE AUTHORS, CONTRIBUTORS, NOR BRIGHTCOVE SHALL BE RESPONSIBLE 34 | * IN ANY MANNER FOR USE OF THE SOFTWARE. THE SOFTWARE IS PROVIDED FOR YOUR 35 | * CONVENIENCE AND ANY USE IS SOLELY AT YOUR OWN RISK. NO MAINTENANCE AND/OR 36 | * SUPPORT OF ANY KIND IS PROVIDED FOR THE SOFTWARE. 37 | */ 38 | 39 | class BCMAPICache 40 | { 41 | public static $extension = NULL; 42 | public static $location = NULL; 43 | public static $memcached = NULL; 44 | public static $port = NULL; 45 | public static $time = 0; 46 | public static $type = NULL; 47 | 48 | /** 49 | * The constructor for the BCMAPICache class. 50 | * @access Public 51 | * @since 1.0.0 52 | * @param string [$type] The type of caching method to use, either 'file' or 'memcached' 53 | * @param int [$time] How many seconds until cache files are considered cold 54 | * @param string [$location] The absolute path of the cache directory (file) or host (memcached) 55 | * @param string [$extension] The file extension for cache items (file only) 56 | * @param int [$port] The port to use (Memcached only) 57 | */ 58 | public function __construct($type = 'file', $time = 600, $location, $extension = '.c', $port = 11211) 59 | { 60 | 61 | if(strtolower($type) == 'file') 62 | { 63 | $type = 'file'; 64 | } else if(strtolower($type) == 'memcache' || strtolower($type) == 'memcached') { 65 | $type = 'memcached'; 66 | 67 | $memcached = new Memcached(); 68 | $memcached->addServer($location, $port); 69 | 70 | self::$memcached = $memcached; 71 | } else { 72 | $type = FALSE; 73 | } 74 | 75 | self::$extension = $extension; 76 | self::$location = $location; 77 | self::$port = $port; 78 | self::$time = $time; 79 | self::$type = $type; 80 | } 81 | 82 | /** 83 | * Retrieves any valid cached data. 84 | * @access Public 85 | * @since 1.0.1 86 | * @param string [$key] The cache file key 87 | * @return mixed The cached data if valid, otherwise FALSE 88 | */ 89 | public function get($key) 90 | { 91 | if(self::$type == 'file') 92 | { 93 | $file = self::$location . md5($key) . self::$extension; 94 | 95 | if(file_exists($file) && is_readable($file)) 96 | { 97 | if((time() - filemtime($file)) <= self::$time) 98 | { 99 | return file_get_contents($file); 100 | } 101 | } 102 | 103 | return FALSE; 104 | } else if(self::$type == 'memcached') { 105 | $data = self::$memcached->get($key); 106 | 107 | if(self::$memcached->getResultCode() == Memcached::RES_SUCCESS) 108 | { 109 | return $data; 110 | } 111 | } else { 112 | return FALSE; 113 | } 114 | } 115 | 116 | /** 117 | * Creates a cache of data. 118 | * @access Public 119 | * @since 1.0.0 120 | * @param string [$key] The cache file key 121 | * @param mixed [$data] The data to cache 122 | */ 123 | public function set($key, $data) 124 | { 125 | if(self::$type == 'file') 126 | { 127 | $file = self::$location . md5($key) . self::$extension; 128 | 129 | if(is_writable(self::$location)) 130 | { 131 | $handle = fopen($file, 'w'); 132 | fwrite($handle, json_encode($data)); 133 | fclose($handle); 134 | } 135 | } else if(self::$type == 'memcached') { 136 | self::$memcached->set($key, $data, time() + self::$time); 137 | } else { 138 | return FALSE; 139 | } 140 | } 141 | } 142 | 143 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | About 2 | ===== 3 | 4 | This project provides a starting point for integrating the Brightcove Media 5 | API into your application. It provides simple ways to interact with the 6 | API, as well as a long list of helper functions. 7 | 8 | Compatibility Notice 9 | ==================== 10 | 11 | Please note that the PHP MAPI Wrapper v2.0 is **not** compatible with any 12 | previous versions (when it was known as "Echove"). The class name has been 13 | changed, numerous functions have been re-named, and methods have been 14 | updated to take advantage of Brightcove API changes. 15 | 16 | If you need assistance in determining what changes have been made, please 17 | send an e-mail to opensource@brightcove.com with your request. 18 | 19 | Requirements 20 | ============ 21 | 22 | PHP version 5.2 or greater, or you must have the JavaScript Object Notation 23 | (JSON) PECL package. For more information on the JSON PECL package, please 24 | visit the [PHP JSON](http://www.php.net/json) package website. 25 | 26 | Using Cache Extension 27 | ===================== 28 | 29 | The PHP MAPI Wrapper includes a caching extension. To use this feature, 30 | include the file on your page along with the core PHP MAPI Wrapper file. 31 | 32 | require('bc-mapi.php'); 33 | require('bc-mapi-cache.php'); 34 | 35 | Then, after instantiating the core class, you can instantiate the caching 36 | extension. 37 | 38 | // Using flat files 39 | $bc = new BCMAPI(API_READ_TOKEN, API_WRITE_TOKEN); 40 | $bc_cache = new BCMAPICache('file', 600, '/var/www/myWebSite/cache/', '.cache'); 41 | 42 | // Using Memcached 43 | $bc = new BCMAPI(API_READ_TOKEN, API_WRITE_TOKEN); 44 | $bc_cache = new BCMAPICache('memcached', 600, 'localhost', NULL, 11211); 45 | 46 | The parameters for the constructor are: 47 | 48 | * [string] The type of caching method to use, either 'file' or 'memcached' 49 | * [int] How many seconds until cache files are considered cold 50 | * [string] The absolute path of the cache directory (file) or host (memcached) 51 | * [string] The file extension for cache items (file only) 52 | * [int] The port to use (Memcached only) 53 | 54 | * * * 55 | 56 | Examples 57 | ======== 58 | 59 | Instantiation 60 | ------------- 61 | 62 | This example shows how to instantiate, or start, the BCMAPI PHP class. The first token, which is for the Read API, is required. The second token is for the Write API and is optional. 63 | 64 | // Include the BCMAPI SDK 65 | require('bc-mapi.php'); 66 | 67 | // Instantiate the class, passing it our Brightcove API tokens (read, then write) 68 | $bc = new BCMAPI( 69 | 'READ_API_TOKEN', 70 | 'WRITE_API_TOKEN' 71 | ); 72 | 73 | // You may optionally include the caching extension provided with BCMAPI... 74 | require('bc-mapi-cache.php'); 75 | 76 | // Using flat files 77 | $bc_cache = new BCMAPICache('file', 600, '/var/www/myWebSite/cache/', '.cache'); 78 | 79 | // Using Memcached 80 | $bc_cache = new BCMAPICache('memcached', 600, 'localhost', NULL, 11211); 81 | 82 | 83 | Properties 84 | ---------- 85 | This example shows how to set and retrieve some of the BCMAPI properties that can be used for debugging and additional settings. 86 | 87 | // Turn on HTTPS mode 88 | $bc->__set('secure', TRUE); 89 | 90 | // Make our API call 91 | $videos = $bc->find('allVideos'); 92 | 93 | // Determine how many possible results there are 94 | echo 'Total Videos: ' . $bc->total_count . '<br />'; 95 | 96 | // Make our API call 97 | $videos = $bc->findAll(); 98 | 99 | // Determine how many times we called the Brightcove API 100 | echo 'API Calls: ' . $bc->__get('api_calls'); 101 | 102 | 103 | Regional Support (Internationalization) 104 | --------------------------------------- 105 | This example shows how to change the API URLs for supporting international regions. 106 | 107 | // Change our region to Japan 108 | $bc->__set('url_read', 'api.brightcove.co.jp/services/library?'); 109 | $bc->__set('url_write', 'api.brightcove.co.jp/services/post'); 110 | 111 | 112 | Error Handling 113 | -------------- 114 | This example shows how to utilize the built-in error handling in BCMAPI. 115 | 116 | // Create a try/catch 117 | try { 118 | // Make our API call 119 | $video = $bc->find('find_video_by_id', 123456789); 120 | } catch(Exception $error) { 121 | // Handle our error 122 | echo $error; 123 | die(); 124 | } 125 | 126 | 127 | Find Query 128 | ---------- 129 | This example shows how to retrieve a video from a Brightcove account. 130 | 131 | // Make our API call 132 | $video = $bc->find('find_video_by_id', 123456789); 133 | 134 | // Print the video name and ID 135 | echo $video->name . ' (' . $video->id . ')'; 136 | 137 | 138 | Find Query - Shorthand 139 | ---------------------- 140 | This example shows how you can use shorthand method names to make code easier to write and read. 141 | 142 | // Make our API call 143 | $video = $bc->find('videoById', 123456789); 144 | 145 | 146 | Find Query - Additional Parameters 147 | ---------------------------------- 148 | This example shows how to define additional API call parameters using a key-value array. 149 | 150 | // Define our parameters 151 | $params = array( 152 | 'id' => 123456789, 153 | 'video_fields' => 'video_id,name,shortDescription' 154 | ); 155 | 156 | // Make our API call 157 | $video = $bc->find('videoById', $params); 158 | 159 | 160 | Find Query - True Find All 161 | -------------------------- 162 | Brightcove limits the "find_all_videos" call to 100 results, requiring pagination and numerous API calls. This example shows how to use the findAll() method to do this automatically. 163 | **WARNING: Use very carefully** * 164 | // Define our parameters 165 | $params = array( 166 | 'video_fields' => 'id,name' 167 | ); 168 | 169 | // Make our API call 170 | $videos = $bc->findAll('video', $params); 171 | 172 | 173 | Search Query 174 | ------------ 175 | This example shows how to search for a video about "gates", but not "Bill Gates". 176 | 177 | // Define our parameters 178 | $params = array( 179 | 'video_fields' => 'id,name,shortDescription' 180 | ); 181 | 182 | // Set our search terms 183 | $terms = array( 184 | 'all' => 'display_name:gates', 185 | 'none' => 'display_name:bill' 186 | ); 187 | 188 | // Make our API call 189 | $videos = $bc->search('video', $terms, $params); 190 | 191 | 192 | Search Query (Multiple-Field Search) 193 | ------------------------------------ 194 | This example shows how to search for a video with "jobs" in the title AND tags. 195 | 196 | // Define our parameters 197 | $params = array( 198 | 'video_fields' => 'id,name,shortDescription' 199 | ); 200 | 201 | // Set our search terms 202 | $terms = array( 203 | 'all' => 'display_name:jobs,tag:jobs' 204 | ); 205 | 206 | // Make our API call 207 | $videos = $bc->search('video', $terms, $params); 208 | 209 | 210 | Create - Video 211 | -------------- 212 | This example details how to upload a video to a Brightcove account. This code is handling data that was passed from a form. Note that we re-name the uploaded movie to its original name rather than the random string generated when it's placed in the "tmp" directory; this is because the tmp_name does not include the file extension. The video name is a required field. 213 | 214 | // Create an array of meta data from our form fields 215 | $metaData = array( 216 | 'name' => $_POST['videoName'], 217 | 'shortDescription' => $_POST['videoShortDescription'] 218 | ); 219 | 220 | // Move the file out of 'tmp', or rename 221 | rename($_FILES['videoFile']['tmp_name'], '/tmp/' . $_FILES['videoFile']['name']); 222 | $file = '/tmp/' . $_FILES['videoFile']['name']; 223 | 224 | // Upload the video and save the video ID 225 | $id = $bc->createMedia('video', $file, $metaData); 226 | 227 | 228 | Create - Image 229 | -------------- 230 | This example details how to upload a image to a Brightcove account. This code is handling data that was passed from a form. Note that we re-name the uploaded image to its original name rather than the random string generated when it's placed in the "tmp" directory; this is because the tmp_name does not include the file extension. 231 | 232 | // Create an array of meta data from our form fields 233 | $metaData = array( 234 | 'type' => 'VIDEO_STILL', 235 | 'displayName' => $_POST['imageName'] 236 | ); 237 | 238 | // Move the file out of 'tmp', or rename 239 | rename($_FILES['bcImage']['tmp_name'], '/tmp/' . $_FILES['bcImage']['name']); 240 | $file = '/tmp/' . $_FILES['bcImage']['name']; 241 | 242 | // Upload the image, assign to a video, and save the image asset ID 243 | $id = $bc->createImage('video', $file, $metaData, 123456789); 244 | 245 | 246 | Create - Playlist 247 | ----------------- 248 | This example shows how to create a playlist in a Brightcove account. The code is handling data that was passed from a form. The name, video IDs, and playlist type are all required fields. 249 | 250 | // Take a comma-separated string of video IDs and explode into an array 251 | $videoIds = explode(',', $_POST['playlistVideoIds']); 252 | 253 | // Create an array of meta data from our form fields 254 | $metaData = array( 255 | 'name' => $_POST['playlistName'], 256 | 'shortDescription' => $_POST['playlistShortDescription'], 257 | 'videoIds' => $videoIds, 258 | 'playlistType' => 'explicit' 259 | ); 260 | 261 | // Create the playlist and save the playlist ID 262 | $id = $bc->createPlaylist('video', $metaData); 263 | 264 | 265 | Update - Video / Playlist 266 | ------------------------- 267 | This example shows how to update a video, but the same method will work for a playlist. 268 | 269 | // Create an array of the new meta data 270 | $metaData = array( 271 | 'id' => 123456789, 272 | 'shortDescription' => 'Our new short description.' 273 | ); 274 | 275 | // Update a video with the new meta data 276 | $bc->update('video', $metaData); 277 | 278 | 279 | Delete - Video / Playlist 280 | ------------------------- 281 | This example shows how to delete a video, but the same method will work for a playlist. Cascaded deletion means that the video will also be removed from all playlists and players. 282 | 283 | // Delete a 'video' by ID, and cascade the deletion 284 | $bc->delete('video', 123456789, NULL, TRUE); 285 | 286 | 287 | Status - Video Upload 288 | --------------------- 289 | This example shows how to determine the status of a video being uploaded to a Brightcove account. 290 | 291 | // Retrieve upload status 292 | $status = $bc->getStatus('video', 123456789); 293 | 294 | 295 | Share Video 296 | ----------- 297 | This example shows how to share a video with another Brightcove account. A list of the new video IDs will be returned. Note that sharing must be enabled between the two accounts. 298 | 299 | // List the accounts to share the video with 300 | $ids = array( 301 | 123456789 302 | ); 303 | 304 | // Share the videos, and save the new video IDs 305 | $new_ids = $bc->shareMedia('video', 123456789, $ids); 306 | 307 | 308 | Add To / Remove From Playlist 309 | ----------------------------- 310 | This example shows how to add an asset to a playlist, as well as how to remove an asset from a playlist. You may pass an array of video IDs, or a single video ID. 311 | 312 | // Add two videos to a playlist 313 | $bc->addToPlaylist(555555555, array(123456789, 987654321)); 314 | 315 | // Remove a video from a playlist 316 | $bc->removeFromPlaylist(555555555, 987654321); 317 | 318 | 319 | SEF URLs / Time Formatting 320 | -------------------------- 321 | This example shows the BCMAPI convenience methods that convert video titles into a search-engine friendly format and video lengths into formatted strings. 322 | 323 | // Make our API call 324 | $video = $bc->find('videoById', 123456789); 325 | 326 | // Print the SEF video name and formatted duration 327 | echo 'Name: ' . $bc->sef($video->name) . '<br />'; 328 | echo 'Duration:' . $bc->time($video->length) . '<br />'; 329 | 330 | 331 | Automatic Timestamp Conversion 332 | ------------------------------ 333 | To more seamlessly bridge the Brightcove API into PHP the 'from_date' parameter for the "find_modified_videos" call should be provided as seconds since Epoch (UNIX timestamp) instead of minutes since, as the Brightcove Media API documentation states. You can still pass minutes if you prefer. 334 | 335 | // Set timestamp to 7 days ago (in seconds) 336 | $time = time() - 604800; 337 | 338 | // Make our API call 339 | $videos = $bc->find('modifiedVideos', $time); 340 | 341 | // Set timestamp to 7 days ago (in minutes) 342 | $time = floor((time() - 604800) / 60); 343 | 344 | // Make our API call 345 | $videos = $bc->find('modifiedVideos', $time); 346 | 347 | 348 | Tags 349 | ---- 350 | This example demonstrates how a tag with a value of "abc=xyz" can easily be parsed into a key-value array pair. 351 | 352 | // Make our API call 353 | $video = $bc->find('videoById', 123456789); 354 | 355 | // Parse any key=value tags into array 356 | $video->tags = $bc->tags($video->tags); 357 | 358 | // Print out each tag 359 | foreach($video->tags as $key => $value) 360 | { 361 | echo $key . ': ' . $value . '<br />'; 362 | } 363 | 364 | 365 | Tag Filter 366 | ---------- 367 | This example shows how to remove all videos that don't contain any of the listed tags. 368 | 369 | // Make our API call 370 | $videos = $bc->find('allVideos'); 371 | 372 | // Remove all videos without specified tags 373 | $videos = $bc->filter($videos, 'published=true,include=true'); 374 | 375 | * * * 376 | 377 | Methods 378 | ======= 379 | 380 | BCMAPI 381 | ------ 382 | The constructor for the BCMAPI class. 383 | 384 | ### Arguments 385 | - **token_read** *The read API token for the Brightcove account* 386 | 387 | Default: NULL 388 | Type: String 389 | 390 | - **token_write** *The write API token for the Brightcove account* 391 | 392 | Default: NULL 393 | Type: String 394 | 395 | 396 | ### Properties 397 | - **api_calls** *Private - The total number of API calls that have been processed* 398 | 399 | Type: Integer 400 | 401 | - **media_delivery** *Private - What type of URL to return for UDS assets* 402 | 403 | Type: String 404 | 405 | - **page_number** *Public - The value of the last 'page_number' return* 406 | 407 | Type: Integer 408 | 409 | - **page_size** *Public - The value of the last 'page_size' return* 410 | 411 | Type: Integer 412 | 413 | - **secure** *Private - Whether BCMAPI is operating over HTTPS* 414 | 415 | Type: Boolean 416 | 417 | - **show_notices** *Private - Whether BCMAPI will send error notices* 418 | 419 | Type: Boolean 420 | 421 | - **timeout_attempts** *Private - The number of times to retry a call in case of API timeout* 422 | 423 | Type: Integer 424 | 425 | - **timeout_delay** *Private - Number of seconds to delay retry attempts* 426 | 427 | Type: Integer 428 | 429 | - **timeout_retry** *Private - Whether to automatically retry calls that fail due to API timeout* 430 | 431 | Type: Boolean 432 | 433 | - **token_read** *Private - The read Brightcove token to use* 434 | 435 | Type: String 436 | 437 | - **token_write** *Private - The write Brightcove token to use* 438 | 439 | Type: String 440 | 441 | - **total_count** *Public - The value of the last 'total_count' return* 442 | 443 | Type: Integer 444 | 445 | __set 446 | ----- 447 | Sets a property of the BCMAPI class. 448 | 449 | ### Arguments 450 | - **key** *The property to set* 451 | 452 | Type: String 453 | 454 | - **value** *The new value for the property* 455 | 456 | Type: Mixed 457 | 458 | 459 | ### Return Value 460 | The new value of the property 461 | 462 | Type: Mixed 463 | 464 | 465 | __get 466 | ----- 467 | Retrieves a property of the BCMAPI class. 468 | 469 | ### Arguments 470 | - **key** *The property to retrieve* 471 | 472 | Type: String 473 | 474 | ### Return Value 475 | The value of the property 476 | 477 | Type: Mixed 478 | 479 | find 480 | ---- 481 | Formats the request for any API "Find" methods and retrieves the data. The requested call may be written in a shortened version (e.g. "allVideos" or "all_videos" instead of "find_all_videos"). If the call supports get_item_count, it is defaulted to TRUE. 482 | 483 | ### Arguments 484 | - **call** *The requested API method* 485 | 486 | Type: String 487 | 488 | - **params** *A key-value array of API parameters, or a single value that matches the default* 489 | 490 | Default: NULL 491 | Type: Mixed 492 | 493 | ### Return Value 494 | An object containing all API return data 495 | 496 | Type: Object 497 | 498 | findAll 499 | ------- 500 | Finds all media assets in account, ignoring pagination. This method should be used with extreme care as accounts with a large library of assets will require a high number of API calls. This could significantly affect performance and may result in additional charges from Brightcove. 501 | 502 | ### Arguments 503 | - **type** *The type of object to retrieve* 504 | 505 | Default: video 506 | Type: String 507 | 508 | - **params** *A key-value array of API parameters* 509 | 510 | Default: NULL 511 | Type: Array 512 | 513 | 514 | ### Return Value 515 | An object containing all API return data 516 | 517 | Type: Object 518 | 519 | 520 | search 521 | ------ 522 | Performs a search of video meta data 523 | 524 | ### Arguments 525 | - **type** *The type of objects to retrieve* 526 | 527 | Default: video 528 | Type: String 529 | 530 | - **terms** *The terms to use for the search* 531 | 532 | Default: NULL 533 | Type: Array 534 | 535 | - **params** *A key-value array of API parameters* 536 | 537 | Default: NULL 538 | Type: Mixed 539 | 540 | ### Return Value 541 | An object containing all API return data 542 | 543 | Type: Object 544 | 545 | 546 | createMedia 547 | ----------- 548 | Uploads a media asset file to Brightcove. When creating an asset from an upload it is suggested that you first move the file out of the temporary directory where PHP placed it and rename the file to it's original name. An asset name and short description are both required; leaving these values blank will cause them to be populated with the current UNIX timestamp. Certain upload settings are not allowed depending upon what default have already been set, and depending on the type of file being uploaded. Setting the incorrect values for these parameters will trigger a notice. 549 | 550 | ### Arguments 551 | - **type** *The type of object to upload* 552 | 553 | Default: video 554 | Type: String 555 | 556 | - **file** *The location of the temporary file* 557 | 558 | Default: NULL 559 | Type: String 560 | 561 | - **meta** *The media asset information* 562 | 563 | Type: Array 564 | 565 | - **options** *Optional upload values* 566 | 567 | Default: NULL 568 | Type: Array 569 | 570 | ### Return Value 571 | The media asset ID 572 | 573 | Type: String 574 | 575 | 576 | createPlaylist 577 | -------------- 578 | Creates a playlist. 579 | 580 | ### Arguments 581 | - **type** *The type of playlist to create* 582 | 583 | Default: video 584 | Type: String 585 | 586 | - **meta** *The playlist information* 587 | 588 | Type: Array 589 | 590 | ### Return Value 591 | The playlist ID 592 | 593 | Type: String 594 | 595 | 596 | update 597 | ------ 598 | Updates a media asset. Only the meta data that has changed needs to be passed along. Be sure to include the asset ID, though. 599 | 600 | ### Arguments 601 | - **type** *The type of object to update* 602 | 603 | Default: video 604 | Type: String 605 | 606 | - **meta** *The information for the media asset* 607 | 608 | Type: Array 609 | 610 | ### Return Value 611 | The new DTO 612 | 613 | Type: DTO 614 | 615 | 616 | createImage 617 | ----------- 618 | Uploads a media image file to Brightcove. When creating an image it is suggested that you first move the file out of the temporary directory where PHP placed it and rename the file to it's original name. 619 | 620 | ### Arguments 621 | - **type** *The type of object to upload image for* 622 | 623 | Default: video 624 | Type: String 625 | 626 | - **file** *The location of the temporary file* 627 | 628 | Default: NULL 629 | Type: String 630 | 631 | - **meta** *The image information* 632 | 633 | Type: Array 634 | 635 | - **id** *The ID of the media asset to assign the image to* 636 | 637 | Default: NULL 638 | Type: Integer 639 | 640 | - **ref_id** *The reference ID of the media asset to assign the image to* 641 | 642 | Default: NULL 643 | Type: String 644 | 645 | - **resize** *Whether or not to resize the image on upload* 646 | 647 | Default: TRUE 648 | Type: Boolean 649 | 650 | 651 | ### Return Value 652 | The image asset 653 | 654 | Type: Mixed 655 | 656 | 657 | createOverlay 658 | ------------- 659 | Uploads a logo overlay file to Brightcove. When creating a logo overlay it is suggested that you first move the file out of the temporary directory where PHP placed it and rename the file to it's original name. 660 | 661 | ### Arguments 662 | - **file** *The location of the temporary file* 663 | 664 | Default: NULL 665 | Type: String 666 | 667 | - **meta** *The logo overlay information* 668 | 669 | Type: Array 670 | 671 | - **id** *The ID of the media asset to assign the logo overlay to* 672 | 673 | Default: NULL 674 | Type: Integer 675 | 676 | - **ref_id** *The reference ID of the media asset to assign the logo overlay to* 677 | 678 | Default: NULL 679 | Type: String 680 | 681 | 682 | ### Return Value 683 | The logo overlay asset 684 | 685 | Type: Mixed 686 | 687 | 688 | deleteOverlay 689 | ------------- 690 | Deletes a logo overlay. 691 | 692 | ### Arguments 693 | - **id** *The ID of the media asset* 694 | 695 | Default: NULL 696 | Type: Integer 697 | 698 | - **ref_id** *The reference ID of the media asset* 699 | 700 | Default: NULL 701 | Type: String 702 | 703 | - **options** *Optional values* 704 | 705 | Default: NULL 706 | Type: Array 707 | 708 | 709 | delete 710 | ------ 711 | Deletes a media asset. Either an ID or Reference ID must be passed. 712 | 713 | ### Arguments 714 | - **type** *The type of the item to delete* 715 | 716 | Default: video 717 | Type: String 718 | 719 | - **id** *The ID of the media asset* 720 | 721 | Default: NULL 722 | Type: Integer 723 | 724 | - **ref_id** *The reference ID of the media asset* 725 | 726 | Default: NULL 727 | Type: String 728 | 729 | - **options** *Optional values* 730 | 731 | Default: NULL 732 | Type: Array 733 | 734 | 735 | getStatus 736 | --------- 737 | Retrieves the status of a media asset upload. 738 | 739 | ### Arguments 740 | - **type** *The type of object to check* 741 | 742 | Default: video 743 | Type: String 744 | 745 | - **id** *The ID of the media asset* 746 | 747 | Default: NULL 748 | Type: String 749 | 750 | - **ref_id** *The reference ID of the media asset* 751 | 752 | Default: TRUE 753 | Type: String 754 | 755 | ### Return Value 756 | The upload status 757 | 758 | Type: String 759 | 760 | 761 | shareMedia 762 | ---------- 763 | Shares a media asset with the selected accounts. Sharing must be enabled between the two accounts. 764 | 765 | ### Arguments 766 | - **type** *The type of object to share* 767 | 768 | Default: video 769 | Type: String 770 | 771 | - **id** *The ID of the media asset* 772 | 773 | Type: Integer 774 | 775 | - **account_ids** *An array of account IDs* 776 | 777 | Type: Array 778 | 779 | - **accept** *Whether the share should be auto accepted* 780 | 781 | Default: FALSE 782 | Type: Boolean 783 | 784 | - **force** *Whether the share should overwrite existing copies of the media* 785 | 786 | Default: FALSE 787 | Type: Boolean 788 | 789 | ### Return Value 790 | The new media asset IDs 791 | 792 | Type: Array 793 | 794 | 795 | removeFromPlaylist 796 | ------------------ 797 | Removes assets from a playlist. 798 | 799 | ### Arguments 800 | - **playlist_id** *The ID of the playlist to modify* 801 | 802 | Type: Integer 803 | 804 | - **video_ids** *An array of video IDs to delete from the playlist* 805 | 806 | Type: Array 807 | 808 | ### Return Value 809 | The new playlist DTO 810 | 811 | Type: Array 812 | 813 | 814 | addToPlaylist 815 | ------------- 816 | Adds assets to a playlist. 817 | 818 | ### Arguments 819 | - **playlist_id** *The ID of the playlist to modify* 820 | 821 | Type: Integer 822 | 823 | - **video_ids** *An array of video IDs to add to the playlist* 824 | 825 | Type: Array 826 | 827 | ### Return Value 828 | The new playlist DTO 829 | 830 | Type: Array 831 | 832 | 833 | convertTime 834 | ----------- 835 | Converts milliseconds to formatted time or seconds. 836 | 837 | ### Arguments 838 | - **ms** *The length of the media asset in milliseconds* 839 | 840 | Default: 841 | Type: Integer 842 | 843 | - **seconds** *Whether to return only seconds* 844 | 845 | Default: FALSE 846 | Type: Boolean 847 | 848 | 849 | ### Return Value 850 | The formatted length or total seconds of the media asset 851 | 852 | Type: Mixed 853 | 854 | 855 | convertTags 856 | ----------- 857 | Parses media asset tags array into a key-value array. 858 | 859 | ### Arguments 860 | - **tags** *The tags array from a media asset DTO* 861 | 862 | Default: 863 | Type: Array 864 | 865 | - **implode** *Return array to Brightcove format* 866 | 867 | Default: FALSE 868 | Type: Boolean 869 | 870 | ### Return Value 871 | A key-value array of tags, or a comma-separated string 872 | 873 | Type: Mixed 874 | 875 | 876 | tagsFilter 877 | ---------- 878 | Removes assets that don't contain the appropriate tags. 879 | 880 | ### Arguments 881 | - **videos** *All the assets you wish to filter* 882 | 883 | Default: 884 | Type: Array 885 | 886 | - **tag** *A comma-separated list of tags to filter on* 887 | 888 | Default: 889 | Type: String 890 | 891 | ### Return Value 892 | The filtered list of assets 893 | 894 | Type: Array 895 | 896 | 897 | sef 898 | --- 899 | Formats a media asset name to be search-engine friendly. 900 | 901 | ### Arguments 902 | - **name** *The asset name* 903 | 904 | Default: 905 | Type: String 906 | 907 | ### Return Value 908 | The search-engine friendly asset name 909 | 910 | Type: String 911 | 912 | 913 | BCMAPICache 914 | ----------- 915 | The constructor for the BCMAPICache class. 916 | 917 | ### Arguments 918 | - **type** *The type of caching method to use, either 'file' or 'memcached'* 919 | 920 | Default: file 921 | Type: String 922 | 923 | - **time** *How many seconds until cache files are considered cold* 924 | 925 | Default: 600 926 | Type: Integer 927 | 928 | - **location** *The absolute path of the cache directory (file) or host (memcached)* 929 | 930 | Default: 931 | Type: String 932 | 933 | - **extension** *The file extension for cache items (file only)* 934 | 935 | Default: .c 936 | Type: String 937 | 938 | - **port** 939 | 940 | Default: 11211 941 | Type: Integer 942 | 943 | 944 | ### Properties 945 | 946 | - **extension** *Public - The file extension for cache items (file only)* 947 | 948 | Type: String 949 | 950 | - **location** *Public - The absolute path of the cache directory (file) or host (memcached)* 951 | 952 | Type: String 953 | 954 | - **memcached** *Public - The Memcached object, if valid* 955 | 956 | Type: Object 957 | 958 | - **port** *Public - The port to use (Memcached only)* 959 | 960 | Type: Integer 961 | 962 | - **time** *Public - How many seconds until cache files are considered cold* 963 | 964 | Type: Integer 965 | 966 | - **type** *Public - The type of caching method to use, either 'file' or 'memcached'* 967 | 968 | Type: String 969 | 970 | * * * 971 | 972 | Errors 973 | ====== 974 | 975 | BCMAPIApiError 976 | -------------- 977 | This is the most generic error returned from BCMAPI as it is thrown whenever the API returns unexpected data, or an error. The API return data will be included in the error to help you diagnose the problem. 978 | 979 | BCMAPIDeprecated 980 | ---------------- 981 | The requested item is no longer supported by Brightcove and/or BCMAPI. Stop using this method as early as possible, as the item could be removed in any future release. 982 | 983 | BCMAPIDtoDoesNotExist 984 | --------------------- 985 | The specified asset does not exist in the Brightcove system. Ensure you're using the correct ID. 986 | 987 | BCMAPIIdNotProvided 988 | ------------------- 989 | An ID has not been passed to the method (usually a "delete" or "share" function). Include the ID parameter to resolve the error. 990 | 991 | BCMAPIInvalidFileType 992 | --------------------- 993 | The file being passed to the function is not supported. Try another file type to resolve the error. 994 | 995 | BCMAPIInvalidMethod 996 | ------------------- 997 | The "find" method being requested is not supported by BCMAPI, or does not exist in the Brightcove API. Remove the method call and check both the BCMAPI and Brightcove API documentation. 998 | 999 | BCMAPIInvalidProperty 1000 | --------------------- 1001 | The BCMAPI property you are trying to set or retrieve does not exist. Check the BCMAPI documentation. 1002 | 1003 | BCMAPIInvalidType 1004 | ----------------- 1005 | The DTO type (video, playlist, image, etc) you specified is not allowed for the method. Check both the BCMAPI and Brightcove API documentation. 1006 | 1007 | BCMAPISearchTermsNotProvided 1008 | ---------------------------- 1009 | Please specify one or more search parameters. Verify you are passing the parameters in an array. 1010 | 1011 | BCMAPITokenError 1012 | ---------------- 1013 | The read or write token you provided is not recognized by Brightcove. Verify you are using the correct token. 1014 | 1015 | BCMAPITransactionError 1016 | ---------------------- 1017 | The API could not be accessed, or the API did not return any data. Verify the server has cURL installed, enabled, and able to retrieve remote data. Verify the Brightcove API is currently available. 1018 | 1019 | -------------------------------------------------------------------------------- /bc-mapi.php: -------------------------------------------------------------------------------- 1 | 13 | * Brian Franklin 14 | * 15 | * CONTRIBUTORS: 16 | * Luke Weber, Brandon Aaskov 17 | * 18 | * Permission is hereby granted, free of charge, to any person obtaining a 19 | * copy of this software and associated documentation files (the “Software”), 20 | * to deal in the Software without restriction, including without limitation 21 | * the rights to use, copy, modify, alter, merge, publish, distribute, 22 | * sublicense, and/or sell copies of the Software, and to permit persons to 23 | * whom the Software is furnished to do so, subject to the following conditions: 24 | * 25 | * 1. The permission granted herein does not extend to commercial use of 26 | * the Software by entities primarily engaged in providing online video and 27 | * related services. 28 | * 29 | * 2. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OF ANY KIND, 30 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, SUITABILITY, TITLE, 32 | * NONINFRINGEMENT, OR THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 33 | * SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 34 | * CLAIM, DAMAGES OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF 35 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 36 | * THE SOFTWARE OR THE USE, INABILITY TO USE, OR OTHER DEALINGS IN THE SOFTWARE. 37 | * 38 | * 3. NONE OF THE AUTHORS, CONTRIBUTORS, NOR BRIGHTCOVE SHALL BE RESPONSIBLE 39 | * IN ANY MANNER FOR USE OF THE SOFTWARE. THE SOFTWARE IS PROVIDED FOR YOUR 40 | * CONVENIENCE AND ANY USE IS SOLELY AT YOUR OWN RISK. NO MAINTENANCE AND/OR 41 | * SUPPORT OF ANY KIND IS PROVIDED FOR THE SOFTWARE. 42 | */ 43 | 44 | class BCMAPI 45 | { 46 | const ERROR_API_ERROR = 1; 47 | const ERROR_DEPRECATED = 99; 48 | const ERROR_DTO_DOES_NOT_EXIST = 12; 49 | const ERROR_ID_NOT_PROVIDED = 2; 50 | const ERROR_INVALID_FILE_TYPE = 5; 51 | const ERROR_INVALID_METHOD = 3; 52 | const ERROR_INVALID_PROPERTY = 4; 53 | const ERROR_INVALID_TYPE = 6; 54 | const ERROR_INVALID_UPLOAD_OPTION = 7; 55 | const ERROR_READ_API_TRANSACTION_FAILED = 8; 56 | const ERROR_READ_TOKEN_NOT_PROVIDED = 9; 57 | const ERROR_SEARCH_TERMS_NOT_PROVIDED = 13; 58 | const ERROR_WRITE_API_TRANSACTION_FAILED = 10; 59 | const ERROR_WRITE_TOKEN_NOT_PROVIDED = 11; 60 | 61 | public $page_number = NULL; 62 | public $page_size = NULL; 63 | public $total_count = NULL; 64 | 65 | private $api_calls = 0; 66 | private $bit32 = FALSE; 67 | private $media_delivery = 'default'; 68 | private $secure = FALSE; 69 | private $show_notices = FALSE; 70 | private $timeout_attempts = 100; 71 | private $timeout_current = 0; 72 | private $timeout_delay = 1; 73 | private $timeout_retry = FALSE; 74 | private $token_read = NULL; 75 | private $token_write = NULL; 76 | private $url_read = 'api.brightcove.com/services/library?'; 77 | private $url_write = 'api.brightcove.com/services/post'; 78 | private $valid_types = array( 79 | 'playlist', 80 | 'video' 81 | ); 82 | 83 | /** 84 | * The constructor for the BCMAPI class. 85 | * @access Public 86 | * @since 0.1.0 87 | * @param string [$token_read] The read API token for the Brightcove account 88 | * @param string [$token_write] The write API token for the Brightcove account 89 | */ 90 | public function __construct($token_read = NULL, $token_write = NULL) 91 | { 92 | $this->token_read = $token_read; 93 | $this->token_write = $token_write; 94 | $this->bit32 = ((string)'99999999999999' == (int)'99999999999999') ? FALSE : TRUE; 95 | } 96 | 97 | /** 98 | * Sets a property of the BCMAPI class. 99 | * @access Public 100 | * @since 1.0.0 101 | * @param string [$key] The property to set 102 | * @param mixed [$value] The new value for the property 103 | * @return mixed The new value of the property 104 | */ 105 | public function __set($key, $value) 106 | { 107 | if(isset($this->$key) || is_null($this->$key)) 108 | { 109 | $this->$key = $value; 110 | } else { 111 | throw new BCMAPIInvalidProperty($this, self::ERROR_INVALID_PROPERTY); 112 | } 113 | } 114 | 115 | /** 116 | * Retrieves a property of the BCMAPI class. 117 | * @access Public 118 | * @since 1.0.0 119 | * @param string [$key] The property to retrieve 120 | * @return mixed The value of the property 121 | */ 122 | public function __get($key) 123 | { 124 | if(isset($this->$key) || is_null($this->$key)) 125 | { 126 | return $this->$key; 127 | } else { 128 | throw new BCMAPIInvalidProperty($this, self::ERROR_INVALID_PROPERTY); 129 | } 130 | } 131 | 132 | /** 133 | * Formats the request for any API 'Find' methods and retrieves the data. 134 | * @access Public 135 | * @since 0.1.0 136 | * @param string [$call] The requested API method 137 | * @param mixed [$params] A key-value array of API parameters, or a single value that matches the default 138 | * @return object An object containing all API return data 139 | */ 140 | public function find($call, $params = NULL) 141 | { 142 | $call = strtolower(preg_replace('/(?:find|_)+/i', '', $call)); 143 | 144 | switch($call) 145 | { 146 | case 'allvideos': 147 | $method = 'find_all_videos'; 148 | $get_item_count = TRUE; 149 | break; 150 | case 'videobyid': 151 | $method = 'find_video_by_id'; 152 | $default = 'video_id'; 153 | $get_item_count = FALSE; 154 | break; 155 | case 'videobyidunfiltered': 156 | $method = 'find_video_by_id_unfiltered'; 157 | $default = 'video_id'; 158 | $get_item_count = FALSE; 159 | break; 160 | case 'videosbyids': 161 | $method = 'find_videos_by_ids'; 162 | $default = 'video_ids'; 163 | $get_item_count = FALSE; 164 | break; 165 | case 'videosbyidsunfiltered': 166 | $method = 'find_videos_by_ids_unfiltered'; 167 | $default = 'video_ids'; 168 | $get_item_count = FALSE; 169 | break; 170 | case 'videobyreferenceid': 171 | $method = 'find_video_by_reference_id'; 172 | $default = 'reference_id'; 173 | $get_item_count = FALSE; 174 | break; 175 | case 'videobyreferenceidunfiltered': 176 | $method = 'find_video_by_reference_id_unfiltered'; 177 | $default = 'reference_id'; 178 | $get_item_count = FALSE; 179 | break; 180 | case 'videosbyreferenceids': 181 | $method = 'find_videos_by_reference_ids'; 182 | $default = 'reference_ids'; 183 | $get_item_count = FALSE; 184 | break; 185 | case 'videosbyreferenceidsunfiltered': 186 | $method = 'find_videos_by_reference_ids_unfiltered'; 187 | $default = 'reference_ids'; 188 | $get_item_count = FALSE; 189 | break; 190 | case 'videosbycampaignid': 191 | $method = 'find_videos_by_campaign_id'; 192 | $default = 'campaign_id'; 193 | $get_item_count = TRUE; 194 | break; 195 | case 'videosbytags': 196 | $method = 'find_videos_by_tags'; 197 | $default = 'or_tags'; 198 | $get_item_count = TRUE; 199 | break; 200 | case 'videosbytext': 201 | $method = 'find_videos_by_text'; 202 | $default = 'text'; 203 | $get_item_count = TRUE; 204 | break; 205 | case 'videosbyuserid': 206 | $method = 'find_videos_by_user_id'; 207 | $default = 'user_id'; 208 | $get_item_count = TRUE; 209 | break; 210 | case 'modifiedvideos': 211 | $method = 'find_modified_videos'; 212 | $default = 'from_date'; 213 | $get_item_count = TRUE; 214 | break; 215 | case 'relatedvideos': 216 | $method = 'find_related_videos'; 217 | $default = 'video_id'; 218 | $get_item_count = TRUE; 219 | break; 220 | case 'allplaylists': 221 | $method = 'find_all_playlists'; 222 | $get_item_count = TRUE; 223 | break; 224 | case 'playlistbyid': 225 | $method = 'find_playlist_by_id'; 226 | $default = 'playlist_id'; 227 | $get_item_count = FALSE; 228 | break; 229 | case 'playlistsbyids': 230 | $method = 'find_playlists_by_ids'; 231 | $default = 'playlist_ids'; 232 | $get_item_count = FALSE; 233 | break; 234 | case 'playlistbyreferenceid': 235 | $method = 'find_playlist_by_reference_id'; 236 | $default = 'reference_id'; 237 | $get_item_count = FALSE; 238 | break; 239 | case 'playlistsbyreferenceids': 240 | $method = 'find_playlists_by_reference_ids'; 241 | $default = 'reference_ids'; 242 | $get_item_count = FALSE; 243 | break; 244 | case 'playlistsforplayerid': 245 | $method = 'find_playlists_for_player_id'; 246 | $default = 'player_id'; 247 | $get_item_count = TRUE; 248 | break; 249 | default: 250 | throw new BCMAPIInvalidMethod($this, self::ERROR_INVALID_METHOD); 251 | break; 252 | } 253 | 254 | if(!isset($params)) 255 | { 256 | $params = array(); 257 | } else { 258 | if(!is_array($params)) 259 | { 260 | $temp = $params; 261 | 262 | $params = array(); 263 | $params[$default] = $temp; 264 | } 265 | } 266 | 267 | if(isset($params['from_date'])) 268 | { 269 | $params['from_date'] = (string)$params['from_date']; 270 | 271 | if(strlen($params['from_date']) > 9) 272 | { 273 | $params['from_date'] = floor((int)$params['from_date'] / 60); 274 | } 275 | } 276 | 277 | if(!isset($params['get_item_count']) && $get_item_count) 278 | { 279 | $params['get_item_count'] = 'TRUE'; 280 | } 281 | 282 | if(!isset($params['media_delivery']) && $this->media_delivery != 'default') 283 | { 284 | $params['media_delivery'] = $this->media_delivery; 285 | } 286 | 287 | $url = $this->appendParams($method, $params); 288 | 289 | $this->timeout_current = 0; 290 | 291 | return $this->getData($url); 292 | } 293 | 294 | /** 295 | * Finds all media assets in account, ignoring pagination. 296 | * @access Public 297 | * @since 0.3.6 298 | * @param string [$type] The type of object to retrieve 299 | * @param array [$params] A key-value array of API parameters 300 | * @return object An object containing all API return data 301 | */ 302 | public function findAll($type = 'video', $params = NULL) 303 | { 304 | $this->timeout_current = 0; 305 | 306 | $this->validType($type); 307 | 308 | if(!isset($params)) 309 | { 310 | $params = array(); 311 | } 312 | 313 | $params['get_item_count'] = 'TRUE'; 314 | $params['page_number'] = 0; 315 | 316 | if(!isset($params['page_size']) || $params['page_size'] > 100) 317 | { 318 | $params['page_size'] = 100; 319 | } 320 | 321 | if(!isset($params['media_delivery']) && $this->media_delivery != 'default') 322 | { 323 | $params['media_delivery'] = $this->media_delivery; 324 | } 325 | 326 | $assets = array(); 327 | $current_page = 0; 328 | $total_count = 0; 329 | $total_page = 1; 330 | 331 | while($current_page < $total_page) 332 | { 333 | $params['page_number'] = $current_page; 334 | 335 | $url = $this->appendParams(strtolower('find_all_' . $type . 's'), $params); 336 | 337 | $result = $this->getData($url); 338 | 339 | if($total_count < 1) 340 | { 341 | $total_count = $this->total_count; 342 | $total_page = ceil($total_count / $params['page_size']); 343 | } 344 | 345 | if(is_array($result)) 346 | { 347 | foreach($result as $asset) 348 | { 349 | $assets[] = $asset; 350 | } 351 | } 352 | 353 | $current_page++; 354 | } 355 | 356 | $this->timeout_current = 0; 357 | 358 | return $assets; 359 | } 360 | 361 | /** 362 | * Performs a search of video meta data 363 | * @access Public 364 | * @since 1.1.1 365 | * @param string [$type] The type of objects to retrieve 366 | * @param array [$terms] The terms to use for the search 367 | * @param mixed [$params] A key-value array of API parameters 368 | * @return object An object containing all API return data 369 | */ 370 | public function search($type = 'video', $terms = NULL, $params = NULL) 371 | { 372 | if(!isset($terms) || !is_array($terms)) 373 | { 374 | throw new BCMAPISearchTermsNotProvided($this, self::ERROR_SEARCH_TERMS_NOT_PROVIDED); 375 | } 376 | 377 | if(!isset($params)) 378 | { 379 | $params = array(); 380 | } else { 381 | if(!is_array($params)) 382 | { 383 | $temp = $params; 384 | 385 | $params = array(); 386 | $params[$default] = $temp; 387 | } 388 | } 389 | 390 | if(!isset($params['get_item_count'])) 391 | { 392 | $params['get_item_count'] = 'TRUE'; 393 | } 394 | 395 | foreach($terms as $key => $value) 396 | { 397 | if(strpos($value, ',') !== FALSE) 398 | { 399 | $i = 0; 400 | $parts = explode(',', $value); 401 | 402 | foreach($parts as $part) 403 | { 404 | if($i == 0) 405 | { 406 | $params[$key] = $part; 407 | $i++; 408 | } else { 409 | $params[$key] .= '%26' . $key . '%3D' . $part; 410 | } 411 | } 412 | } else { 413 | $params[$key] = $value; 414 | } 415 | } 416 | 417 | if (isset($params['sort_by']) && isset($params['sort_order'])) { 418 | $params['sort_by'] .= (':'.$params['sort_order']); 419 | unset($params['sort_order']); 420 | } 421 | 422 | $url = str_replace(array('%2526', '%253D'), array('&', '='), $this->appendParams('search_' . $type . 's', $params)); 423 | 424 | $this->timeout_current = 0; 425 | 426 | return $this->getData($url); 427 | } 428 | 429 | /** 430 | * Uploads a media asset file to Brightcove. 431 | * @access Public 432 | * @since 1.0.0 433 | * @param string [$type] The type of object to upload 434 | * @param string [$file] The location of the temporary file 435 | * @param array [$meta] The media asset information 436 | * @param array [$options] Optional upload values 437 | * @return string The media asset ID 438 | */ 439 | public function createMedia($type = 'video', $file = NULL, $meta, $options = NULL) 440 | { 441 | if(strtolower($type) == 'video') 442 | { 443 | if(isset($file)) 444 | { 445 | preg_match('/(\.f4a|\.f4b|\.f4v|\.f4p|\.flv)*$/i', $file, $invalid_extensions); 446 | 447 | if(isset($invalid_extensions[1])) 448 | { 449 | if(isset($options['encode_to'])) 450 | { 451 | unset($options['encode_to']); 452 | 453 | throw new BCMAPIInvalidUploadOption($this, self::ERROR_INVALID_UPLOAD_OPTION); 454 | } 455 | 456 | if(isset($options['create_multiple_renditions'])) 457 | { 458 | $options['create_multiple_renditions'] = 'FALSE'; 459 | 460 | throw new BCMAPIInvalidUploadOption($this, self::ERROR_INVALID_UPLOAD_OPTION); 461 | } 462 | 463 | if(isset($options['preserve_source_rendition'])) 464 | { 465 | unset($options['preserve_source_rendition']); 466 | 467 | throw new BCMAPIInvalidUploadOption($this, self::ERROR_INVALID_UPLOAD_OPTION); 468 | } 469 | } 470 | 471 | if((isset($options['create_multiple_renditions']) && $options['create_multiple_renditions'] === TRUE) && (isset($options['H264NoProcessing']) && $options['H264NoProcessing'] === TRUE)) 472 | { 473 | unset($options['H264NoProcessing']); 474 | 475 | throw new BCMAPIInvalidUploadOption($this, self::ERROR_INVALID_UPLOAD_OPTION); 476 | } 477 | } 478 | } else { 479 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 480 | } 481 | 482 | $request = array(); 483 | $post = array(); 484 | $params = array(); 485 | $media = array(); 486 | 487 | foreach($meta as $key => $value) 488 | { 489 | $media[$key] = $value; 490 | } 491 | 492 | if(!isset($media['name']) || is_null($media['name']) || $media['name'] == '') 493 | { 494 | $media['name'] = time(); 495 | } 496 | 497 | if(!isset($media['shortDescription']) || is_null($media['shortDescription']) || $media['shortDescription'] == '') 498 | { 499 | $media['shortDescription'] = time(); 500 | } 501 | 502 | if(isset($options)) 503 | { 504 | foreach($options as $key => $value) 505 | { 506 | $params[$key] = $value; 507 | } 508 | } 509 | 510 | $params['token'] = $this->token_write; 511 | $params[strtolower($type)] = $media; 512 | 513 | $post['method'] = strtolower('create_' . $type); 514 | $post['params'] = $params; 515 | 516 | $request['json'] = json_encode($post); 517 | 518 | if(isset($file)) 519 | { 520 | $request['file'] = '@' . $file; 521 | } 522 | 523 | return (string)$this->putData($request)->result; 524 | } 525 | 526 | /** 527 | * Creates a playlist. 528 | * @access Public 529 | * @since 0.3.0 530 | * @param string [$type] The type of playlist to create 531 | * @param array [$meta] The playlist information 532 | * @return string The playlist ID 533 | */ 534 | public function createPlaylist($type = 'video', $meta) 535 | { 536 | $request = array(); 537 | $post = array(); 538 | $params = array(); 539 | $media = array(); 540 | 541 | foreach($meta as $key => $value) 542 | { 543 | $media[$key] = $value; 544 | } 545 | 546 | if(strtolower($type) == 'video') 547 | { 548 | if(isset($media['videoIds'])) 549 | { 550 | foreach($media['videoIds'] as $key => $value) 551 | { 552 | $media['videoIds'][$key] = (int)$value; 553 | } 554 | } 555 | 556 | $params['playlist'] = $media; 557 | $post['method'] = 'create_playlist'; 558 | } else { 559 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 560 | } 561 | 562 | $params['token'] = $this->token_write; 563 | 564 | $post['params'] = $params; 565 | 566 | $request['json'] = json_encode($post); 567 | 568 | return (string)$this->putData($request)->result; 569 | } 570 | 571 | /** 572 | * Uploads a media image file to Brightcove. 573 | * @access Public 574 | * @since 0.3.4 575 | * @param string [$type] The type of object to upload image for 576 | * @param string [$file] The location of the temporary file 577 | * @param array [$meta] The image information 578 | * @param int [$id] The ID of the media asset to assign the image to 579 | * @param string [$ref_id] The reference ID of the media asset to assign the image to 580 | * @param bool [$resize] Whether or not to resize the image on upload 581 | * @return mixed The image asset 582 | */ 583 | public function createImage($type = 'video', $file = NULL, $meta, $id = NULL, $ref_id = NULL, $resize = TRUE) 584 | { 585 | $request = array(); 586 | $post = array(); 587 | $params = array(); 588 | $media = array(); 589 | 590 | if(strtolower($type) == 'video') 591 | { 592 | $post['method'] = 'add_image'; 593 | } else { 594 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 595 | } 596 | 597 | foreach($meta as $key => $value) 598 | { 599 | $media[$key] = $value; 600 | } 601 | 602 | if(isset($id)) 603 | { 604 | $params[strtolower($type) . '_id'] = $id; 605 | } elseif(isset($ref_id)) { 606 | $params[strtolower($type) . '_reference_id'] = $ref_id; 607 | } else { 608 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 609 | } 610 | 611 | if($resize) 612 | { 613 | $params['resize'] = 'TRUE'; 614 | } else { 615 | $params['resize'] = 'FALSE'; 616 | } 617 | 618 | $params['token'] = $this->token_write; 619 | $params['image'] = $media; 620 | 621 | $post['params'] = $params; 622 | 623 | $request['json'] = json_encode($post) . "\n"; 624 | 625 | if(isset($file)) 626 | { 627 | $request['file'] = '@' . $file; 628 | } 629 | 630 | return $this->putData($request)->result; 631 | } 632 | 633 | /** 634 | * Uploads a logo overlay file to Brightcove. 635 | * @access Public 636 | * @since 1.1.0 637 | * @param string [$file] The location of the temporary file 638 | * @param array [$meta] The logo overlay information 639 | * @param int [$id] The ID of the media asset to assign the logo overlay to 640 | * @param string [$ref_id] The reference ID of the media asset to assign the logo overlay to 641 | * @return mixed The logo overlay asset 642 | */ 643 | public function createOverlay($file = NULL, $meta, $id = NULL, $ref_id = NULL) 644 | { 645 | $request = array(); 646 | $post = array(); 647 | $params = array(); 648 | $media = array(); 649 | 650 | $post['method'] = 'add_logo_overlay'; 651 | 652 | foreach($meta as $key => $value) 653 | { 654 | $media[$key] = $value; 655 | } 656 | 657 | if(isset($id)) 658 | { 659 | $params['video_id'] = $id; 660 | } elseif(isset($ref_id)) { 661 | $params['video_reference_id'] = $ref_id; 662 | } else { 663 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 664 | } 665 | 666 | $params['token'] = $this->token_write; 667 | $params['logooverlay'] = $media; 668 | 669 | $post['params'] = $params; 670 | 671 | $request['json'] = json_encode($post) . "\n"; 672 | 673 | if(isset($file)) 674 | { 675 | $request['file'] = '@' . $file; 676 | } 677 | 678 | return $this->putData($request)->result; 679 | } 680 | 681 | /** 682 | * Deletes a logo overlay. 683 | * @access Public 684 | * @since 1.1.0 685 | * @param int [$id] The ID of the media asset 686 | * @param string [$ref_id] The reference ID of the media asset 687 | * @param array [$options] Optional values 688 | */ 689 | public function deleteOverlay($id = NULL, $ref_id = NULL, $options = NULL) 690 | { 691 | $request = array(); 692 | $post = array(); 693 | $params = array(); 694 | 695 | $params['token'] = $this->token_write; 696 | 697 | if(isset($options)) 698 | { 699 | foreach($options as $key => $value) 700 | { 701 | $params[$key] = $value; 702 | } 703 | } 704 | 705 | if(isset($id)) 706 | { 707 | $params['video_id'] = $id; 708 | } elseif(isset($ref_id)) { 709 | $params['video_reference_id'] = $ref_id; 710 | } else { 711 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 712 | } 713 | 714 | $post['method'] = strtolower('remove_logo_overlay'); 715 | $post['params'] = $params; 716 | 717 | $request['json'] = json_encode($post) . "\n"; 718 | 719 | return $this->putData($request, FALSE); 720 | } 721 | 722 | /** 723 | * Updates a media asset. 724 | * @access Public 725 | * @since 0.3.0 726 | * @param string [$type] The type of object to update 727 | * @param array [$meta] The information for the media asset 728 | * @return object The new DTO 729 | */ 730 | public function update($type = 'video', $meta) 731 | { 732 | $this->validType($type); 733 | 734 | $request = array(); 735 | $post = array(); 736 | $media = array(); 737 | $params = array(); 738 | 739 | foreach($meta as $key => $value) 740 | { 741 | $media[$key] = $value; 742 | } 743 | 744 | $params['token'] = $this->token_write; 745 | $params[strtolower($type)] = $media; 746 | 747 | $post['method'] = strtolower('update_' . $type); 748 | $post['params'] = $params; 749 | 750 | $request['json'] = json_encode($post) . "\n"; 751 | 752 | return $this->putData($request)->result; 753 | } 754 | 755 | /** 756 | * Deletes a media asset. 757 | * @access Public 758 | * @since 0.3.0 759 | * @param string [$type] The type of item to delete 760 | * @param int [$id] The ID of the media asset 761 | * @param string [$ref_id] The reference ID of the media asset 762 | * @param array [$options] Optional values 763 | */ 764 | public function delete($type = 'video', $id = NULL, $ref_id = NULL, $options = NULL) 765 | { 766 | $this->validType($type); 767 | 768 | $request = array(); 769 | $post = array(); 770 | $params = array(); 771 | 772 | $params['token'] = $this->token_write; 773 | 774 | if(isset($options)) 775 | { 776 | foreach($options as $key => $value) 777 | { 778 | $params[$key] = $value; 779 | } 780 | } 781 | 782 | if(isset($id)) 783 | { 784 | $params[strtolower($type . '_id')] = $id; 785 | } elseif(isset($ref_id)) { 786 | $params['reference_id'] = $ref_id; 787 | } else { 788 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 789 | } 790 | 791 | $post['method'] = strtolower('delete_' . $type); 792 | $post['params'] = $params; 793 | 794 | $request['json'] = json_encode($post) . "\n"; 795 | 796 | return $this->putData($request, FALSE); 797 | } 798 | 799 | /** 800 | * Retrieves the status of a media asset upload. 801 | * @access Public 802 | * @since 0.3.9 803 | * @param string [$type] The type of object to check 804 | * @param int [$id] The ID of the media asset 805 | * @param string [$ref_id] The reference ID of the media asset 806 | * @return string The upload status 807 | */ 808 | public function getStatus($type = 'video', $id = NULL, $ref_id = TRUE) 809 | { 810 | if(!isset($id) && !isset($ref_id)) 811 | { 812 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 813 | } 814 | 815 | $request = array(); 816 | $post = array(); 817 | $params = array(); 818 | 819 | $params['token'] = $this->token_write; 820 | 821 | if(isset($id)) 822 | { 823 | $params[strtolower($type) . '_id'] = $id; 824 | } 825 | 826 | if(isset($ref_id)) 827 | { 828 | $params['reference_id'] = $ref_id; 829 | } 830 | 831 | if(strtolower($type) == 'video') 832 | { 833 | $post['method'] = 'get_upload_status'; 834 | } else { 835 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 836 | } 837 | 838 | $post['params'] = $params; 839 | 840 | $request['json'] = json_encode($post) . "\n"; 841 | 842 | return $this->putData($request)->result; 843 | } 844 | 845 | /** 846 | * Shares a media asset with the selected accounts. 847 | * @access Public 848 | * @since 1.0.0 849 | * @param string [$type] The type of object to check 850 | * @param int [$id] The ID of the media asset 851 | * @param array [$account_ids] An array of account IDs 852 | * @param bool [$accept] Whether the share should be auto accepted 853 | * @param bool [$force] Whether the share should overwrite existing copies of the media 854 | * @return array The new media asset IDs 855 | */ 856 | public function shareMedia($type = 'video', $id, $account_ids, $accept = FALSE, $force = FALSE) 857 | { 858 | if(!isset($id)) 859 | { 860 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 861 | } 862 | 863 | if(!is_array($account_ids)) 864 | { 865 | $account_ids = array($account_ids); 866 | } 867 | 868 | $request = array(); 869 | $post = array(); 870 | $params = array(); 871 | 872 | $params['token'] = $this->token_write; 873 | $params['sharee_account_ids'] = $account_ids; 874 | 875 | if($accept) 876 | { 877 | $params['auto_accept'] = 'TRUE'; 878 | } else { 879 | $params['auto_accept'] = 'FALSE'; 880 | } 881 | 882 | if($force) 883 | { 884 | $params['force_reshare'] = 'TRUE'; 885 | } else { 886 | $params['force_reshare'] = 'FALSE'; 887 | } 888 | 889 | if(strtolower($type) == 'video') 890 | { 891 | $params['video_id'] = $id; 892 | $post['method'] = 'share_video'; 893 | } else { 894 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 895 | } 896 | 897 | $post['params'] = $params; 898 | 899 | $request['json'] = json_encode($post) . "\n"; 900 | 901 | return $this->putData($request)->result; 902 | } 903 | 904 | /** 905 | * Removes assets from a playlist 906 | * @access Public 907 | * @since 1.0.8 908 | * @param int [$playlist_id] The ID of the playlist to modify 909 | * @param array [$video_ids] An array of video IDs to delete from the playlist 910 | * @return object The new playlist DTO 911 | */ 912 | public function removeFromPlaylist($playlist_id, $video_ids) 913 | { 914 | if(!isset($playlist_id)) 915 | { 916 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 917 | } 918 | 919 | if(!is_array($video_ids)) 920 | { 921 | $video_ids = array($video_ids); 922 | } 923 | 924 | $safe_videos = array(); 925 | 926 | $meta = array( 927 | 'playlist_id' => $playlist_id, 928 | 'fields' => 'videoIds' 929 | ); 930 | 931 | $playlist = $this->find('playlistById', $meta); 932 | 933 | if(!isset($playlist)) 934 | { 935 | throw new BCMAPIDtoDoesNotExist($this, self::ERROR_DTO_DOES_NOT_EXIST); 936 | } 937 | 938 | foreach($playlist->videoIds as $video) 939 | { 940 | if(!in_array($video, $video_ids)) 941 | { 942 | $safe_videos[] = $video; 943 | } 944 | } 945 | 946 | $new_meta = array( 947 | 'id' => $playlist_id, 948 | 'videoIds' => $safe_videos 949 | ); 950 | 951 | return $this->update('playlist', $new_meta); 952 | } 953 | 954 | /** 955 | * Adds assets to a playlist 956 | * @access Public 957 | * @since 1.0.8 958 | * @param int [$playlist_id] The ID of the playlist to modify 959 | * @param array [$video_ids] An array of video IDs to add to the playlist 960 | * @return object The new playlist DTO 961 | */ 962 | public function addToPlaylist($playlist_id, $video_ids) 963 | { 964 | if(!isset($playlist_id)) 965 | { 966 | throw new BCMAPIIdNotProvided($this, self::ERROR_ID_NOT_PROVIDED); 967 | } 968 | 969 | if(!is_array($video_ids)) 970 | { 971 | $video_ids = array($video_ids); 972 | } 973 | 974 | $meta = array( 975 | 'playlist_id' => $playlist_id, 976 | 'fields' => 'videoIds' 977 | ); 978 | 979 | $playlist = $this->find('playlistById', $meta); 980 | 981 | if(!isset($playlist)) 982 | { 983 | throw new BCMAPIDtoDoesNotExist($this, self::ERROR_DTO_DOES_NOT_EXIST); 984 | } 985 | 986 | foreach($video_ids as $video) 987 | { 988 | $playlist->videoIds[] = $video; 989 | } 990 | 991 | $new_meta = array( 992 | 'id' => $playlist_id, 993 | 'videoIds' => $playlist->videoIds 994 | ); 995 | 996 | return $this->update('playlist', $new_meta); 997 | } 998 | 999 | /** 1000 | * Converts milliseconds to formatted time or seconds. 1001 | * @access Public 1002 | * @since 0.2.1 1003 | * @param int [$ms] The length of the media asset in milliseconds 1004 | * @param bool [$seconds] Whether to return only seconds 1005 | * @return mixed The formatted length or total seconds of the media asset 1006 | */ 1007 | public function convertTime($ms, $seconds = FALSE) 1008 | { 1009 | $total_seconds = ($ms / 1000); 1010 | 1011 | if($seconds) 1012 | { 1013 | return $total_seconds; 1014 | } else { 1015 | $time = ''; 1016 | 1017 | $value = array( 1018 | 'hours' => 0, 1019 | 'minutes' => 0, 1020 | 'seconds' => 0 1021 | ); 1022 | 1023 | if($total_seconds >= 3600) 1024 | { 1025 | $value['hours'] = floor($total_seconds / 3600); 1026 | $total_seconds = $total_seconds % 3600; 1027 | 1028 | $time .= $value['hours'] . ':'; 1029 | } 1030 | 1031 | if($total_seconds >= 60) 1032 | { 1033 | $value['minutes'] = floor($total_seconds / 60); 1034 | $total_seconds = $total_seconds % 60; 1035 | 1036 | $time .= $value['minutes'] . ':'; 1037 | } else { 1038 | $time .= '0:'; 1039 | } 1040 | 1041 | $value['seconds'] = floor($total_seconds); 1042 | 1043 | if($value['seconds'] < 10) 1044 | { 1045 | $value['seconds'] = '0' . $value['seconds']; 1046 | } 1047 | 1048 | $time .= $value['seconds']; 1049 | 1050 | return $time; 1051 | } 1052 | } 1053 | 1054 | /** 1055 | * Parses media asset tags array into a key-value array. 1056 | * @access Public 1057 | * @since 0.3.2 1058 | * @param array [$tags] The tags array from a media asset DTO 1059 | * @param bool [$implode] Return array to Brightcove format 1060 | * @return array A key-value array of tags 1061 | */ 1062 | public function convertTags($tags, $implode = FALSE) 1063 | { 1064 | $return = array(); 1065 | 1066 | if(count($tags) > 0) 1067 | { 1068 | if($implode) 1069 | { 1070 | $i = 0; 1071 | 1072 | foreach($tags as $key => $value) 1073 | { 1074 | if($key !== $i) 1075 | { 1076 | $return[] = $key . '=' . $value; 1077 | } else { 1078 | $return[] = $value; 1079 | } 1080 | 1081 | $i++; 1082 | } 1083 | } else { 1084 | foreach($tags as $tag) 1085 | { 1086 | if(strpos($tag, '=') === FALSE) 1087 | { 1088 | $return[] = $tag; 1089 | } else { 1090 | $group = explode('=', $tag); 1091 | $key = trim($group[0]); 1092 | $value = trim($group[1]); 1093 | 1094 | if(!isset($return[$key])) 1095 | { 1096 | $return[$key] = $value; 1097 | } else { 1098 | if(is_array($return[$key])) 1099 | { 1100 | $return[$key][] = $value; 1101 | } else { 1102 | $return[$key] = array($return[$key], $value); 1103 | } 1104 | } 1105 | } 1106 | } 1107 | } 1108 | } 1109 | 1110 | return $return; 1111 | } 1112 | 1113 | /** 1114 | * Removes assets that don't contain the appropriate tags. 1115 | * @access Public 1116 | * @since 0.3.6 1117 | * @param array [$assets] All the assets you wish to filter 1118 | * @param string [$tag] A comma-separated list of tags to filter on 1119 | * @return array The filtered list of assets 1120 | */ 1121 | public function tagsFilter($assets, $tags) 1122 | { 1123 | $filtered = array(); 1124 | $array = explode(',', strtolower($tags)); 1125 | 1126 | foreach($assets as $asset) 1127 | { 1128 | foreach($asset->tags as $k => $v) 1129 | { 1130 | if(isset($asset->tags)) 1131 | { 1132 | $asset->tags[$k] = strtolower($v); 1133 | } 1134 | } 1135 | 1136 | if(isset($asset->tags)) 1137 | { 1138 | if(count(array_intersect($array, $asset->tags)) > 0) 1139 | { 1140 | $filtered[] = $asset; 1141 | } 1142 | } 1143 | } 1144 | 1145 | return $filtered; 1146 | } 1147 | 1148 | /** 1149 | * Formats a media asset name to be search-engine friendly. 1150 | * @access Public 1151 | * @since 0.2.1 1152 | * @param string [$name] The asset name 1153 | * @return string The SEF asset name 1154 | */ 1155 | public function sef($name) 1156 | { 1157 | $accent_match = array('Â', 'Ã', 'Ä', 'À', 'Á', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ'); 1158 | $accent_replace = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'B', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'o', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y'); 1159 | 1160 | $name = str_replace($accent_match, $accent_replace, $name); 1161 | $name = preg_replace('/[^a-zA-Z0-9\s]+/', '', $name); 1162 | $name = preg_replace('/\s/', '-', $name); 1163 | 1164 | return $name; 1165 | } 1166 | 1167 | /** 1168 | * Retrieves the appropriate API URL 1169 | * @access Private 1170 | * @since 1.0.0 1171 | * @param string [$type] The type of URL to retrieve, read or write 1172 | * @return string The appropriate API URL 1173 | */ 1174 | private function getUrl($type = 'read') 1175 | { 1176 | if($this->secure) 1177 | { 1178 | $url = 'https://'; 1179 | } else { 1180 | $url = 'http://'; 1181 | } 1182 | 1183 | if(strtolower($type) == 'read') 1184 | { 1185 | $url .= $this->url_read; 1186 | } elseif(strtolower($type) == 'write') { 1187 | $url .= $this->url_write; 1188 | } else { 1189 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 1190 | } 1191 | 1192 | return $url; 1193 | } 1194 | 1195 | /** 1196 | * Appends API parameters onto API request URL. 1197 | * @access Private 1198 | * @since 0.1.0 1199 | * @param string [$method] The requested API method 1200 | * @param array [$params] A key-value array of API parameters 1201 | * @param string [$default] The default API parameter if only 1 provided 1202 | * @return string The complete API request URL 1203 | */ 1204 | private function appendParams($method, $params = NULL, $default = NULL) 1205 | { 1206 | $url = $this->getUrl('read') . 'token=' . $this->token_read . '&command=' . $method; 1207 | 1208 | if(isset($params)) 1209 | { 1210 | if(isset($default)) 1211 | { 1212 | $url .= '&' . $default . '=' . urlencode($params); 1213 | } else { 1214 | foreach($params as $option => $value) 1215 | { 1216 | $url .= '&' . $option . '=' . urlencode($value); 1217 | } 1218 | } 1219 | } 1220 | 1221 | return $url; 1222 | } 1223 | 1224 | /** 1225 | * Retrieves API data from provided URL. 1226 | * @access Private 1227 | * @since 0.1.0 1228 | * @param string [$url] The complete API request URL 1229 | * @return object An object containing all API return data 1230 | */ 1231 | private function getData($url) 1232 | { 1233 | if(class_exists('BCMAPICache')) 1234 | { 1235 | $cache = BCMAPICache::get($url); 1236 | 1237 | if($cache !== FALSE) 1238 | { 1239 | $response_object = json_decode($cache); 1240 | 1241 | if(isset($response_object->items)) 1242 | { 1243 | $data = $response_object->items; 1244 | } else { 1245 | $data = $response_object; 1246 | } 1247 | 1248 | $this->page_number = isset($response_object->page_number) ? $response_object->page_number : NULL; 1249 | $this->page_size = isset($response_object->page_size) ? $response_object->page_size : NULL; 1250 | $this->total_count = isset($response_object->total_count) ? $response_object->total_count : NULL; 1251 | 1252 | return $data; 1253 | } 1254 | } 1255 | 1256 | $this->timeout_current++; 1257 | 1258 | if(!isset($this->token_read)) 1259 | { 1260 | throw new BCMAPITokenError($this, self::ERROR_READ_TOKEN_NOT_PROVIDED); 1261 | } 1262 | 1263 | $response = $this->curlRequest($url, TRUE); 1264 | 1265 | if($response && $response != 'NULL') 1266 | { 1267 | $response_object = json_decode(preg_replace('/[[:cntrl:]]/u', '', $response));; 1268 | 1269 | if(isset($response_object->error)) 1270 | { 1271 | if($this->timeout_retry && $response_object->code == 103 && $this->timeout_current < $this->timeout_attempts) 1272 | { 1273 | if($this->timeout_delay > 0) 1274 | { 1275 | if($this->timeout_delay < 1) 1276 | { 1277 | usleep($this->timeout_delay * 1000000); 1278 | } else { 1279 | sleep($this->timeout_delay); 1280 | } 1281 | } 1282 | 1283 | return $this->getData($url); 1284 | } else { 1285 | throw new BCMAPIApiError($this, self::ERROR_API_ERROR, $response_object); 1286 | } 1287 | } else { 1288 | if(class_exists('BCMAPICache')) 1289 | { 1290 | $cache = BCMAPICache::set($url, $response_object); 1291 | } 1292 | 1293 | if(isset($response_object->items)) 1294 | { 1295 | $data = $response_object->items; 1296 | } else { 1297 | $data = $response_object; 1298 | } 1299 | 1300 | $this->page_number = isset($response_object->page_number) ? $response_object->page_number : NULL; 1301 | $this->page_size = isset($response_object->page_size) ? $response_object->page_size : NULL; 1302 | $this->total_count = isset($response_object->total_count) ? $response_object->total_count : NULL; 1303 | 1304 | return $data; 1305 | } 1306 | } else { 1307 | throw new BCMAPIApiError($this, self::ERROR_API_ERROR); 1308 | } 1309 | } 1310 | 1311 | /** 1312 | * Sends data to the API. 1313 | * @access Private 1314 | * @since 1.0.0 1315 | * @param array [$request] The data to send 1316 | * @param bool [$return_json] Whether we should return any data or not 1317 | * @return object An object containing all API return data 1318 | */ 1319 | private function putData($request, $return_json = TRUE) 1320 | { 1321 | if(!isset($this->token_write)) 1322 | { 1323 | throw new BCMAPITokenError($this, self::ERROR_WRITE_TOKEN_NOT_PROVIDED); 1324 | } 1325 | 1326 | $response = $this->curlRequest($request, FALSE); 1327 | 1328 | if($return_json) 1329 | { 1330 | $response_object = json_decode(preg_replace('/[[:cntrl:]]/', '', $response)); 1331 | 1332 | if(!isset($response_object->result)) 1333 | { 1334 | throw new BCMAPIApiError($this, self::ERROR_API_ERROR, $response_object); 1335 | } 1336 | 1337 | return $response_object; 1338 | } 1339 | } 1340 | 1341 | /** 1342 | * Makes a cURL request. 1343 | * @access Private 1344 | * @since 1.0.0 1345 | * @param mixed [$request] URL to fetch or the data to send via POST 1346 | * @param boolean [$get_request] If false, send POST params 1347 | * @return void 1348 | */ 1349 | private function curlRequest($request, $get_request = FALSE) 1350 | { 1351 | $curl = curl_init(); 1352 | 1353 | if($get_request) 1354 | { 1355 | curl_setopt($curl, CURLOPT_URL, $request); 1356 | } else { 1357 | curl_setopt($curl, CURLOPT_URL, $this->getUrl('write')); 1358 | curl_setopt($curl, CURLOPT_POST, 1); 1359 | curl_setopt($curl, CURLOPT_POSTFIELDS, $request); 1360 | } 1361 | 1362 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 1363 | $response = curl_exec($curl); 1364 | 1365 | $this->api_calls++; 1366 | 1367 | $curl_error = NULL; 1368 | 1369 | if(curl_errno($curl)) 1370 | { 1371 | $curl_error = curl_error($curl); 1372 | } 1373 | 1374 | curl_close($curl); 1375 | 1376 | if($curl_error !== NULL) 1377 | { 1378 | if($get_request) 1379 | { 1380 | throw new BCMAPITransactionError($this, self::ERROR_READ_API_TRANSACTION_FAILED, $curl_error); 1381 | } else { 1382 | throw new BCMAPITransactionError($this, self::ERROR_WRITE_API_TRANSACTION_FAILED, $curl_error); 1383 | } 1384 | } 1385 | 1386 | return $this->bit32clean($response); 1387 | } 1388 | 1389 | /** 1390 | * Cleans the response for 32-bit machine compliance. 1391 | * @access Private 1392 | * @since 1.0.0 1393 | * @param string [$response] The response from a cURL request 1394 | * @return string The cleansed string if using a 32-bit machine. 1395 | */ 1396 | private function bit32Clean($response) 1397 | { 1398 | if($this->bit32) 1399 | { 1400 | $response = preg_replace('/(?:((?:":\s*)(?:\[\s*)?|(?:\[\s*)|(?:\,\s*))+(\d{10,}))/', '\1"\2"', $response); 1401 | } 1402 | 1403 | return $response; 1404 | } 1405 | 1406 | /** 1407 | * Determines if provided type is valid 1408 | * @access Private 1409 | * @since 1.0.0 1410 | * @param string [$type] The type 1411 | */ 1412 | private function validType($type) 1413 | { 1414 | if(!in_array(strtolower($type), $this->valid_types)) 1415 | { 1416 | throw new BCMAPIInvalidType($this, self::ERROR_INVALID_TYPE); 1417 | } else { 1418 | return TRUE; 1419 | } 1420 | } 1421 | 1422 | /** 1423 | * Dummy method for backwards compatability 1424 | * @todo Deprecate in > 2.1.0 1425 | */ 1426 | public function filter($assets, $tags) 1427 | { 1428 | return $this->tagsFilter($assets, $tags); 1429 | } 1430 | 1431 | /** 1432 | * Dummy method for backwards compatability 1433 | * @todo Deprecate in > 2.1.0 1434 | */ 1435 | public function tags($tags, $implode = FALSE) 1436 | { 1437 | return $this->convertTags($tags, $implode); 1438 | } 1439 | 1440 | /** 1441 | * Dummy method for backwards compatability 1442 | * @todo Deprecate in > 2.1.0 1443 | */ 1444 | public function time($ms, $seconds = FALSE) 1445 | { 1446 | return $this->convertTime($ms, $seconds); 1447 | } 1448 | 1449 | /** 1450 | * Returns the JavaScript version of the player embed code. 1451 | * @access Public 1452 | * @since 0.2.2 1453 | * @deprecated 1.2.0 1454 | * @return string The embed code 1455 | */ 1456 | public function embed($a = NULL, $b = NULL, $c = NULL, $d = NULL, $e = NULL) 1457 | { 1458 | throw new BCMAPIDeprecated($this, self::ERROR_DEPRECATED); 1459 | 1460 | return FALSE; 1461 | } 1462 | 1463 | /** 1464 | * Converts an error code into a textual representation. 1465 | * @access public 1466 | * @since 1.0.0 1467 | * @param int [$error_code] The code number of an error 1468 | * @return string The error text 1469 | */ 1470 | public function getErrorAsString($error_code) 1471 | { 1472 | switch($error_code) 1473 | { 1474 | case self::ERROR_API_ERROR: 1475 | return 'API error'; 1476 | break; 1477 | case self::ERROR_DTO_DOES_NOT_EXIST: 1478 | return 'The requested object does not exist'; 1479 | break; 1480 | case self::ERROR_ID_NOT_PROVIDED: 1481 | return 'ID not provided'; 1482 | break; 1483 | case self::ERROR_INVALID_FILE_TYPE: 1484 | return 'Unsupported file type'; 1485 | break; 1486 | case self::ERROR_INVALID_METHOD: 1487 | return 'Requested method not found'; 1488 | break; 1489 | case self::ERROR_INVALID_PROPERTY: 1490 | return 'Requested property not found'; 1491 | break; 1492 | case self::ERROR_INVALID_TYPE: 1493 | return 'Type not specified'; 1494 | break; 1495 | case self::ERROR_INVALID_UPLOAD_OPTION: 1496 | return 'An invalid media upload parameter has been set'; 1497 | break; 1498 | case self::ERROR_READ_API_TRANSACTION_FAILED: 1499 | return 'Read API transaction failed'; 1500 | break; 1501 | case self::ERROR_READ_TOKEN_NOT_PROVIDED: 1502 | return 'Read token not provided'; 1503 | break; 1504 | case self::ERROR_SEARCH_TERMS_NOT_PROVIDED: 1505 | return 'Search terms not provided'; 1506 | break; 1507 | case self::ERROR_WRITE_API_TRANSACTION_FAILED: 1508 | return 'Write API transaction failed'; 1509 | break; 1510 | case self::ERROR_WRITE_TOKEN_NOT_PROVIDED: 1511 | return 'Write token not provided'; 1512 | break; 1513 | case self::ERROR_DEPRECATED: 1514 | return 'Access to this method or property has been deprecated'; 1515 | break; 1516 | } 1517 | } 1518 | } 1519 | 1520 | class BCMAPIException extends Exception 1521 | { 1522 | /** 1523 | * The constructor for the BCMAPIException class 1524 | * @access Public 1525 | * @since 1.0.0 1526 | * @param object [$obj] A pointer to the BCMAPI class 1527 | * @param int [$error_code] The error code 1528 | * @param string [$raw_error] Any additional error information 1529 | */ 1530 | public function __construct(BCMAPI $obj, $error_code, $raw_error = NULL) 1531 | { 1532 | $error = $obj->getErrorAsString($error_code); 1533 | 1534 | if(isset($raw_error)) 1535 | { 1536 | if(isset($raw_error->error) && isset($raw_error->error->message) && isset($raw_error->error->code)) 1537 | { 1538 | $raw_error = $raw_error->error; 1539 | } 1540 | 1541 | $error .= "'\n"; 1542 | $error .= (isset($raw_error->message) && isset($raw_error->code)) ? '== ' . $raw_error->message . ' (' . $raw_error->code . ') ==' . "\n" : ''; 1543 | $error .= isset($raw_error->errors[0]) ? '== ' . $raw_error->errors[0]->error . ' (' . $raw_error->errors[0]->code . ') ==' . "\n" : ''; 1544 | } 1545 | 1546 | parent::__construct($error, $error_code); 1547 | } 1548 | } 1549 | 1550 | class BCMAPIApiError extends BCMAPIException{} 1551 | class BCMAPIDeprecated extends BCMAPIException{} 1552 | class BCMAPIDtoDoesNotExist extends BCMAPIException{} 1553 | class BCMAPIIdNotProvided extends BCMAPIException{} 1554 | class BCMAPIInvalidFileType extends BCMAPIException{} 1555 | class BCMAPIInvalidMethod extends BCMAPIException{} 1556 | class BCMAPIInvalidProperty extends BCMAPIException{} 1557 | class BCMAPIInvalidType extends BCMAPIException{} 1558 | class BCMAPIInvalidUploadOption extends BCMAPIException{} 1559 | class BCMAPISearchTermsNotProvided extends BCMAPIException{} 1560 | class BCMAPITokenError extends BCMAPIException{} 1561 | class BCMAPITransactionError extends BCMAPIException{} 1562 | 1563 | ?> --------------------------------------------------------------------------------