rtMedia for WordPress, BuddyPress and bbPress - Version 3.8.18

Version Description

  • Filter for media action text
  • Updated getid3 lib to latest version
Download this release

Release Info

Developer rtcamp
Plugin Icon 128x128 rtMedia for WordPress, BuddyPress and bbPress
Version 3.8.18
Comparing to
See all releases

Code changes from version 3.8.17 to 3.8.18

Files changed (77) hide show
  1. app/main/controllers/media/RTMediaLike.php +2 -2
  2. app/main/controllers/media/RTMediaUserInteraction.php +96 -74
  3. index.php +1 -1
  4. lib/getid3/extension.cache.dbm.php +8 -10
  5. lib/getid3/extension.cache.mysql.php +43 -26
  6. lib/getid3/extension.cache.sqlite3.php +266 -0
  7. lib/getid3/getid3.lib.php +236 -156
  8. lib/getid3/getid3.php +1790 -1597
  9. lib/getid3/module.archive.gzip.php +12 -11
  10. lib/getid3/module.archive.rar.php +3 -5
  11. lib/getid3/module.archive.szip.php +11 -10
  12. lib/getid3/module.archive.tar.php +11 -12
  13. lib/getid3/module.archive.zip.php +148 -59
  14. lib/getid3/module.audio-video.asf.php +95 -103
  15. lib/getid3/module.audio-video.bink.php +7 -8
  16. lib/getid3/module.audio-video.flv.php +161 -147
  17. lib/getid3/module.audio-video.matroska.php +322 -244
  18. lib/getid3/module.audio-video.mpeg.php +510 -203
  19. lib/getid3/module.audio-video.nsv.php +12 -14
  20. lib/getid3/module.audio-video.quicktime.php +510 -366
  21. lib/getid3/module.audio-video.real.php +14 -16
  22. lib/getid3/module.audio-video.riff.php +742 -565
  23. lib/getid3/module.audio-video.swf.php +5 -7
  24. lib/getid3/module.audio-video.ts.php +79 -0
  25. lib/getid3/module.audio.aa.php +13 -13
  26. lib/getid3/module.audio.aac.php +14 -16
  27. lib/getid3/module.audio.ac3.php +120 -119
  28. lib/getid3/module.audio.amr.php +97 -0
  29. lib/getid3/module.audio.au.php +8 -10
  30. lib/getid3/module.audio.avr.php +4 -6
  31. lib/getid3/module.audio.bonk.php +22 -24
  32. lib/getid3/module.audio.dss.php +46 -28
  33. lib/getid3/module.audio.dts.php +117 -72
  34. lib/getid3/module.audio.flac.php +257 -284
  35. lib/getid3/module.audio.la.php +7 -10
  36. lib/getid3/module.audio.lpac.php +4 -6
  37. lib/getid3/module.audio.midi.php +15 -11
  38. lib/getid3/module.audio.mod.php +16 -18
  39. lib/getid3/module.audio.monkey.php +7 -8
  40. lib/getid3/module.audio.mp3.php +120 -109
  41. lib/getid3/module.audio.mpc.php +22 -24
  42. lib/getid3/module.audio.ogg.php +259 -124
  43. lib/getid3/module.audio.optimfrog.php +31 -33
  44. lib/getid3/module.audio.rkau.php +5 -6
  45. lib/getid3/module.audio.shorten.php +10 -11
  46. lib/getid3/module.audio.tta.php +5 -7
  47. lib/getid3/module.audio.voc.php +26 -28
  48. lib/getid3/module.audio.vqf.php +12 -14
  49. lib/getid3/module.audio.wavpack.php +16 -18
  50. lib/getid3/module.graphic.bmp.php +14 -16
  51. lib/getid3/module.graphic.efax.php +4 -6
  52. lib/getid3/module.graphic.gif.php +15 -17
  53. lib/getid3/module.graphic.jpg.php +27 -27
  54. lib/getid3/module.graphic.pcd.php +14 -15
  55. lib/getid3/module.graphic.png.php +14 -16
  56. lib/getid3/module.graphic.svg.php +4 -6
  57. lib/getid3/module.graphic.tiff.php +19 -21
  58. lib/getid3/module.misc.cue.php +14 -14
  59. lib/getid3/module.misc.exe.php +4 -6
  60. lib/getid3/module.misc.iso.php +18 -19
  61. lib/getid3/module.misc.msoffice.php +5 -7
  62. lib/getid3/module.misc.par2.php +2 -4
  63. lib/getid3/module.misc.pdf.php +2 -4
  64. lib/getid3/module.tag.apetag.php +96 -52
  65. lib/getid3/module.tag.id3v1.php +15 -17
  66. lib/getid3/module.tag.id3v2.php +417 -106
  67. lib/getid3/module.tag.lyrics3.php +20 -19
  68. lib/getid3/module.tag.xmp.php +18 -16
  69. lib/getid3/write.apetag.php +20 -21
  70. lib/getid3/write.id3v1.php +11 -12
  71. lib/getid3/write.id3v2.php +52 -46
  72. lib/getid3/write.lyrics3.php +11 -12
  73. lib/getid3/write.metaflac.php +10 -11
  74. lib/getid3/write.php +25 -32
  75. lib/getid3/write.real.php +19 -20
  76. lib/getid3/write.vorbiscomment.php +10 -11
  77. readme.txt +7 -3
app/main/controllers/media/RTMediaLike.php CHANGED
@@ -96,10 +96,10 @@ class RTMediaLike extends RTMediaUserInteraction {
96
$actions = intval( $actions[ 0 ]->{$actionwa} );
97
if ( $this->increase === true ) {
98
$actions ++;
99
- $return[ "next" ] = $this->undo_label;
100
} else {
101
$actions --;
102
- $return[ "next" ] = $this->label;
103
}
104
if ( $actions < 0 ) {
105
$actions = 0;
96
$actions = intval( $actions[ 0 ]->{$actionwa} );
97
if ( $this->increase === true ) {
98
$actions ++;
99
+ $return[ "next" ] = apply_filters( 'rtmedia_' . $this->action . '_label_text', $this->undo_label );
100
} else {
101
$actions --;
102
+ $return[ "next" ] = apply_filters( 'rtmedia_' . $this->action . '_label_text', $this->label );
103
}
104
if ( $actions < 0 ) {
105
$actions = 0;
app/main/controllers/media/RTMediaUserInteraction.php CHANGED
@@ -51,49 +51,52 @@ class RTMediaUserInteraction {
51
* Initialise the user interaction
52
*
53
* @global object $rtmedia_query Default query
54
* @param string $action The user action
55
* @param boolean $private Whether other users are allowed the action
56
* @param string $label The label for the button
57
* @param boolean $increase Increase or decrease the action count
58
*/
59
- function __construct($args = array()) {
60
$defaults = array(
61
- 'action' => '',
62
- 'label' => '',
63
- 'plural' => '',
64
- 'undo_label' => '',
65
- 'privacy' => 60,
66
- 'countable' => false,
67
- 'single' => false,
68
- 'repeatable' => false,
69
- 'undoable' => false,
70
- 'icon_class' => ''
71
);
72
73
- $args = wp_parse_args($args,$defaults);
74
- foreach($args as $key=>$val){
75
$this->{$key} = $val;
76
}
77
78
79
-
80
$this->init();
81
82
83
-
84
// filter the default actions with this new one
85
add_filter( 'rtmedia_query_actions', array( $this, 'register' ) );
86
// hook into the template for this action
87
add_action( 'rtmedia_pre_action_' . $this->action, array( $this, 'preprocess' ) );
88
- add_filter( 'rtmedia_action_buttons_before_delete', array($this,'button_filter') );
89
}
90
91
92
- function init(){
93
- $this->model = new RTMediaModel();
94
- global $rtmedia_query;
95
- if(!isset($rtmedia_query->action_query)) return;
96
- if(!isset($rtmedia_query->action_query->id)) return;
97
98
$this->set_label();
99
$this->set_plural();
@@ -106,29 +109,29 @@ class RTMediaUserInteraction {
106
* Checks if there's a label, if not creates from the action name
107
*/
108
function set_label() {
109
- if ( empty($this->label) ) {
110
$this->label = ucfirst( $this->action );
111
}
112
}
113
114
function set_plural() {
115
- if ( empty($this->plural) ) {
116
- $this->plural = $this->label .'s';
117
}
118
}
119
120
function set_media() {
121
122
- $media_id = false;
123
$this->media = false;
124
125
global $rtmedia_query;
126
$this->action_query = $rtmedia_query->action_query;
127
128
- if (isset( $this->action_query->id ) ){
129
$media_id = $this->action_query->id;
130
- $media = $this->model->get( array( 'id' => $media_id ) );
131
- if(!empty($media)){
132
$this->media = $media[0];
133
$this->owner = $this->media->media_author;
134
}
@@ -139,100 +142,117 @@ class RTMediaUserInteraction {
139
140
function set_interactor() {
141
$this->interactor = false;
142
- if( is_user_logged_in()){
143
$this->interactor = get_current_user_id();
144
}
145
$this->interactor_privacy = $this->interactor_privacy();
146
}
147
148
- function interactor_privacy(){
149
150
- if(!isset($this->interactor)) return 0;
151
- if($this->interactor === false ) return 0;
152
- if($this->interactor ==$this->owner) return 60;
153
154
$friends = new RTMediaFriends();
155
- $friends = $friends->get_friends_cache($this->interactor);
156
157
- if($friends && in_array($this->owner,$friends)) return 40;
158
159
return 20;
160
}
161
162
- function is_visible(){
163
- if($this->interactor_privacy >= $this->privacy) return true;
164
return false;
165
}
166
167
- function is_clickable(){
168
$clickable = false;
169
- if($this->repeatable){
170
$clickable = true;
171
- if($this->undoable){
172
$clickable = true;
173
}
174
- }else{
175
- if($this->undoable){
176
$clickable = true;
177
}
178
}
179
180
return $clickable;
181
}
182
- function before_render(){
183
184
- }
185
186
- function render(){
187
- $before_render = $this->before_render();
188
- if($before_render === false )
189
- return false;
190
$button = $button_start = $button_end = '';
191
- if($this->is_visible()){
192
- $link = trailingslashit(get_rtmedia_permalink($this->media->id)).
193
- $this->action.'/';
194
$disabled = $icon = '';
195
- if(!$this->is_clickable()){
196
$disabled = ' disabled';
197
}
198
-
199
- if( isset( $this->icon_class ) && $this->icon_class != "" ) {
200
- $icon = "<i class='" . $this->icon_class . "'></i>";
201
- }
202
- $button_start = '<form action="'. $link .'">';
203
- $button = '<button type="submit" id="rtmedia-'. $this->action .'-button-'.$this->media->id.'" class="rtmedia-'.$this->action
204
- .' rtmedia-action-buttons button'.$disabled.'">' . $icon . '<span>' . $this->label.'</span></button>';
205
-
206
- //filter the button as required
207
- $button = apply_filters( 'rtmedia_' . $this->action . '_button_filter', $button);
208
-
209
- $button_end = '</form>';
210
-
211
- $button = $button_start . $button . $button_end;
212
-
213
}
214
215
return $button;
216
}
217
218
- function button_filter($buttons){
219
- if(empty($this->media)){
220
$this->init();
221
}
222
$buttons[] = $this->render();
223
return $buttons;
224
}
225
/**
226
*
227
* @param array $actions The default array of actions
228
* @return array $actions Filtered actions array
229
*/
230
function register( $actions ) {
231
- if(empty($this->media)){
232
$this->init();
233
}
234
235
$actions[ $this->action ] = array( $this->label, false );
236
return $actions;
237
}
238
@@ -246,19 +266,21 @@ class RTMediaUserInteraction {
246
global $rtmedia_query;
247
$this->action_query = $rtmedia_query->action_query;
248
249
- if ( $this->action_query->action != $this->action )
250
return false;
251
252
- if ( ! isset( $this->action_query->id ) )
253
return false;
254
$result = false;
255
256
do_action( 'rtmedia_pre_process_' . $this->action );
257
- if(empty($this->media)){
258
$this->init();
259
}
260
261
- if($this->interactor_privacy >=$this->privacy){
262
$result = $this->process();
263
}
264
51
* Initialise the user interaction
52
*
53
* @global object $rtmedia_query Default query
54
+ *
55
* @param string $action The user action
56
* @param boolean $private Whether other users are allowed the action
57
* @param string $label The label for the button
58
* @param boolean $increase Increase or decrease the action count
59
*/
60
+ function __construct( $args = array() ) {
61
$defaults = array(
62
+ 'action' => '',
63
+ 'label' => '',
64
+ 'plural' => '',
65
+ 'undo_label' => '',
66
+ 'privacy' => 60,
67
+ 'countable' => false,
68
+ 'single' => false,
69
+ 'repeatable' => false,
70
+ 'undoable' => false,
71
+ 'icon_class' => ''
72
);
73
74
+ $args = wp_parse_args( $args, $defaults );
75
+ foreach ( $args as $key => $val ) {
76
$this->{$key} = $val;
77
}
78
79
80
$this->init();
81
82
83
// filter the default actions with this new one
84
add_filter( 'rtmedia_query_actions', array( $this, 'register' ) );
85
// hook into the template for this action
86
add_action( 'rtmedia_pre_action_' . $this->action, array( $this, 'preprocess' ) );
87
+ add_filter( 'rtmedia_action_buttons_before_delete', array( $this, 'button_filter' ) );
88
}
89
90
91
+ function init() {
92
+ $this->model = new RTMediaModel();
93
+ global $rtmedia_query;
94
+ if ( ! isset( $rtmedia_query->action_query ) ) {
95
+ return;
96
+ }
97
+ if ( ! isset( $rtmedia_query->action_query->id ) ) {
98
+ return;
99
+ }
100
101
$this->set_label();
102
$this->set_plural();
109
* Checks if there's a label, if not creates from the action name
110
*/
111
function set_label() {
112
+ if ( empty( $this->label ) ) {
113
$this->label = ucfirst( $this->action );
114
}
115
}
116
117
function set_plural() {
118
+ if ( empty( $this->plural ) ) {
119
+ $this->plural = $this->label . 's';
120
}
121
}
122
123
function set_media() {
124
125
+ $media_id = false;
126
$this->media = false;
127
128
global $rtmedia_query;
129
$this->action_query = $rtmedia_query->action_query;
130
131
+ if ( isset( $this->action_query->id ) ) {
132
$media_id = $this->action_query->id;
133
+ $media = $this->model->get( array( 'id' => $media_id ) );
134
+ if ( ! empty( $media ) ) {
135
$this->media = $media[0];
136
$this->owner = $this->media->media_author;
137
}
142
143
function set_interactor() {
144
$this->interactor = false;
145
+ if ( is_user_logged_in() ) {
146
$this->interactor = get_current_user_id();
147
}
148
$this->interactor_privacy = $this->interactor_privacy();
149
}
150
151
+ function interactor_privacy() {
152
153
+ if ( ! isset( $this->interactor ) ) {
154
+ return 0;
155
+ }
156
+ if ( $this->interactor === false ) {
157
+ return 0;
158
+ }
159
+ if ( $this->interactor == $this->owner ) {
160
+ return 60;
161
+ }
162
163
$friends = new RTMediaFriends();
164
+ $friends = $friends->get_friends_cache( $this->interactor );
165
166
+ if ( $friends && in_array( $this->owner, $friends ) ) {
167
+ return 40;
168
+ }
169
170
return 20;
171
}
172
173
+ function is_visible() {
174
+ if ( $this->interactor_privacy >= $this->privacy ) {
175
+ return true;
176
+ }
177
+
178
return false;
179
}
180
181
+ function is_clickable() {
182
$clickable = false;
183
+ if ( $this->repeatable ) {
184
$clickable = true;
185
+ if ( $this->undoable ) {
186
$clickable = true;
187
}
188
+ } else {
189
+ if ( $this->undoable ) {
190
$clickable = true;
191
}
192
}
193
194
return $clickable;
195
}
196
197
+ function before_render() {
198
+
199
+ }
200
201
+ function render() {
202
+ $before_render = $this->before_render();
203
+ if ( $before_render === false ) {
204
+ return false;
205
+ }
206
$button = $button_start = $button_end = '';
207
+ if ( $this->is_visible() ) {
208
+ $link = trailingslashit( get_rtmedia_permalink( $this->media->id ) ) .
209
+ $this->action . '/';
210
$disabled = $icon = '';
211
+ if ( ! $this->is_clickable() ) {
212
$disabled = ' disabled';
213
}
214
+
215
+ if ( isset( $this->icon_class ) && $this->icon_class != "" ) {
216
+ $icon = "<i class='" . $this->icon_class . "'></i>";
217
+ }
218
+ $button_start = '<form action="' . $link . '">';
219
+ $button = '<button type="submit" id="rtmedia-' . $this->action . '-button-' . $this->media->id . '" class="rtmedia-' . $this->action
220
+ . ' rtmedia-action-buttons button' . $disabled . '">' . $icon . '<span>' . apply_filters( 'rtmedia_' . $this->action . '_label_text', $this->label ) . '</span></button>';
221
+
222
+ //filter the button as required
223
+ $button = apply_filters( 'rtmedia_' . $this->action . '_button_filter', $button );
224
+
225
+ $button_end = '</form>';
226
+
227
+ $button = $button_start . $button . $button_end;
228
+
229
}
230
231
return $button;
232
}
233
234
+ function button_filter( $buttons ) {
235
+ if ( empty( $this->media ) ) {
236
$this->init();
237
}
238
$buttons[] = $this->render();
239
+
240
return $buttons;
241
}
242
+
243
/**
244
*
245
* @param array $actions The default array of actions
246
+ *
247
* @return array $actions Filtered actions array
248
*/
249
function register( $actions ) {
250
+ if ( empty( $this->media ) ) {
251
$this->init();
252
}
253
254
$actions[ $this->action ] = array( $this->label, false );
255
+
256
return $actions;
257
}
258
266
global $rtmedia_query;
267
$this->action_query = $rtmedia_query->action_query;
268
269
+ if ( $this->action_query->action != $this->action ) {
270
return false;
271
+ }
272
273
+ if ( ! isset( $this->action_query->id ) ) {
274
return false;
275
+ }
276
$result = false;
277
278
do_action( 'rtmedia_pre_process_' . $this->action );
279
+ if ( empty( $this->media ) ) {
280
$this->init();
281
}
282
283
+ if ( $this->interactor_privacy >= $this->privacy ) {
284
$result = $this->process();
285
}
286
index.php CHANGED
@@ -4,7 +4,7 @@
4
Plugin Name: rtMedia for WordPress, BuddyPress and bbPress
5
Plugin URI: http://rtcamp.com/rtmedia/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
6
Description: This plugin adds missing media rich features like photos, videos and audio uploading to BuddyPress which are essential if you are building social network, seriously!
7
- Version: 3.8.17
8
Author: rtCamp
9
Text Domain: rtmedia
10
Author URI: http://rtcamp.com/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
4
Plugin Name: rtMedia for WordPress, BuddyPress and bbPress
5
Plugin URI: http://rtcamp.com/rtmedia/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
6
Description: This plugin adds missing media rich features like photos, videos and audio uploading to BuddyPress which are essential if you are building social network, seriously!
7
+ Version: 3.8.18
8
Author: rtCamp
9
Text Domain: rtmedia
10
Author URI: http://rtcamp.com/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
lib/getid3/extension.cache.dbm.php CHANGED
@@ -3,6 +3,7 @@
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
/////////////////////////////////////////////////////////////////
7
// //
8
// extension.cache.dbm.php - part of getID3() //
@@ -10,7 +11,7 @@
10
// ///
11
/////////////////////////////////////////////////////////////////
12
// //
13
- // This extension written by Allan Hansen <ah�artemis*dk> //
14
// ///
15
/////////////////////////////////////////////////////////////////
16
@@ -73,7 +74,7 @@ class getID3_cached_dbm extends getID3
73
{
74
75
// public: constructor - see top of this file for cache type and cache_options
76
- function getID3_cached_dbm($cache_type, $dbm_filename, $lock_filename) {
77
78
// Check for dba extension
79
if (!extension_loaded('dba')) {
@@ -135,13 +136,13 @@ class getID3_cached_dbm extends getID3
135
$this->clear_cache();
136
}
137
138
- parent::getID3();
139
}
140
141
142
143
- // public: destuctor
144
- function __destruct() {
145
146
// Close dbm file
147
dba_close($this->dba);
@@ -156,7 +157,7 @@ class getID3_cached_dbm extends getID3
156
157
158
// public: clear cache
159
- function clear_cache() {
160
161
// Close dbm file
162
dba_close($this->dba);
@@ -178,7 +179,7 @@ class getID3_cached_dbm extends getID3
178
179
180
// public: analyze file
181
- function analyze($filename) {
182
183
if (file_exists($filename)) {
184
@@ -206,6 +207,3 @@ class getID3_cached_dbm extends getID3
206
}
207
208
}
209
-
210
-
211
- ?>
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
+ // also https://github.com/JamesHeinrich/getID3 //
7
/////////////////////////////////////////////////////////////////
8
// //
9
// extension.cache.dbm.php - part of getID3() //
11
// ///
12
/////////////////////////////////////////////////////////////////
13
// //
14
+ // This extension written by Allan Hansen <ahØartemis*dk> //
15
// ///
16
/////////////////////////////////////////////////////////////////
17
74
{
75
76
// public: constructor - see top of this file for cache type and cache_options
77
+ public function getID3_cached_dbm($cache_type, $dbm_filename, $lock_filename) {
78
79
// Check for dba extension
80
if (!extension_loaded('dba')) {
136
$this->clear_cache();
137
}
138
139
+ parent::__construct();
140
}
141
142
143
144
+ // public: destructor
145
+ public function __destruct() {
146
147
// Close dbm file
148
dba_close($this->dba);
157
158
159
// public: clear cache
160
+ public function clear_cache() {
161
162
// Close dbm file
163
dba_close($this->dba);
179
180
181
// public: analyze file
182
+ public function analyze($filename) {
183
184
if (file_exists($filename)) {
185
207
}
208
209
}
lib/getid3/extension.cache.mysql.php CHANGED
@@ -3,6 +3,7 @@
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
/////////////////////////////////////////////////////////////////
7
// //
8
// extension.cache.mysql.php - part of getID3() //
@@ -10,8 +11,8 @@
10
// ///
11
/////////////////////////////////////////////////////////////////
12
// //
13
- // This extension written by Allan Hansen <ah�artemis*dk> //
14
- // Table name mod by Carlo Capocasa <calro�carlocapocasa*com> //
15
// ///
16
/////////////////////////////////////////////////////////////////
17
@@ -74,12 +75,12 @@ class getID3_cached_mysql extends getID3
74
{
75
76
// private vars
77
- var $cursor;
78
- var $connection;
79
80
81
// public: constructor - see top of this file for cache type and cache_options
82
- function getID3_cached_mysql($host, $database, $username, $password, $table='getid3_cache') {
83
84
// Check for mysql support
85
if (!function_exists('mysql_pconnect')) {
@@ -105,38 +106,49 @@ class getID3_cached_mysql extends getID3
105
106
// Check version number and clear cache if changed
107
$version = '';
108
- if ($this->cursor = mysql_query("SELECT `value` FROM `".mysql_real_escape_string($this->table)."` WHERE (`filename` = '".mysql_real_escape_string(getID3::VERSION)."') AND (`filesize` = '-1') AND (`filetime` = '-1') AND (`analyzetime` = '-1')", $this->connection)) {
109
list($version) = mysql_fetch_array($this->cursor);
110
}
111
if ($version != getID3::VERSION) {
112
$this->clear_cache();
113
}
114
115
- parent::getID3();
116
}
117
118
119
120
// public: clear cache
121
- function clear_cache() {
122
123
- $this->cursor = mysql_query("DELETE FROM `".mysql_real_escape_string($this->table)."`", $this->connection);
124
- $this->cursor = mysql_query("INSERT INTO `".mysql_real_escape_string($this->table)."` VALUES ('".getID3::VERSION."', -1, -1, -1, '".getID3::VERSION."')", $this->connection);
125
}
126
127
128
129
// public: analyze file
130
- function analyze($filename) {
131
132
if (file_exists($filename)) {
133
134
// Short-hands
135
$filetime = filemtime($filename);
136
- $filesize = filesize($filename);
137
138
// Lookup file
139
- $this->cursor = mysql_query("SELECT `value` FROM `".mysql_real_escape_string($this->table)."` WHERE (`filename` = '".mysql_real_escape_string($filename)."') AND (`filesize` = '".mysql_real_escape_string($filesize)."') AND (`filetime` = '".mysql_real_escape_string($filetime)."')", $this->connection);
140
if (mysql_num_rows($this->cursor) > 0) {
141
// Hit
142
list($result) = mysql_fetch_array($this->cursor);
@@ -145,11 +157,17 @@ class getID3_cached_mysql extends getID3
145
}
146
147
// Miss
148
- $analysis = parent::analyze($filename);
149
150
// Save result
151
if (file_exists($filename)) {
152
- $this->cursor = mysql_query("INSERT INTO `".mysql_real_escape_string($this->table)."` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES ('".mysql_real_escape_string($filename)."', '".mysql_real_escape_string($filesize)."', '".mysql_real_escape_string($filetime)."', '".mysql_real_escape_string(time())."', '".mysql_real_escape_string(base64_encode(serialize($analysis)))."')", $this->connection);
153
}
154
return $analysis;
155
}
@@ -157,17 +175,16 @@ class getID3_cached_mysql extends getID3
157
158
159
// private: (re)create sql table
160
- function create_table($drop=false) {
161
-
162
- $this->cursor = mysql_query("CREATE TABLE IF NOT EXISTS `".mysql_real_escape_string($this->table)."` (
163
- `filename` VARCHAR(255) NOT NULL DEFAULT '',
164
- `filesize` INT(11) NOT NULL DEFAULT '0',
165
- `filetime` INT(11) NOT NULL DEFAULT '0',
166
- `analyzetime` INT(11) NOT NULL DEFAULT '0',
167
- `value` TEXT NOT NULL,
168
- PRIMARY KEY (`filename`,`filesize`,`filetime`)) TYPE=MyISAM", $this->connection);
169
echo mysql_error($this->connection);
170
}
171
}
172
-
173
- ?>
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
+ // also https://github.com/JamesHeinrich/getID3 //
7
/////////////////////////////////////////////////////////////////
8
// //
9
// extension.cache.mysql.php - part of getID3() //
11
// ///
12
/////////////////////////////////////////////////////////////////
13
// //
14
+ // This extension written by Allan Hansen <ahØartemis*dk> //
15
+ // Table name mod by Carlo Capocasa <calroØcarlocapocasa*com> //
16
// ///
17
/////////////////////////////////////////////////////////////////
18
75
{
76
77
// private vars
78
+ private $cursor;
79
+ private $connection;
80
81
82
// public: constructor - see top of this file for cache type and cache_options
83
+ public function getID3_cached_mysql($host, $database, $username, $password, $table='getid3_cache') {
84
85
// Check for mysql support
86
if (!function_exists('mysql_pconnect')) {
106
107
// Check version number and clear cache if changed
108
$version = '';
109
+ $SQLquery = 'SELECT `value`';
110
+ $SQLquery .= ' FROM `'.mysql_real_escape_string($this->table).'`';
111
+ $SQLquery .= ' WHERE (`filename` = \''.mysql_real_escape_string(getID3::VERSION).'\')';
112
+ $SQLquery .= ' AND (`filesize` = -1)';
113
+ $SQLquery .= ' AND (`filetime` = -1)';
114
+ $SQLquery .= ' AND (`analyzetime` = -1)';
115
+ if ($this->cursor = mysql_query($SQLquery, $this->connection)) {
116
list($version) = mysql_fetch_array($this->cursor);
117
}
118
if ($version != getID3::VERSION) {
119
$this->clear_cache();
120
}
121
122
+ parent::__construct();
123
}
124
125
126
127
// public: clear cache
128
+ public function clear_cache() {
129
130
+ $this->cursor = mysql_query('DELETE FROM `'.mysql_real_escape_string($this->table).'`', $this->connection);
131
+ $this->cursor = mysql_query('INSERT INTO `'.mysql_real_escape_string($this->table).'` VALUES (\''.getID3::VERSION.'\', -1, -1, -1, \''.getID3::VERSION.'\')', $this->connection);
132
}
133
134
135
136
// public: analyze file
137
+ public function analyze($filename, $filesize=null, $original_filename='') {
138
139
if (file_exists($filename)) {
140
141
// Short-hands
142
$filetime = filemtime($filename);
143
+ $filesize = filesize($filename);
144
145
// Lookup file
146
+ $SQLquery = 'SELECT `value`';
147
+ $SQLquery .= ' FROM `'.mysql_real_escape_string($this->table).'`';
148
+ $SQLquery .= ' WHERE (`filename` = \''.mysql_real_escape_string($filename).'\')';
149
+ $SQLquery .= ' AND (`filesize` = \''.mysql_real_escape_string($filesize).'\')';
150
+ $SQLquery .= ' AND (`filetime` = \''.mysql_real_escape_string($filetime).'\')';
151
+ $this->cursor = mysql_query($SQLquery, $this->connection);
152
if (mysql_num_rows($this->cursor) > 0) {
153
// Hit
154
list($result) = mysql_fetch_array($this->cursor);
157
}
158
159
// Miss
160
+ $analysis = parent::analyze($filename, $filesize, $original_filename);
161
162
// Save result
163
if (file_exists($filename)) {
164
+ $SQLquery = 'INSERT INTO `'.mysql_real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (';
165
+ $SQLquery .= '\''.mysql_real_escape_string($filename).'\'';
166
+ $SQLquery .= ', \''.mysql_real_escape_string($filesize).'\'';
167
+ $SQLquery .= ', \''.mysql_real_escape_string($filetime).'\'';
168
+ $SQLquery .= ', \''.mysql_real_escape_string(time() ).'\'';
169
+ $SQLquery .= ', \''.mysql_real_escape_string(base64_encode(serialize($analysis))).'\')';
170
+ $this->cursor = mysql_query($SQLquery, $this->connection);
171
}
172
return $analysis;
173
}
175
176
177
// private: (re)create sql table
178
+ private function create_table($drop=false) {
179
+
180
+ $SQLquery = 'CREATE TABLE IF NOT EXISTS `'.mysql_real_escape_string($this->table).'` (';
181
+ $SQLquery .= '`filename` VARCHAR(500) NOT NULL DEFAULT \'\'';
182
+ $SQLquery .= ', `filesize` INT(11) NOT NULL DEFAULT \'0\'';
183
+ $SQLquery .= ', `filetime` INT(11) NOT NULL DEFAULT \'0\'';
184
+ $SQLquery .= ', `analyzetime` INT(11) NOT NULL DEFAULT \'0\'';
185
+ $SQLquery .= ', `value` LONGTEXT NOT NULL';
186
+ $SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`)) ENGINE=MyISAM';
187
+ $this->cursor = mysql_query($SQLquery, $this->connection);
188
echo mysql_error($this->connection);
189
}
190
}
lib/getid3/extension.cache.sqlite3.php ADDED
@@ -0,0 +1,266 @@
1
+ <?php
2
+ /////////////////////////////////////////////////////////////////////////////////
3
+ /// getID3() by James Heinrich <info@getid3.org> //
4
+ // available at http://getid3.sourceforge.net //
5
+ // or http://www.getid3.org //
6
+ // also https://github.com/JamesHeinrich/getID3 //
7
+ /////////////////////////////////////////////////////////////////////////////////
8
+ /// //
9
+ // extension.cache.sqlite3.php - part of getID3() //
10
+ // Please see readme.txt for more information //
11
+ // ///
12
+ /////////////////////////////////////////////////////////////////////////////////
13
+ /// //
14
+ // MySQL extension written by Allan Hansen <ahØartemis*dk> //
15
+ // Table name mod by Carlo Capocasa <calroØcarlocapocasa*com> //
16
+ // MySQL extension was reworked for SQLite3 by Karl G. Holz <newaeonØmac*com> //
17
+ // ///
18
+ /////////////////////////////////////////////////////////////////////////////////
19
+ /**
20
+ * This is a caching extension for getID3(). It works the exact same
21
+ * way as the getID3 class, but return cached information much faster
22
+ *
23
+ * Normal getID3 usage (example):
24
+ *
25
+ * require_once 'getid3/getid3.php';
26
+ * $getID3 = new getID3;
27
+ * $getID3->encoding = 'UTF-8';
28
+ * $info1 = $getID3->analyze('file1.flac');
29
+ * $info2 = $getID3->analyze('file2.wv');
30
+ *
31
+ * getID3_cached usage:
32
+ *
33
+ * require_once 'getid3/getid3.php';
34
+ * require_once 'getid3/extension.cache.sqlite3.php';
35
+ * // all parameters are optional, defaults are:
36
+ * $getID3 = new getID3_cached_sqlite3($table='getid3_cache', $hide=FALSE);
37
+ * $getID3->encoding = 'UTF-8';
38
+ * $info1 = $getID3->analyze('file1.flac');
39
+ * $info2 = $getID3->analyze('file2.wv');
40
+ *
41
+ *
42
+ * Supported Cache Types (this extension)
43
+ *
44
+ * SQL Databases:
45
+ *
46
+ * cache_type cache_options
47
+ * -------------------------------------------------------------------
48
+ * mysql host, database, username, password
49
+ *
50
+ * sqlite3 table='getid3_cache', hide=false (PHP5)
51
+ *
52
+ *
53
+ * *** database file will be stored in the same directory as this script,
54
+ * *** webserver must have write access to that directory!
55
+ * *** set $hide to TRUE to prefix db file with .ht to pervent access from web client
56
+ * *** this is a default setting in the Apache configuration:
57
+ *
58
+ * The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
59
+ *
60
+ * <Files ~ "^\.ht">
61
+ * Order allow,deny
62
+ * Deny from all
63
+ * Satisfy all
64
+ * </Files>
65
+ *
66
+ ********************************************************************************
67
+ *
68
+ * -------------------------------------------------------------------
69
+ * DBM-Style Databases: (use extension.cache.dbm)
70
+ *
71
+ * cache_type cache_options
72
+ * -------------------------------------------------------------------
73
+ * gdbm dbm_filename, lock_filename
74
+ * ndbm dbm_filename, lock_filename
75
+ * db2 dbm_filename, lock_filename
76
+ * db3 dbm_filename, lock_filename
77
+ * db4 dbm_filename, lock_filename (PHP5 required)
78
+ *
79
+ * PHP must have write access to both dbm_filename and lock_filename.
80
+ *
81
+ * Recommended Cache Types
82
+ *
83
+ * Infrequent updates, many reads any DBM
84
+ * Frequent updates mysql
85
+ ********************************************************************************
86
+ *
87
+ * IMHO this is still a bit slow, I'm using this with MP4/MOV/ M4v files
88
+ * there is a plan to add directory scanning and analyzing to make things work much faster
89
+ *
90
+ *
91
+ */
92
+ class getID3_cached_sqlite3 extends getID3 {
93
+
94
+ /**
95
+ * __construct()
96
+ * @param string $table holds name of sqlite table
97
+ * @return type
98
+ */
99
+ public function __construct($table='getid3_cache', $hide=false) {
100
+ $this->table = $table; // Set table
101
+ $file = dirname(__FILE__).'/'.basename(__FILE__, 'php').'sqlite';
102
+ if ($hide) {
103
+ $file = dirname(__FILE__).'/.ht.'.basename(__FILE__, 'php').'sqlite';
104
+ }
105
+ $this->db = new SQLite3($file);
106
+ $db = $this->db;
107
+ $this->create_table(); // Create cache table if not exists
108
+ $version = '';
109
+ $sql = $this->version_check;
110
+ $stmt = $db->prepare($sql);
111
+ $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
112
+ $result = $stmt->execute();
113
+ list($version) = $result->fetchArray();
114
+ if ($version != getID3::VERSION) { // Check version number and clear cache if changed
115
+ $this->clear_cache();
116
+ }
117
+ return parent::__construct();
118
+ }
119
+
120
+ /**
121
+ * close the database connection
122
+ */
123
+ public function __destruct() {
124
+ $db=$this->db;
125
+ $db->close();
126
+ }
127
+
128
+ /**
129
+ * hold the sqlite db
130
+ * @var SQLite Resource
131
+ */
132
+ private $db;
133
+
134
+ /**
135
+ * table to use for caching
136
+ * @var string $table
137
+ */
138
+ private $table;
139
+
140
+ /**
141
+ * clear the cache
142
+ * @access private
143
+ * @return type
144
+ */
145
+ private function clear_cache() {
146
+ $db = $this->db;
147
+ $sql = $this->delete_cache;
148
+ $db->exec($sql);
149
+ $sql = $this->set_version;
150
+ $stmt = $db->prepare($sql);
151
+ $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
152
+ $stmt->bindValue(':dirname', getID3::VERSION, SQLITE3_TEXT);
153
+ $stmt->bindValue(':val', getID3::VERSION, SQLITE3_TEXT);
154
+ return $stmt->execute();
155
+ }
156
+
157
+ /**
158
+ * analyze file and cache them, if cached pull from the db
159
+ * @param type $filename
160
+ * @return boolean
161
+ */
162
+ public function analyze($filename, $filesize=null, $original_filename='') {
163
+ if (!file_exists($filename)) {
164
+ return false;
165
+ }
166
+ // items to track for caching
167
+ $filetime = filemtime($filename);
168
+ $filesize = filesize($filename);
169
+ // this will be saved for a quick directory lookup of analized files
170
+ // ... why do 50 seperate sql quries when you can do 1 for the same result
171
+ $dirname = dirname($filename);
172
+ // Lookup file
173
+ $db = $this->db;
174
+ $sql = $this->get_id3_data;
175
+ $stmt = $db->prepare($sql);
176
+ $stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
177
+ $stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
178
+ $stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
179
+ $res = $stmt->execute();
180
+ list($result) = $res->fetchArray();
181
+ if (count($result) > 0 ) {
182
+ return unserialize(base64_decode($result));
183
+ }
184
+ // if it hasn't been analyzed before, then do it now
185
+ $analysis = parent::analyze($filename, $filesize=null, $original_filename='');
186
+ // Save result
187
+ $sql = $this->cache_file;
188
+ $stmt = $db->prepare($sql);
189
+ $stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
190
+ $stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT);
191
+ $stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
192
+ $stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
193
+ $stmt->bindValue(':atime', time(), SQLITE3_INTEGER);
194
+ $stmt->bindValue(':val', base64_encode(serialize($analysis)), SQLITE3_TEXT);
195
+ $res = $stmt->execute();
196
+ return $analysis;
197
+ }
198
+
199
+ /**
200
+ * create data base table
201
+ * this is almost the same as MySQL, with the exception of the dirname being added
202
+ * @return type
203
+ */
204
+ private function create_table() {
205
+ $db = $this->db;
206
+ $sql = $this->make_table;
207
+ return $db->exec($sql);
208
+ }
209
+
210
+ /**
211
+ * get cached directory
212
+ *
213
+ * This function is not in the MySQL extention, it's ment to speed up requesting multiple files
214
+ * which is ideal for podcasting, playlists, etc.
215
+ *
216
+ * @access public
217
+ * @param string $dir directory to search the cache database for
218
+ * @return array return an array of matching id3 data
219
+ */
220
+ public function get_cached_dir($dir) {
221
+ $db = $this->db;
222
+ $rows = array();
223
+ $sql = $this->get_cached_dir;
224
+ $stmt = $db->prepare($sql);
225
+ $stmt->bindValue(':dirname', $dir, SQLITE3_TEXT);
226
+ $res = $stmt->execute();
227
+ while ($row=$res->fetchArray()) {
228
+ $rows[] = unserialize(base64_decode($row));
229
+ }
230
+ return $rows;
231
+ }
232
+
233
+ /**
234
+ * use the magical __get() for sql queries
235
+ *
236
+ * access as easy as $this->{case name}, returns NULL if query is not found
237
+ */
238
+ public function __get($name) {
239
+ switch($name) {
240
+ case 'version_check':
241
+ return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = '-1' AND filetime = '-1' AND analyzetime = '-1'";
242
+ break;
243
+ case 'delete_cache':
244
+ return "DELETE FROM $this->table";
245
+ break;
246
+ case 'set_version':
247
+ return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, -1, -1, -1, :val)";
248
+ break;
249
+ case 'get_id3_data':
250
+ return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = :filesize AND filetime = :filetime";
251
+ break;
252
+ case 'cache_file':
253
+ return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)";
254
+ break;
255
+ case 'make_table':
256
+ //return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) NOT NULL DEFAULT '', dirname VARCHAR(255) NOT NULL DEFAULT '', filesize INT(11) NOT NULL DEFAULT '0', filetime INT(11) NOT NULL DEFAULT '0', analyzetime INT(11) NOT NULL DEFAULT '0', val text not null, PRIMARY KEY (filename, filesize, filetime))";
257
+ return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) DEFAULT '', dirname VARCHAR(255) DEFAULT '', filesize INT(11) DEFAULT '0', filetime INT(11) DEFAULT '0', analyzetime INT(11) DEFAULT '0', val text, PRIMARY KEY (filename, filesize, filetime))";
258
+ break;
259
+ case 'get_cached_dir':
260
+ return "SELECT val FROM $this->table WHERE dirname = :dirname";
261
+ break;
262
+ }
263
+ return null;
264
+ }
265
+
266
+ }
lib/getid3/getid3.lib.php CHANGED
@@ -3,6 +3,7 @@
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
/////////////////////////////////////////////////////////////////
7
// //
8
// getid3.lib.php - part of getID3() //
@@ -14,13 +15,13 @@
14
class getid3_lib
15
{
16
17
- static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') {
18
$returnstring = '';
19
for ($i = 0; $i < strlen($string); $i++) {
20
if ($hex) {
21
$returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
22
} else {
23
- $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '�');
24
}
25
if ($spaces) {
26
$returnstring .= ' ';
@@ -35,7 +36,7 @@ class getid3_lib
35
return $returnstring;
36
}
37
38
- static function trunc($floatnumber) {
39
// truncates a floating-point number at the decimal point
40
// returns int (if possible, otherwise float)
41
if ($floatnumber >= 1) {
@@ -45,14 +46,14 @@ class getid3_lib
45
} else {
46
$truncatednumber = 0;
47
}
48
- if (getid3_lib::intValueSupported($truncatednumber)) {
49
$truncatednumber = (int) $truncatednumber;
50
}
51
return $truncatednumber;
52
}
53
54
55
- static function safe_inc(&$variable, $increment=1) {
56
if (isset($variable)) {
57
$variable += $increment;
58
} else {
@@ -61,14 +62,14 @@ class getid3_lib
61
return true;
62
}
63
64
- static function CastAsInt($floatnum) {
65
// convert to float if not already
66
$floatnum = (float) $floatnum;
67
68
// convert a float to type int, only if possible
69
- if (getid3_lib::trunc($floatnum) == $floatnum) {
70
// it's not floating point
71
- if (getid3_lib::intValueSupported($floatnum)) {
72
// it's within int range
73
$floatnum = (int) $floatnum;
74
}
@@ -92,20 +93,20 @@ class getid3_lib
92
return false;
93
}
94
95
- static function DecimalizeFraction($fraction) {
96
list($numerator, $denominator) = explode('/', $fraction);
97
return $numerator / ($denominator ? $denominator : 1);
98
}
99
100
101
- static function DecimalBinary2Float($binarynumerator) {
102
- $numerator = getid3_lib::Bin2Dec($binarynumerator);
103
- $denominator = getid3_lib::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator)));
104
return ($numerator / $denominator);
105
}
106
107
108
- static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
109
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
110
if (strpos($binarypointnumber, '.') === false) {
111
$binarypointnumber = '0.'.$binarypointnumber;
@@ -129,23 +130,23 @@ class getid3_lib
129
}
130
131
132
- static function Float2BinaryDecimal($floatvalue) {
133
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
134
$maxbits = 128; // to how many bits of precision should the calculations be taken?
135
- $intpart = getid3_lib::trunc($floatvalue);
136
$floatpart = abs($floatvalue - $intpart);
137
$pointbitstring = '';
138
while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) {
139
$floatpart *= 2;
140
- $pointbitstring .= (string) getid3_lib::trunc($floatpart);
141
- $floatpart -= getid3_lib::trunc($floatpart);
142
}
143
$binarypointnumber = decbin($intpart).'.'.$pointbitstring;
144
return $binarypointnumber;
145
}
146
147
148
- static function Float2String($floatvalue, $bits) {
149
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
150
switch ($bits) {
151
case 32:
@@ -167,26 +168,26 @@ class getid3_lib
167
} else {
168
$signbit = '1';
169
}
170
- $normalizedbinary = getid3_lib::NormalizeBinaryPoint(getid3_lib::Float2BinaryDecimal($floatvalue), $fractionbits);
171
$biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent
172
$exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT);
173
$fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT);
174
175
- return getid3_lib::BigEndian2String(getid3_lib::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false);
176
}
177
178
179
- static function LittleEndian2Float($byteword) {
180
- return getid3_lib::BigEndian2Float(strrev($byteword));
181
}
182
183
184
- static function BigEndian2Float($byteword) {
185
// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
186
// http://www.psc.edu/general/software/packages/ieee/ieee.html
187
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
188
189
- $bitword = getid3_lib::BigEndian2Bin($byteword);
190
if (!$bitword) {
191
return 0;
192
}
@@ -209,8 +210,8 @@ class getid3_lib
209
$exponentstring = substr($bitword, 1, 15);
210
$isnormalized = intval($bitword{16});
211
$fractionstring = substr($bitword, 17, 63);
212
- $exponent = pow(2, getid3_lib::Bin2Dec($exponentstring) - 16383);
213
- $fraction = $isnormalized + getid3_lib::DecimalBinary2Float($fractionstring);
214
$floatvalue = $exponent * $fraction;
215
if ($signbit == '1') {
216
$floatvalue *= -1;
@@ -224,8 +225,8 @@ class getid3_lib
224
}
225
$exponentstring = substr($bitword, 1, $exponentbits);
226
$fractionstring = substr($bitword, $exponentbits + 1, $fractionbits);
227
- $exponent = getid3_lib::Bin2Dec($exponentstring);
228
- $fraction = getid3_lib::Bin2Dec($fractionstring);
229
230
if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
231
// Not a Number
@@ -245,12 +246,12 @@ class getid3_lib
245
$floatvalue = ($signbit ? 0 : -0);
246
} elseif (($exponent == 0) && ($fraction != 0)) {
247
// These are 'unnormalized' values
248
- $floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * getid3_lib::DecimalBinary2Float($fractionstring);
249
if ($signbit == '1') {
250
$floatvalue *= -1;
251
}
252
} elseif ($exponent != 0) {
253
- $floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + getid3_lib::DecimalBinary2Float($fractionstring));
254
if ($signbit == '1') {
255
$floatvalue *= -1;
256
}
@@ -259,7 +260,7 @@ class getid3_lib
259
}
260
261
262
- static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) {
263
$intvalue = 0;
264
$bytewordlen = strlen($byteword);
265
if ($bytewordlen == 0) {
@@ -281,20 +282,19 @@ class getid3_lib
281
$intvalue = 0 - ($intvalue & ($signMaskBit - 1));
282
}
283
} else {
284
- throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits ('.strlen($byteword).') in getid3_lib::BigEndian2Int()');
285
- break;
286
}
287
}
288
- return getid3_lib::CastAsInt($intvalue);
289
}
290
291
292
- static function LittleEndian2Int($byteword, $signed=false) {
293
- return getid3_lib::BigEndian2Int(strrev($byteword), false, $signed);
294
}
295
296
297
- static function BigEndian2Bin($byteword) {
298
$binvalue = '';
299
$bytewordlen = strlen($byteword);
300
for ($i = 0; $i < $bytewordlen; $i++) {
@@ -304,15 +304,15 @@ class getid3_lib
304
}
305
306
307
- static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) {
308
if ($number < 0) {
309
- throw new Exception('ERROR: getid3_lib::BigEndian2String() does not support negative numbers');
310
}
311
$maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF);
312
$intstring = '';
313
if ($signed) {
314
if ($minbytes > PHP_INT_SIZE) {
315
- throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits in getid3_lib::BigEndian2String()');
316
}
317
$number = $number & (0x80 << (8 * ($minbytes - 1)));
318
}
@@ -325,7 +325,7 @@ class getid3_lib
325
}
326
327
328
- static function Dec2Bin($number) {
329
while ($number >= 256) {
330
$bytes[] = (($number / 256) - (floor($number / 256))) * 256;
331
$number = floor($number / 256);
@@ -339,7 +339,7 @@ class getid3_lib
339
}
340
341
342
- static function Bin2Dec($binstring, $signed=false) {
343
$signmult = 1;
344
if ($signed) {
345
if ($binstring{0} == '1') {
@@ -351,22 +351,22 @@ class getid3_lib
351
for ($i = 0; $i < strlen($binstring); $i++) {
352
$decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i);
353
}
354
- return getid3_lib::CastAsInt($decvalue * $signmult);
355
}
356
357
358
- static function Bin2String($binstring) {
359
// return 'hi' for input of '0110100001101001'
360
$string = '';
361
$binstringreversed = strrev($binstring);
362
for ($i = 0; $i < strlen($binstringreversed); $i += 8) {
363
- $string = chr(getid3_lib::Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string;
364
}
365
return $string;
366
}
367
368
369
- static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
370
$intstring = '';
371
while ($number > 0) {
372
if ($synchsafe) {
@@ -381,8 +381,8 @@ class getid3_lib
381
}
382
383
384
- static function array_merge_clobber($array1, $array2) {
385
- // written by kc�hireability*com
386
// taken from http://www.php.net/manual/en/function.array-merge-recursive.php
387
if (!is_array($array1) || !is_array($array2)) {
388
return false;
@@ -390,7 +390,7 @@ class getid3_lib
390
$newarray = $array1;
391
foreach ($array2 as $key => $val) {
392
if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
393
- $newarray[$key] = getid3_lib::array_merge_clobber($newarray[$key], $val);
394
} else {
395
$newarray[$key] = $val;
396
}
@@ -399,14 +399,14 @@ class getid3_lib
399
}
400
401
402
- static function array_merge_noclobber($array1, $array2) {
403
if (!is_array($array1) || !is_array($array2)) {
404
return false;
405
}
406
$newarray = $array1;
407
foreach ($array2 as $key => $val) {
408
if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
409
- $newarray[$key] = getid3_lib::array_merge_noclobber($newarray[$key], $val);
410
} elseif (!isset($newarray[$key])) {
411
$newarray[$key] = $val;
412
}
@@ -414,8 +414,22 @@ class getid3_lib
414
return $newarray;
415
}
416
417
418
- static function ksort_recursive(&$theArray) {
419
ksort($theArray);
420
foreach ($theArray as $key => $value) {
421
if (is_array($value)) {
@@ -425,7 +439,7 @@ class getid3_lib
425
return true;
426
}
427
428
- static function fileextension($filename, $numextensions=1) {
429
if (strstr($filename, '.')) {
430
$reversedfilename = strrev($filename);
431
$offset = 0;
@@ -441,58 +455,56 @@ class getid3_lib
441
}
442
443
444
- static function PlaytimeString($seconds) {
445
$sign = (($seconds < 0) ? '-' : '');
446
- $seconds = abs($seconds);
447
- $H = floor( $seconds / 3600);
448
- $M = floor(($seconds - (3600 * $H) ) / 60);
449
- $S = round( $seconds - (3600 * $H) - (60 * $M) );
450
return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
451
}
452
453
454
- static function DateMac2Unix($macdate) {
455
// Macintosh timestamp: seconds since 00:00h January 1, 1904
456
// UNIX timestamp: seconds since 00:00h January 1, 1970
457
- return getid3_lib::CastAsInt($macdate - 2082844800);
458
}
459
460
461
- static function FixedPoint8_8($rawdata) {
462
- return getid3_lib::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (getid3_lib::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8));
463
}
464
465
466
- static function FixedPoint16_16($rawdata) {
467
- return getid3_lib::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (getid3_lib::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16));
468
}
469
470
471
- static function FixedPoint2_30($rawdata) {
472
- $binarystring = getid3_lib::BigEndian2Bin($rawdata);
473
- return getid3_lib::Bin2Dec(substr($binarystring, 0, 2)) + (float) (getid3_lib::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30));
474
}
475
476
477
- static function CreateDeepArray($ArrayPath, $Separator, $Value) {
478
// assigns $Value to a nested array path:
479
- // $foo = getid3_lib::CreateDeepArray('/path/to/my', '/', 'file.txt')
480
// is the same as:
481
// $foo = array('path'=>array('to'=>'array('my'=>array('file.txt'))));
482
// or
483
// $foo['path']['to']['my'] = 'file.txt';
484
- while ($ArrayPath && ($ArrayPath{0} == $Separator)) {
485
- $ArrayPath = substr($ArrayPath, 1);
486
- }
487
if (($pos = strpos($ArrayPath, $Separator)) !== false) {
488
- $ReturnedArray[substr($ArrayPath, 0, $pos)] = getid3_lib::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
489
} else {
490
$ReturnedArray[$ArrayPath] = $Value;
491
}
492
return $ReturnedArray;
493
}
494
495
- static function array_max($arraydata, $returnkey=false) {
496
$maxvalue = false;
497
$maxkey = false;
498
foreach ($arraydata as $key => $value) {
@@ -506,7 +518,7 @@ class getid3_lib
506
return ($returnkey ? $maxkey : $maxvalue);
507
}
508
509
- static function array_min($arraydata, $returnkey=false) {
510
$minvalue = false;
511
$minkey = false;
512
foreach ($arraydata as $key => $value) {
@@ -520,17 +532,20 @@ class getid3_lib
520
return ($returnkey ? $minkey : $minvalue);
521
}
522
523
- static function XML2array($XMLstring) {
524
- if (function_exists('simplexml_load_string')) {
525
- if (function_exists('get_object_vars')) {
526
- $XMLobject = simplexml_load_string($XMLstring);
527
- return self::SimpleXMLelement2array($XMLobject);
528
- }
529
}
530
return false;
531
}
532
533
- static function SimpleXMLelement2array($XMLobject) {
534
if (!is_object($XMLobject) && !is_array($XMLobject)) {
535
return $XMLobject;
536
}
@@ -542,11 +557,11 @@ class getid3_lib
542
}
543
544
545
- // Allan Hansen <ah�artemis*dk>
546
- // getid3_lib::md5_data() - returns md5sum for a file from startuing position to absolute end position
547
- static function hash_data($file, $offset, $end, $algorithm) {
548
static $tempdir = '';
549
- if (!getid3_lib::intValueSupported($end)) {
550
return false;
551
}
552
switch ($algorithm) {
@@ -565,7 +580,7 @@ class getid3_lib
565
break;
566
567
default:
568
- throw new Exception('Invalid algorithm ('.$algorithm.') in getid3_lib::hash_data()');
569
break;
570
}
571
$size = $end - $offset;
@@ -582,10 +597,10 @@ class getid3_lib
582
foreach ($RequiredFiles as $required_file) {
583
if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
584
// helper apps not available - fall back to old method
585
- break;
586
}
587
}
588
- $commandline = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' "'.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).'" | ';
589
$commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
590
$commandline .= GETID3_HELPERAPPSDIR.$windows_call;
591
@@ -621,22 +636,22 @@ class getid3_lib
621
622
// copy parts of file
623
try {
624
- getid3_lib::CopyFileParts($file, $data_filename, $offset, $end - $offset);
625
$result = $hash_function($data_filename);
626
} catch (Exception $e) {
627
- throw new Exception('getid3_lib::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage());
628
}
629
unlink($data_filename);
630
return $result;
631
}
632
633
- static function CopyFileParts($filename_source, $filename_dest, $offset, $length) {
634
- if (!getid3_lib::intValueSupported($offset + $length)) {
635
throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit');
636
}
637
if (is_readable($filename_source) && is_file($filename_source) && ($fp_src = fopen($filename_source, 'rb'))) {
638
if (($fp_dest = fopen($filename_dest, 'wb'))) {
639
- if (fseek($fp_src, $offset, SEEK_SET) == 0) {
640
$byteslefttowrite = $length;
641
while (($byteslefttowrite > 0) && ($buffer = fread($fp_src, min($byteslefttowrite, getID3::FREAD_BUFFER_SIZE)))) {
642
$byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite);
@@ -657,7 +672,7 @@ class getid3_lib
657
return false;
658
}
659
660
- static function iconv_fallback_int_utf8($charval) {
661
if ($charval < 128) {
662
// 0bbbbbbb
663
$newcharstring = chr($charval);
@@ -681,7 +696,7 @@ class getid3_lib
681
}
682
683
// ISO-8859-1 => UTF-8
684
- static function iconv_fallback_iso88591_utf8($string, $bom=false) {
685
if (function_exists('utf8_encode')) {
686
return utf8_encode($string);
687
}
@@ -692,13 +707,13 @@ class getid3_lib
692
}
693
for ($i = 0; $i < strlen($string); $i++) {
694
$charval = ord($string{$i});
695
- $newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
696
}
697
return $newcharstring;
698
}
699
700
// ISO-8859-1 => UTF-16BE
701
- static function iconv_fallback_iso88591_utf16be($string, $bom=false) {
702
$newcharstring = '';
703
if ($bom) {
704
$newcharstring .= "\xFE\xFF";
@@ -710,7 +725,7 @@ class getid3_lib
710
}
711
712
// ISO-8859-1 => UTF-16LE
713
- static function iconv_fallback_iso88591_utf16le($string, $bom=false) {
714
$newcharstring = '';
715
if ($bom) {
716
$newcharstring .= "\xFF\xFE";
@@ -722,12 +737,12 @@ class getid3_lib
722
}
723
724
// ISO-8859-1 => UTF-16LE (BOM)
725
- static function iconv_fallback_iso88591_utf16($string) {
726
- return getid3_lib::iconv_fallback_iso88591_utf16le($string, true);
727
}
728
729
// UTF-8 => ISO-8859-1
730
- static function iconv_fallback_utf8_iso88591($string) {
731
if (function_exists('utf8_decode')) {
732
return utf8_decode($string);
733
}
@@ -771,7 +786,7 @@ class getid3_lib
771
}
772
773
// UTF-8 => UTF-16BE
774
- static function iconv_fallback_utf8_utf16be($string, $bom=false) {
775
$newcharstring = '';
776
if ($bom) {
777
$newcharstring .= "\xFE\xFF";
@@ -807,14 +822,14 @@ class getid3_lib
807
$offset += 1;
808
}
809
if ($charval !== false) {
810
- $newcharstring .= (($charval < 65536) ? getid3_lib::BigEndian2String($charval, 2) : "\x00".'?');
811
}
812
}
813
return $newcharstring;
814
}
815
816
// UTF-8 => UTF-16LE
817
- static function iconv_fallback_utf8_utf16le($string, $bom=false) {
818
$newcharstring = '';
819
if ($bom) {
820
$newcharstring .= "\xFF\xFE";
@@ -850,96 +865,96 @@ class getid3_lib
850
$offset += 1;
851
}
852
if ($charval !== false) {
853
- $newcharstring .= (($charval < 65536) ? getid3_lib::LittleEndian2String($charval, 2) : '?'."\x00");
854
}
855
}
856
return $newcharstring;
857
}
858
859
// UTF-8 => UTF-16LE (BOM)
860
- static function iconv_fallback_utf8_utf16($string) {
861
- return getid3_lib::iconv_fallback_utf8_utf16le($string, true);
862
}
863
864
// UTF-16BE => UTF-8
865
- static function iconv_fallback_utf16be_utf8($string) {
866
if (substr($string, 0, 2) == "\xFE\xFF") {
867
// strip BOM
868
$string = substr($string, 2);
869
}
870
$newcharstring = '';
871
for ($i = 0; $i < strlen($string); $i += 2) {
872
- $charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
873
- $newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
874
}
875
return $newcharstring;
876
}
877
878
// UTF-16LE => UTF-8
879
- static function iconv_fallback_utf16le_utf8($string) {
880
if (substr($string, 0, 2) == "\xFF\xFE") {
881
// strip BOM
882
$string = substr($string, 2);
883
}
884
$newcharstring = '';
885
for ($i = 0; $i < strlen($string); $i += 2) {
886
- $charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
887
- $newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
888
}
889
return $newcharstring;
890
}
891
892
// UTF-16BE => ISO-8859-1
893
- static function iconv_fallback_utf16be_iso88591($string) {
894
if (substr($string, 0, 2) == "\xFE\xFF") {
895
// strip BOM
896
$string = substr($string, 2);
897
}
898
$newcharstring = '';
899
for ($i = 0; $i < strlen($string); $i += 2) {
900
- $charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
901
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
902
}
903
return $newcharstring;
904
}
905
906
// UTF-16LE => ISO-8859-1
907
- static function iconv_fallback_utf16le_iso88591($string) {
908
if (substr($string, 0, 2) == "\xFF\xFE") {
909
// strip BOM
910
$string = substr($string, 2);
911
}
912
$newcharstring = '';
913
for ($i = 0; $i < strlen($string); $i += 2) {
914
- $charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
915
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
916
}
917
return $newcharstring;
918
}
919
920
// UTF-16 (BOM) => ISO-8859-1
921
- static function iconv_fallback_utf16_iso88591($string) {
922
$bom = substr($string, 0, 2);
923
if ($bom == "\xFE\xFF") {
924
- return getid3_lib::iconv_fallback_utf16be_iso88591(substr($string, 2));
925
} elseif ($bom == "\xFF\xFE") {
926
- return getid3_lib::iconv_fallback_utf16le_iso88591(substr($string, 2));
927
}
928
return $string;
929
}
930
931
// UTF-16 (BOM) => UTF-8
932
- static function iconv_fallback_utf16_utf8($string) {
933
$bom = substr($string, 0, 2);
934
if ($bom == "\xFE\xFF") {
935
- return getid3_lib::iconv_fallback_utf16be_utf8(substr($string, 2));
936
} elseif ($bom == "\xFF\xFE") {
937
- return getid3_lib::iconv_fallback_utf16le_utf8(substr($string, 2));
938
}
939
return $string;
940
}
941
942
- static function iconv_fallback($in_charset, $out_charset, $string) {
943
944
if ($in_charset == $out_charset) {
945
return $string;
@@ -982,13 +997,26 @@ class getid3_lib
982
}
983
if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
984
$ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
985
- return getid3_lib::$ConversionFunction($string);
986
}
987
throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
988
}
989
990
991
- static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') {
992
$string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string
993
$HTMLstring = '';
994
@@ -1053,7 +1081,7 @@ class getid3_lib
1053
1054
case 'UTF-16LE':
1055
for ($i = 0; $i < strlen($string); $i += 2) {
1056
- $charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
1057
if (($charval >= 32) && ($charval <= 127)) {
1058
$HTMLstring .= chr($charval);
1059
} else {
@@ -1064,7 +1092,7 @@ class getid3_lib
1064
1065
case 'UTF-16BE':
1066
for ($i = 0; $i < strlen($string); $i += 2) {
1067
- $charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
1068
if (($charval >= 32) && ($charval <= 127)) {
1069
$HTMLstring .= chr($charval);
1070
} else {
@@ -1082,7 +1110,7 @@ class getid3_lib
1082
1083
1084
1085
- static function RGADnameLookup($namecode) {
1086
static $RGADname = array();
1087
if (empty($RGADname)) {
1088
$RGADname[0] = 'not set';
@@ -1094,7 +1122,7 @@ class getid3_lib
1094
}
1095
1096
1097
- static function RGADoriginatorLookup($originatorcode) {
1098
static $RGADoriginator = array();
1099
if (empty($RGADoriginator)) {
1100
$RGADoriginator[0] = 'unspecified';
@@ -1107,7 +1135,7 @@ class getid3_lib
1107
}
1108
1109
1110
- static function RGADadjustmentLookup($rawadjustment, $signbit) {
1111
$adjustment = $rawadjustment / 10;
1112
if ($signbit == 1) {
1113
$adjustment *= -1;
@@ -1116,7 +1144,7 @@ class getid3_lib
1116
}
1117
1118
1119
- static function RGADgainString($namecode, $originatorcode, $replaygain) {
1120
if ($replaygain < 0) {
1121
$signbit = '1';
1122
} else {
@@ -1131,12 +1159,12 @@ class getid3_lib
1131
return $gainstring;
1132
}
1133
1134
- static function RGADamplitude2dB($amplitude) {
1135
return 20 * log10($amplitude);
1136
}
1137
1138
1139
- static function GetDataImageSize($imgData, &$imageinfo) {
1140
static $tempdir = '';
1141
if (empty($tempdir)) {
1142
// yes this is ugly, feel free to suggest a better way
@@ -1150,14 +1178,24 @@ class getid3_lib
1150
if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) {
1151
fwrite($tmp, $imgData);
1152
fclose($tmp);
1153
- $GetDataImageSize = @GetImageSize($tempfilename, $imageinfo);
1154
}
1155
unlink($tempfilename);
1156
}
1157
return $GetDataImageSize;
1158
}
1159
1160
- static function ImageTypesLookup($imagetypeid) {
1161
static $ImageTypesLookup = array();
1162
if (empty($ImageTypesLookup)) {
1163
$ImageTypesLookup[1] = 'gif';
@@ -1178,7 +1216,7 @@ class getid3_lib
1178
return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
1179
}
1180
1181
- static function CopyTagsToComments(&$ThisFileInfo) {
1182
1183
// Copy all entries from ['tags'] into common ['comments']
1184
if (!empty($ThisFileInfo['tags'])) {
@@ -1206,16 +1244,21 @@ class getid3_lib
1206
$newvaluelength = strlen(trim($value));
1207
foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
1208
$oldvaluelength = strlen(trim($existingvalue));
1209
- if (($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
1210
$ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
1211
- break 2;
1212
}
1213
}
1214
1215
}
1216
if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) {
1217
$value = (is_string($value) ? trim($value) : $value);
1218
- $ThisFileInfo['comments'][$tagname][] = $value;
1219
}
1220
}
1221
}
@@ -1223,26 +1266,29 @@ class getid3_lib
1223
}
1224
1225
// Copy to ['comments_html']
1226
- foreach ($ThisFileInfo['comments'] as $field => $values) {
1227
- if ($field == 'picture') {
1228
- // pictures can take up a lot of space, and we don't need multiple copies of them
1229
- // let there be a single copy in [comments][picture], and not elsewhere
1230
- continue;
1231
- }
1232
- foreach ($values as $index => $value) {
1233
- if (is_array($value)) {
1234
- $ThisFileInfo['comments_html'][$field][$index] = $value;
1235
- } else {
1236
- $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', getid3_lib::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
1237
}
1238
}
1239
}
1240
}
1241
return true;
1242
}
1243
1244
1245
- static function EmbeddedLookup($key, $begin, $end, $file, $name) {
1246
1247
// Cached
1248
static $cache;
@@ -1288,7 +1334,7 @@ class getid3_lib
1288
return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : '');
1289
}
1290
1291
- static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) {
1292
global $GETID3_ERRORARRAY;
1293
1294
if (file_exists($filename)) {
@@ -1312,6 +1358,40 @@ class getid3_lib
1312
return trim($string, "\x00");
1313
}
1314
1315
- }
1316
1317
- ?>
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
+ // also https://github.com/JamesHeinrich/getID3 //
7
/////////////////////////////////////////////////////////////////
8
// //
9
// getid3.lib.php - part of getID3() //
15
class getid3_lib
16
{
17
18
+ public static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') {
19
$returnstring = '';
20
for ($i = 0; $i < strlen($string); $i++) {
21
if ($hex) {
22
$returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
23
} else {
24
+ $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '¤');
25
}
26
if ($spaces) {
27
$returnstring .= ' ';
36
return $returnstring;
37
}
38
39
+ public static function trunc($floatnumber) {
40
// truncates a floating-point number at the decimal point
41
// returns int (if possible, otherwise float)
42
if ($floatnumber >= 1) {
46
} else {
47
$truncatednumber = 0;
48
}
49
+ if (self::intValueSupported($truncatednumber)) {
50
$truncatednumber = (int) $truncatednumber;
51
}
52
return $truncatednumber;
53
}
54
55
56
+ public static function safe_inc(&$variable, $increment=1) {
57
if (isset($variable)) {
58
$variable += $increment;
59
} else {
62
return true;
63
}
64
65
+ public static function CastAsInt($floatnum) {
66
// convert to float if not already
67
$floatnum = (float) $floatnum;
68
69
// convert a float to type int, only if possible
70
+ if (self::trunc($floatnum) == $floatnum) {
71
// it's not floating point
72
+ if (self::intValueSupported($floatnum)) {
73
// it's within int range
74
$floatnum = (int) $floatnum;
75
}
93
return false;
94
}
95
96
+ public static function DecimalizeFraction($fraction) {
97
list($numerator, $denominator) = explode('/', $fraction);
98
return $numerator / ($denominator ? $denominator : 1);
99
}
100
101
102
+ public static function DecimalBinary2Float($binarynumerator) {
103
+ $numerator = self::Bin2Dec($binarynumerator);
104
+ $denominator = self::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator)));
105
return ($numerator / $denominator);
106
}
107
108
109
+ public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
110
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
111
if (strpos($binarypointnumber, '.') === false) {
112
$binarypointnumber = '0.'.$binarypointnumber;
130
}
131
132
133
+ public static function Float2BinaryDecimal($floatvalue) {
134
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
135
$maxbits = 128; // to how many bits of precision should the calculations be taken?
136
+ $intpart = self::trunc($floatvalue);
137
$floatpart = abs($floatvalue - $intpart);
138
$pointbitstring = '';
139
while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) {
140
$floatpart *= 2;
141
+ $pointbitstring .= (string) self::trunc($floatpart);
142
+ $floatpart -= self::trunc($floatpart);
143
}
144
$binarypointnumber = decbin($intpart).'.'.$pointbitstring;
145
return $binarypointnumber;
146
}
147
148
149
+ public static function Float2String($floatvalue, $bits) {
150
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
151
switch ($bits) {
152
case 32:
168
} else {
169
$signbit = '1';
170
}
171
+ $normalizedbinary = self::NormalizeBinaryPoint(self::Float2BinaryDecimal($floatvalue), $fractionbits);
172
$biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent
173
$exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT);
174
$fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT);
175
176
+ return self::BigEndian2String(self::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false);
177
}
178
179
180
+ public static function LittleEndian2Float($byteword) {
181
+ return self::BigEndian2Float(strrev($byteword));
182
}
183
184
185
+ public static function BigEndian2Float($byteword) {
186
// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
187
// http://www.psc.edu/general/software/packages/ieee/ieee.html
188
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
189
190
+ $bitword = self::BigEndian2Bin($byteword);
191
if (!$bitword) {
192
return 0;
193
}
210
$exponentstring = substr($bitword, 1, 15);
211
$isnormalized = intval($bitword{16});
212
$fractionstring = substr($bitword, 17, 63);
213
+ $exponent = pow(2, self::Bin2Dec($exponentstring) - 16383);
214
+ $fraction = $isnormalized + self::DecimalBinary2Float($fractionstring);
215
$floatvalue = $exponent * $fraction;
216
if ($signbit == '1') {
217
$floatvalue *= -1;
225
}
226
$exponentstring = substr($bitword, 1, $exponentbits);
227
$fractionstring = substr($bitword, $exponentbits + 1, $fractionbits);
228
+ $exponent = self::Bin2Dec($exponentstring);
229
+ $fraction = self::Bin2Dec($fractionstring);
230
231
if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
232
// Not a Number
246
$floatvalue = ($signbit ? 0 : -0);
247
} elseif (($exponent == 0) && ($fraction != 0)) {
248
// These are 'unnormalized' values
249
+ $floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * self::DecimalBinary2Float($fractionstring);
250
if ($signbit == '1') {
251
$floatvalue *= -1;
252
}
253
} elseif ($exponent != 0) {
254
+ $floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + self::DecimalBinary2Float($fractionstring));
255
if ($signbit == '1') {
256
$floatvalue *= -1;
257
}
260
}
261
262
263
+ public static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) {
264
$intvalue = 0;
265
$bytewordlen = strlen($byteword);
266
if ($bytewordlen == 0) {
282
$intvalue = 0 - ($intvalue & ($signMaskBit - 1));
283
}
284
} else {
285
+ throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits ('.strlen($byteword).') in self::BigEndian2Int()');
286
}
287
}
288
+ return self::CastAsInt($intvalue);
289
}
290
291
292
+ public static function LittleEndian2Int($byteword, $signed=false) {
293
+ return self::BigEndian2Int(strrev($byteword), false, $signed);
294
}
295
296
297
+ public static function BigEndian2Bin($byteword) {
298
$binvalue = '';
299
$bytewordlen = strlen($byteword);
300
for ($i = 0; $i < $bytewordlen; $i++) {
304
}
305
306
307
+ public static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) {
308
if ($number < 0) {
309
+ throw new Exception('ERROR: self::BigEndian2String() does not support negative numbers');
310
}
311
$maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF);
312
$intstring = '';
313
if ($signed) {
314
if ($minbytes > PHP_INT_SIZE) {
315
+ throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits in self::BigEndian2String()');
316
}
317
$number = $number & (0x80 << (8 * ($minbytes - 1)));
318
}
325
}
326
327
328
+ public static function Dec2Bin($number) {
329
while ($number >= 256) {
330
$bytes[] = (($number / 256) - (floor($number / 256))) * 256;
331
$number = floor($number / 256);
339
}
340
341
342
+ public static function Bin2Dec($binstring, $signed=false) {
343
$signmult = 1;
344
if ($signed) {
345
if ($binstring{0} == '1') {
351
for ($i = 0; $i < strlen($binstring); $i++) {
352
$decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i);
353
}
354
+ return self::CastAsInt($decvalue * $signmult);
355
}
356
357
358
+ public static function Bin2String($binstring) {
359
// return 'hi' for input of '0110100001101001'
360
$string = '';
361
$binstringreversed = strrev($binstring);
362
for ($i = 0; $i < strlen($binstringreversed); $i += 8) {
363
+ $string = chr(self::Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string;
364
}
365
return $string;
366
}
367
368
369
+ public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
370
$intstring = '';
371
while ($number > 0) {
372
if ($synchsafe) {
381
}
382
383
384
+ public static function array_merge_clobber($array1, $array2) {
385
+ // written by kcØhireability*com
386
// taken from http://www.php.net/manual/en/function.array-merge-recursive.php
387
if (!is_array($array1) || !is_array($array2)) {
388
return false;
390
$newarray = $array1;
391
foreach ($array2 as $key => $val) {
392
if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
393
+ $newarray[$key] = self::array_merge_clobber($newarray[$key], $val);
394
} else {
395
$newarray[$key] = $val;
396
}
399
}
400
401
402
+ public static function array_merge_noclobber($array1, $array2) {
403
if (!is_array($array1) || !is_array($array2)) {
404
return false;
405
}
406
$newarray = $array1;
407
foreach ($array2 as $key => $val) {
408
if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
409
+ $newarray[$key] = self::array_merge_noclobber($newarray[$key], $val);
410
} elseif (!isset($newarray[$key])) {
411
$newarray[$key] = $val;
412
}
414
return $newarray;
415
}
416
417
+ public static function flipped_array_merge_noclobber($array1, $array2) {
418
+ if (!is_array($array1) || !is_array($array2)) {
419
+ return false;
420
+ }
421
+ # naturally, this only works non-recursively
422
+ $newarray = array_flip($array1);
423
+ foreach (array_flip($array2) as $key => $val) {
424
+ if (!isset($newarray[$key])) {
425
+ $newarray[$key] = count($newarray);
426
+ }
427
+ }
428
+ return array_flip($newarray);
429
+ }
430
+
431
432
+ public static function ksort_recursive(&$theArray) {
433
ksort($theArray);
434
foreach ($theArray as $key => $value) {
435
if (is_array($value)) {
439
return true;
440
}
441
442
+ public static function fileextension($filename, $numextensions=1) {
443
if (strstr($filename, '.')) {
444
$reversedfilename = strrev($filename);
445
$offset = 0;
455
}
456
457
458
+ public static function PlaytimeString($seconds) {
459
$sign = (($seconds < 0) ? '-' : '');
460
+ $seconds = round(abs($seconds));
461
+ $H = (int) floor( $seconds / 3600);
462
+ $M = (int) floor(($seconds - (3600 * $H) ) / 60);
463
+ $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
464
return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
465
}
466
467
468
+ public static function DateMac2Unix($macdate) {
469
// Macintosh timestamp: seconds since 00:00h January 1, 1904
470
// UNIX timestamp: seconds since 00:00h January 1, 1970
471
+ return self::CastAsInt($macdate - 2082844800);
472
}
473
474
475
+ public static function FixedPoint8_8($rawdata) {
476
+ return self::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (self::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8));
477
}
478
479
480
+ public static function FixedPoint16_16($rawdata) {
481
+ return self::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (self::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16));
482
}
483
484
485
+ public static function FixedPoint2_30($rawdata) {
486
+ $binarystring = self::BigEndian2Bin($rawdata);
487
+ return self::Bin2Dec(substr($binarystring, 0, 2)) + (float) (self::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30));
488
}
489
490
491
+ public static function CreateDeepArray($ArrayPath, $Separator, $Value) {
492
// assigns $Value to a nested array path:
493
+ // $foo = self::CreateDeepArray('/path/to/my', '/', 'file.txt')
494
// is the same as:
495
// $foo = array('path'=>array('to'=>'array('my'=>array('file.txt'))));
496
// or
497
// $foo['path']['to']['my'] = 'file.txt';
498
+ $ArrayPath = ltrim($ArrayPath, $Separator);
499
if (($pos = strpos($ArrayPath, $Separator)) !== false) {
500
+ $ReturnedArray[substr($ArrayPath, 0, $pos)] = self::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
501
} else {
502
$ReturnedArray[$ArrayPath] = $Value;
503
}
504
return $ReturnedArray;
505
}
506
507
+ public static function array_max($arraydata, $returnkey=false) {
508
$maxvalue = false;
509
$maxkey = false;
510
foreach ($arraydata as $key => $value) {
518
return ($returnkey ? $maxkey : $maxvalue);
519
}
520
521
+ public static function array_min($arraydata, $returnkey=false) {
522
$minvalue = false;
523
$minkey = false;
524
foreach ($arraydata as $key => $value) {
532
return ($returnkey ? $minkey : $minvalue);
533
}
534
535
+ public static function XML2array($XMLstring) {
536
+ if (function_exists('simplexml_load_string') && function_exists('libxml_disable_entity_loader')) {
537
+ // http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html
538
+ // https://core.trac.wordpress.org/changeset/29378
539
+ $loader = libxml_disable_entity_loader(true);
540
+ $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);
541
+ $return = self::SimpleXMLelement2array($XMLobject);
542
+ libxml_disable_entity_loader($loader);
543
+ return $return;
544
}
545
return false;
546
}
547
548
+ public static function SimpleXMLelement2array($XMLobject) {
549
if (!is_object($XMLobject) && !is_array($XMLobject)) {
550
return $XMLobject;
551
}
557
}
558
559
560
+ // Allan Hansen <ahØartemis*dk>
561
+ // self::md5_data() - returns md5sum for a file from startuing position to absolute end position
562
+ public static function hash_data($file, $offset, $end, $algorithm) {
563
static $tempdir = '';
564
+ if (!self::intValueSupported($end)) {
565
return false;
566
}
567
switch ($algorithm) {
580
break;
581
582
default:
583
+ throw new Exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
584
break;
585
}
586
$size = $end - $offset;
597
foreach ($RequiredFiles as $required_file) {
598
if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
599
// helper apps not available - fall back to old method
600
+ break 2;
601
}
602
}
603
+ $commandline = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' '.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).' | ';
604
$commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
605
$commandline .= GETID3_HELPERAPPSDIR.$windows_call;
606
636
637
// copy parts of file
638
try {
639
+ self::CopyFileParts($file, $data_filename, $offset, $end - $offset);
640
$result = $hash_function($data_filename);
641
} catch (Exception $e) {
642
+ throw new Exception('self::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage());
643
}
644
unlink($data_filename);
645
return $result;
646
}
647
648
+ public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) {
649
+ if (!self::intValueSupported($offset + $length)) {
650
throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit');
651
}
652
if (is_readable($filename_source) && is_file($filename_source) && ($fp_src = fopen($filename_source, 'rb'))) {
653
if (($fp_dest = fopen($filename_dest, 'wb'))) {
654
+ if (fseek($fp_src, $offset) == 0) {
655
$byteslefttowrite = $length;
656
while (($byteslefttowrite > 0) && ($buffer = fread($fp_src, min($byteslefttowrite, getID3::FREAD_BUFFER_SIZE)))) {
657
$byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite);
672
return false;
673
}
674
675
+ public static function iconv_fallback_int_utf8($charval) {
676
if ($charval < 128) {
677
// 0bbbbbbb
678
$newcharstring = chr($charval);
696
}
697
698
// ISO-8859-1 => UTF-8
699
+ public static function iconv_fallback_iso88591_utf8($string, $bom=false) {
700
if (function_exists('utf8_encode')) {
701
return utf8_encode($string);
702
}
707
}
708
for ($i = 0; $i < strlen($string); $i++) {
709
$charval = ord($string{$i});
710
+ $newcharstring .= self::iconv_fallback_int_utf8($charval);
711
}
712
return $newcharstring;
713
}
714
715
// ISO-8859-1 => UTF-16BE
716
+ public static function iconv_fallback_iso88591_utf16be($string, $bom=false) {
717
$newcharstring = '';
718
if ($bom) {
719
$newcharstring .= "\xFE\xFF";
725
}
726
727
// ISO-8859-1 => UTF-16LE
728
+ public static function iconv_fallback_iso88591_utf16le($string, $bom=false) {
729
$newcharstring = '';
730
if ($bom) {
731
$newcharstring .= "\xFF\xFE";
737
}
738
739
// ISO-8859-1 => UTF-16LE (BOM)
740
+ public static function iconv_fallback_iso88591_utf16($string) {
741
+ return self::iconv_fallback_iso88591_utf16le($string, true);
742
}
743
744
// UTF-8 => ISO-8859-1
745
+ public static function iconv_fallback_utf8_iso88591($string) {
746
if (function_exists('utf8_decode')) {
747
return utf8_decode($string);
748
}
786
}
787
788
// UTF-8 => UTF-16BE
789
+ public static function iconv_fallback_utf8_utf16be($string, $bom=false) {
790
$newcharstring = '';
791
if ($bom) {
792
$newcharstring .= "\xFE\xFF";
822
$offset += 1;
823
}
824
if ($charval !== false) {
825
+ $newcharstring .= (($charval < 65536) ? self::BigEndian2String($charval, 2) : "\x00".'?');
826
}
827
}
828
return $newcharstring;
829
}
830
831
// UTF-8 => UTF-16LE
832
+ public static function iconv_fallback_utf8_utf16le($string, $bom=false) {
833
$newcharstring = '';
834
if ($bom) {
835
$newcharstring .= "\xFF\xFE";
865
$offset += 1;
866
}
867
if ($charval !== false) {
868
+ $newcharstring .= (($charval < 65536) ? self::LittleEndian2String($charval, 2) : '?'."\x00");
869
}
870
}
871
return $newcharstring;
872
}
873
874
// UTF-8 => UTF-16LE (BOM)
875
+ public static function iconv_fallback_utf8_utf16($string) {
876
+ return self::iconv_fallback_utf8_utf16le($string, true);
877
}
878
879
// UTF-16BE => UTF-8
880
+ public static function iconv_fallback_utf16be_utf8($string) {
881
if (substr($string, 0, 2) == "\xFE\xFF") {
882
// strip BOM
883
$string = substr($string, 2);
884
}
885
$newcharstring = '';
886
for ($i = 0; $i < strlen($string); $i += 2) {
887
+ $charval = self::BigEndian2Int(substr($string, $i, 2));
888
+ $newcharstring .= self::iconv_fallback_int_utf8($charval);
889
}
890
return $newcharstring;
891
}
892
893
// UTF-16LE => UTF-8
894
+ public static function iconv_fallback_utf16le_utf8($string) {
895
if (substr($string, 0, 2) == "\xFF\xFE") {
896
// strip BOM
897
$string = substr($string, 2);
898
}
899
$newcharstring = '';
900
for ($i = 0; $i < strlen($string); $i += 2) {
901
+ $charval = self::LittleEndian2Int(substr($string, $i, 2));
902
+ $newcharstring .= self::iconv_fallback_int_utf8($charval);
903
}
904
return $newcharstring;
905
}
906
907
// UTF-16BE => ISO-8859-1
908
+ public static function iconv_fallback_utf16be_iso88591($string) {
909
if (substr($string, 0, 2) == "\xFE\xFF") {
910
// strip BOM
911
$string = substr($string, 2);
912
}
913
$newcharstring = '';
914
for ($i = 0; $i < strlen($string); $i += 2) {
915
+ $charval = self::BigEndian2Int(substr($string, $i, 2));
916
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
917
}
918
return $newcharstring;
919
}
920
921
// UTF-16LE => ISO-8859-1
922
+ public static function iconv_fallback_utf16le_iso88591($string) {
923
if (substr($string, 0, 2) == "\xFF\xFE") {
924
// strip BOM
925
$string = substr($string, 2);
926
}
927
$newcharstring = '';
928
for ($i = 0; $i < strlen($string); $i += 2) {
929
+ $charval = self::LittleEndian2Int(substr($string, $i, 2));
930
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
931
}
932
return $newcharstring;
933
}
934
935
// UTF-16 (BOM) => ISO-8859-1
936
+ public static function iconv_fallback_utf16_iso88591($string) {
937
$bom = substr($string, 0, 2);
938
if ($bom == "\xFE\xFF") {
939
+ return self::iconv_fallback_utf16be_iso88591(substr($string, 2));
940
} elseif ($bom == "\xFF\xFE") {
941
+ return self::iconv_fallback_utf16le_iso88591(substr($string, 2));
942
}
943
return $string;
944
}
945
946
// UTF-16 (BOM) => UTF-8
947
+ public static function iconv_fallback_utf16_utf8($string) {
948
$bom = substr($string, 0, 2);
949
if ($bom == "\xFE\xFF") {
950
+ return self::iconv_fallback_utf16be_utf8(substr($string, 2));
951
} elseif ($bom == "\xFF\xFE") {
952
+ return self::iconv_fallback_utf16le_utf8(substr($string, 2));
953
}
954
return $string;
955
}
956
957
+ public static function iconv_fallback($in_charset, $out_charset, $string) {
958
959
if ($in_charset == $out_charset) {
960
return $string;
997
}
998
if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
999
$ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
1000
+ return self::$ConversionFunction($string);
1001
}
1002
throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
1003
}
1004
1005
+ public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') {
1006
+ if (is_string($data)) {
1007
+ return self::MultiByteCharString2HTML($data, $charset);
1008
+ } elseif (is_array($data)) {
1009
+ $return_data = array();
1010
+ foreach ($data as $key => $value) {
1011
+ $return_data[$key] = self::recursiveMultiByteCharString2HTML($value, $charset);
1012
+ }
1013
+ return $return_data;
1014
+ }
1015
+ // integer, float, objects, resources, etc
1016
+ return $data;
1017
+ }
1018
1019
+ public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') {
1020
$string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string
1021
$HTMLstring = '';
1022
1081
1082
case 'UTF-16LE':
1083
for ($i = 0; $i < strlen($string); $i += 2) {
1084
+ $charval = self::LittleEndian2Int(substr($string, $i, 2));
1085
if (($charval >= 32) && ($charval <= 127)) {
1086
$HTMLstring .= chr($charval);
1087
} else {
1092
1093
case 'UTF-16BE':
1094
for ($i = 0; $i < strlen($string); $i += 2) {
1095
+ $charval = self::BigEndian2Int(substr($string, $i, 2));
1096
if (($charval >= 32) && ($charval <= 127)) {
1097
$HTMLstring .= chr($charval);
1098
} else {
1110
1111
1112
1113
+ public static function RGADnameLookup($namecode) {
1114
static $RGADname = array();
1115
if (empty($RGADname)) {
1116
$RGADname[0] = 'not set';
1122
}
1123
1124
1125
+ public static function RGADoriginatorLookup($originatorcode) {
1126
static $RGADoriginator = array();
1127
if (empty($RGADoriginator)) {
1128
$RGADoriginator[0] = 'unspecified';
1135
}
1136
1137
1138
+ public static function RGADadjustmentLookup($rawadjustment, $signbit) {
1139
$adjustment = $rawadjustment / 10;
1140
if ($signbit == 1) {
1141
$adjustment *= -1;
1144
}
1145
1146
1147
+ public static function RGADgainString($namecode, $originatorcode, $replaygain) {
1148
if ($replaygain < 0) {
1149
$signbit = '1';
1150
} else {
1159
return $gainstring;
1160
}
1161
1162
+ public static function RGADamplitude2dB($amplitude) {
1163
return 20 * log10($amplitude);
1164
}
1165
1166
1167
+ public static function GetDataImageSize($imgData, &$imageinfo=array()) {
1168
static $tempdir = '';
1169
if (empty($tempdir)) {
1170
// yes this is ugly, feel free to suggest a better way
1178
if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) {
1179
fwrite($tmp, $imgData);
1180
fclose($tmp);
1181
+ $GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
1182
+ if (($GetDataImageSize === false) || !isset($GetDataImageSize[0]) || !isset($GetDataImageSize[1])) {
1183
+ return false;
1184
+ }
1185
+ $GetDataImageSize['height'] = $GetDataImageSize[0];
1186
+ $GetDataImageSize['width'] = $GetDataImageSize[1];
1187
}
1188
unlink($tempfilename);
1189
}
1190
return $GetDataImageSize;
1191
}
1192
1193
+ public static function ImageExtFromMime($mime_type) {
1194
+ // temporary way, works OK for now, but should be reworked in the future
1195
+ return str_replace(array('image/', 'x-', 'jpeg'), array('', '', 'jpg'), $mime_type);
1196
+ }
1197
+
1198
+ public static function ImageTypesLookup($imagetypeid) {
1199
static $ImageTypesLookup = array();
1200
if (empty($ImageTypesLookup)) {
1201
$ImageTypesLookup[1] = 'gif';
1216
return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
1217
}
1218
1219
+ public static function CopyTagsToComments(&$ThisFileInfo) {
1220
1221
// Copy all entries from ['tags'] into common ['comments']
1222
if (!empty($ThisFileInfo['tags'])) {
1244
$newvaluelength = strlen(trim($value));
1245
foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
1246
$oldvaluelength = strlen(trim($existingvalue));
1247
+ if ((strlen($existingvalue) > 10) && ($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
1248
$ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
1249
+ //break 2;
1250
+ break;
1251
}
1252
}
1253
1254
}
1255
if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) {
1256
$value = (is_string($value) ? trim($value) : $value);
1257
+ if (!is_numeric($key)) {
1258
+ $ThisFileInfo['comments'][$tagname][$key] = $value;
1259
+ } else {
1260
+ $ThisFileInfo['comments'][$tagname][] = $value;
1261
+ }
1262
}
1263
}
1264
}
1266
}
1267
1268
// Copy to ['comments_html']
1269
+ if (!empty($ThisFileInfo['comments'])) {
1270
+ foreach ($ThisFileInfo['comments'] as $field => $values) {
1271
+ if ($field == 'picture') {
1272
+ // pictures can take up a lot of space, and we don't need multiple copies of them
1273
+ // let there be a single copy in [comments][picture], and not elsewhere
1274
+ continue;
1275
+ }
1276
+ foreach ($values as $index => $value) {
1277
+ if (is_array($value)) {
1278
+ $ThisFileInfo['comments_html'][$field][$index] = $value;
1279
+ } else {
1280
+ $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', self::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
1281
+ }
1282
}
1283
}
1284
}
1285
+
1286
}
1287
return true;
1288
}
1289
1290
1291
+ public static function EmbeddedLookup($key, $begin, $end, $file, $name) {
1292
1293
// Cached
1294
static $cache;
1334
return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : '');
1335
}
1336
1337
+ public static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) {
1338
global $GETID3_ERRORARRAY;
1339
1340
if (file_exists($filename)) {
1358
return trim($string, "\x00");
1359
}
1360
1361
+ public static function getFileSizeSyscall($path) {
1362
+ $filesize = false;
1363
+
1364
+ if (GETID3_OS_ISWINDOWS) {
1365
+ if (class_exists('COM')) { // From PHP 5.3.15 and 5.4.5, COM and DOTNET is no longer built into the php core.you have to add COM support in php.ini:
1366
+ $filesystem = new COM('Scripting.FileSystemObject');
1367
+ $file = $filesystem->GetFile($path);
1368
+ $filesize = $file->Size();
1369
+ unset($filesystem, $file);
1370
+ } else {
1371
+ $commandline = 'for %I in ('.escapeshellarg($path).') do @echo %~zI';
1372
+ }
1373
+ } else {
1374
+ $commandline = 'ls -l '.escapeshellarg($path).' | awk \'{print $5}\'';
1375
+ }
1376
+ if (isset($commandline)) {
1377
+ $output = trim(`$commandline`);
1378
+ if (ctype_digit($output)) {
1379
+ $filesize = (float) $output;
1380
+ }
1381
+ }
1382
+ return $filesize;
1383
+ }
1384
1385
+
1386
+ /**
1387
+ * Workaround for Bug #37268 (https://bugs.php.net/bug.php?id=37268)
1388
+ * @param string $path A path.
1389
+ * @param string $suffix If the name component ends in suffix this will also be cut off.
1390
+ * @return string
1391
+ */
1392
+ public static function mb_basename($path, $suffix = null) {
1393
+ $splited = preg_split('#/#', rtrim($path, '/ '));
1394
+ return substr(basename('X'.$splited[count($splited) - 1], $suffix), 1);
1395
+ }
1396
+
1397
+ }
lib/getid3/getid3.php CHANGED
@@ -1,674 +1,700 @@
1
<?php
2
-
3
/////////////////////////////////////////////////////////////////
4
/// getID3() by James Heinrich <info@getid3.org> //
5
// available at http://getid3.sourceforge.net //
6
// or http://www.getid3.org //
7
/////////////////////////////////////////////////////////////////
8
// //
9
// Please see readme.txt for more information //
10
// ///
11
/////////////////////////////////////////////////////////////////
12
- // attempt to define temp dir as something flexible but reliable
13
14
if ( class_exists ( "getID3" ) ) {
15
- return;
16
}
17
- if ( class_exists ( "getid3_exception" ) ) {
18
- return;
19
}
20
- $temp_dir = ini_get ( 'upload_tmp_dir' );
21
- if ( $temp_dir && ( ! is_dir ( $temp_dir ) || ! is_readable ( $temp_dir )) ) {
22
- $temp_dir = '';
23
}
24
- if ( ! $temp_dir && function_exists ( 'sys_get_temp_dir' ) ) {
25
- // PHP v5.2.1+
26
- // sys_get_temp_dir() may give inaccessible temp dir, e.g. with open_basedir on virtual hosts
27
- $temp_dir = sys_get_temp_dir ();
28
}
29
- $temp_dir = realpath ( $temp_dir );
30
- $open_basedir = ini_get ( 'open_basedir' );
31
- if ( $open_basedir ) {
32
- // e.g. "/var/www/vhosts/getid3.org/httpdocs/:/tmp/"
33
- $temp_dir = str_replace ( array( '/', '\\' ), DIRECTORY_SEPARATOR, $temp_dir );
34
- $open_basedir = str_replace ( array( '/', '\\' ), DIRECTORY_SEPARATOR, $open_basedir );
35
- if ( substr ( $temp_dir, -1, 1 ) != DIRECTORY_SEPARATOR ) {
36
- $temp_dir .= DIRECTORY_SEPARATOR;
37
- }
38
- $found_valid_tempdir = false;
39
- $open_basedirs = explode ( ':', $open_basedir );
40
- foreach ( $open_basedirs as $basedir ) {
41
- if ( substr ( $basedir, -1, 1 ) != DIRECTORY_SEPARATOR ) {