From 9014acf085ebcb21245fe1d585477c75870249bc Mon Sep 17 00:00:00 2001 From: willtp87 Date: Mon, 30 Jun 2014 17:28:54 +0000 Subject: [PATCH 01/10] better xsl handling --- includes/mime_detect.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc index 03ece01f..8aae5393 100644 --- a/includes/mime_detect.inc +++ b/includes/mime_detect.inc @@ -132,7 +132,8 @@ class MimeDetect { 'wbxml' => 'application/vnd.wap.wbxml', 'xht' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml', - 'xsl' => 'text/xml', + 'xsl' => 'text/xsl', + 'xslt' => 'text/xsl', 'xml' => 'text/xml', 'csv' => 'text/csv', 'tsv' => 'text/tab-separated-values', From 9ea9eeed6001f7423b5f489acaac97c7627f5dd6 Mon Sep 17 00:00:00 2001 From: willtp87 Date: Mon, 30 Jun 2014 18:45:34 +0000 Subject: [PATCH 02/10] datastream replacing mimes more accurate --- includes/datastream.version.inc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index f245830c..515094bd 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -280,17 +280,16 @@ function islandora_datastream_version_replace_form($form, &$form_state, Abstract $form_state['object_id'] = $object->id; $form_state['dsid'] = $datastream->id; $form_state['object'] = $object; - $extensions = islandora_get_object_extensions($object); + $datastream_mime_map = islandora_get_object_extensions($object); $mime_detect = new MimeDetect(); $ext = array(); - if (isset($extensions[$datastream->id])) { - foreach ($extensions[$datastream->id]['mime'] as $key => $value) { - $str = $mime_detect->getExtension($value); - array_push($ext, $str); + if (isset($datastream_mime_map[$datastream->id])) { + foreach ($datastream_mime_map[$datastream->id]['mime'] as $key => $value) { + $extensions = $mime_detect->getValidExtensions($value); + $ext = array_merge($ext, $extensions); } } - $comma = count($ext) > 1 ? "," : ""; - $ext = array(implode($comma, $ext)); + $upload_size = min((int) ini_get('post_max_size'), (int) ini_get('upload_max_filesize')); return array( 'dsid_fieldset' => array( From 2a127bb1533eb7fb48151667776407607bc49018 Mon Sep 17 00:00:00 2001 From: nruest Date: Wed, 2 Jul 2014 23:08:38 -0400 Subject: [PATCH 03/10] I suppose we should have warc in here if we have a web archive solution pack. --- includes/mime_detect.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc index 8aae5393..74b87fd6 100644 --- a/includes/mime_detect.inc +++ b/includes/mime_detect.inc @@ -225,6 +225,8 @@ class MimeDetect { "zip" => "application/x-zip", // others: 'bin' => 'application/octet-stream', + // Web Archives: + "warc" => "application/warc", ); protected $protectedFileExtensions; protected $extensionExceptions = array( From 022842a0a04271676cd69df2e8a631dbb830e12b Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 3 Jul 2014 17:21:24 +0000 Subject: [PATCH 04/10] Move hooks calls a little higher. Where they were in the API, modifications triggering other modifications were causing old data to be used, so the second (and later) modifications would fail due to "locking"... We now allow modifications to complete to the point where they update the lastModifiedDate on instances of Tuque objects before invoking our hooks. --- includes/tuque_wrapper.inc | 92 +++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 573d7c62..33881193 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -173,6 +173,30 @@ class IslandoraFedoraObject extends FedoraObject { throw $e; } } + + /** + * Inherits. + * + * Calls parent and invokes object modified and deleted(/purged) hooks. + * + * @see FedoraObject::modifyObject() + */ + protected function modifyObject($params) { + try { + parent::modifyObject($params); + islandora_invoke_object_hooks(ISLANDORA_OBJECT_MODIFIED_HOOK, $this->models, $this); + if ($this->state == 'D') { + islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $this->models, $this->id); + } + } + catch (Exception $e) { + watchdog('islandora', 'Failed to modify object: @pid
code: @code
message: @msg', array( + '@pid' => $this->id, + '@code' => $e->getCode(), + '@msg' => $e->getMessage()), WATCHDOG_ERROR); + throw $e; + } + } } class IslandoraRepositoryConnection extends RepositoryConnection {} @@ -219,25 +243,10 @@ class IslandoraFedoraApiM extends FedoraApiM { if (isset($params['lastModifiedDate'])) { $params['lastModifiedDate'] = (string) $object[$dsid]->createdDate; } - try { - if ($context['block']) { - throw new Exception('Modify Datastream was blocked.'); - } - $ret = parent::modifyDatastream($pid, $dsid, $params); - islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $object->models, $dsid, $object, $datastream); - if (isset($params['dsState']) && $params['dsState'] == 'D') { - islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $object->models, $dsid, $object, $dsid); - } - return $ret; - } - catch (Exception $e) { - watchdog('islandora', 'Failed to modify datastream @dsid from @pid
code: @code
message: @msg', array( - '@pid' => $pid, - '@dsid' => $dsid, - '@code' => $e->getCode(), - '@msg' => $e->getMessage()), WATCHDOG_ERROR); - throw $e; + if ($context['block']) { + throw new Exception('Modify Datastream was blocked.'); } + return parent::modifyDatastream($pid, $dsid, $params); } /** @@ -254,24 +263,10 @@ class IslandoraFedoraApiM extends FedoraApiM { ); islandora_alter_object($object, $context); $params = $context['params']; - try { - if ($context['block']) { - throw new Exception('Modify Object was blocked.'); - } - $ret = parent::modifyObject($pid, $params); - islandora_invoke_object_hooks(ISLANDORA_OBJECT_MODIFIED_HOOK, $object->models, $object); - if (isset($params['state']) && $params['state'] == 'D') { - islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $object->models, $object->id); - } - return $ret; - } - catch (Exception $e) { - watchdog('islandora', 'Failed to modify object: @pid
code: @code
message: @msg', array( - '@pid' => $pid, - '@code' => $e->getCode(), - '@msg' => $e->getMessage()), WATCHDOG_ERROR); - throw $e; + if ($context['block']) { + throw new Exception('Modify Object was blocked.'); } + return parent::modifyObject($pid, $params); } /** @@ -377,6 +372,33 @@ class IslandoraNewFedoraDatastream extends NewFedoraDatastream { class IslandoraFedoraDatastream extends FedoraDatastream { protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; + + /** + * Inherits. + * + * Calls parent and invokes modified and purged hooks. + * + * @see FedoraDatastream::modifyDatastream() + */ + protected function modifyDatastream(array $args) { + try { + parent::modifyDatastream($args); + // XXX: Reload datastream from parent. + $datastream = $this->parent[$this->id]; + islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $this->parent->models, $this->id, $this->parent, $datastream); + if ($datastream->state == 'D') { + islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $this->parent->models, $this->id, $this->parent, $this->id); + } + } + catch (Exception $e) { + watchdog('islandora', 'Failed to modify datastream @dsid from @pid
code: @code
message: @msg', array( + '@pid' => $this->parent->id, + '@dsid' => $this->id, + '@code' => $e->getCode(), + '@msg' => $e->getMessage()), WATCHDOG_ERROR); + throw $e; + } + } } class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion { From 2712214b81e3a9eb15163cb7a7b0ee0329eb61a3 Mon Sep 17 00:00:00 2001 From: vagrant Date: Sun, 6 Jul 2014 19:10:04 +0000 Subject: [PATCH 05/10] Removing deprecated function islandor_get_comp_ds_mappings. --- includes/utilities.inc | 48 ------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index 050921cc..d0fffa94 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -649,54 +649,6 @@ function islandora_system_settings_form_default_value($name, $default_value, arr return isset($form_state['values'][$name]) ? $form_state['values'][$name] : variable_get($name, $default_value); } -/** - * Returns basic information about DS-COMPOSITE-MODEL. - * - * @deprecated - * The pre-existing--and more flexible-- - * islandora_get_datastreams_requirements_from_content_model() should be - * preferred, as it addresses the case where a stream can be allowed to have - * one of a set of mimetypes (this functions appears to only return the last - * declared mimetype for a given datastream). - * - * @param string $pid - * The PID of content model containing DS_COMP stream. - * - * @return array - * An associative array mapping datastream IDs to an associative array - * representing the parsed DS-COMPOSITE-MODEL of the form: - * - DSID: A string containing the datastream ID. - * - "mimetype": A string containing the last mimetype declared for the - * given datastream ID. - * - "optional": An optional boolean indicating that the given datastream - * is optional. - */ -function islandora_get_comp_ds_mappings($pid) { - $message = islandora_deprecated('7.x-1.2', t('Refactor to use the more flexible islandora_get_datastreams_requirements_from_content_model().')); - trigger_error(filter_xss($message), E_USER_DEPRECATED); - - $cm_object = islandora_object_load($pid); - if (!isset($cm_object) || !isset($cm_object['DS-COMPOSITE-MODEL'])) { - return FALSE; - } - $datastream = $cm_object['DS-COMPOSITE-MODEL']; - $ds_comp_stream = $datastream->content; - $sxml = new SimpleXMLElement($ds_comp_stream); - $mappings = array(); - foreach ($sxml->dsTypeModel as $ds) { - $dsid = (string) $ds['ID']; - $optional = (string) $ds['optional']; - foreach ($ds->form as $form) { - $mime = (string) $form['MIME']; - if ($optional) { - $mappings[$dsid]['optional'] = $optional; - } - $mappings[$dsid]['mimetype'] = $mime; - } - } - return $mappings; -} - /** * Checks that the given/current account has all the given permissions. * From 29978b7a1ef3cbed8e63a0479b8bd1e556a3edfe Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 8 Jul 2014 20:39:51 +0000 Subject: [PATCH 06/10] Resolve issue with recursing. Curse you, PHP! --- includes/tuque_wrapper.inc | 76 +++++++++++++++++++++++++++++-- tests/hooks.test | 4 ++ tests/islandora_hooks_test.module | 8 ++++ 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 33881193..348ac60a 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -144,6 +144,41 @@ class IslandoraFedoraObject extends FedoraObject { protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; + /** + * Magical magic, to allow recursive modifications. + * + * So... Magic functions in PHP are not re-entrant... Meaning that if you + * have something which tries to call __set on an object anywhere later in + * the callstack after it has already been called, it will not call the + * magic method again; instead, it will set the property on the object + * proper. Here, we detect the property being set on the object proper, and + * restore the magic functionality as long as it keeps getting set... + * + * Not necessary to try to account for this in Tuque proper, as Tuque itself + * does not have a mechanism to trigger modifications resulting from other + * modifications. + * + * @param string $name + * The name of the property being set. + * @param mixed $value + * The value to which the property should be set. + */ + public function __set($name, $value) { + parent::__set($name, $value); + + // XXX: Due to the structure of the code, we cannot use property_exists() + // (because many of the properties are declared in the class, and the magic + // triggers due them being NULLed), nor can we use isset() (because it is + // implemented as another magic function...). + $vars = get_object_vars($this); + while (isset($vars[$name])) { + $new_value = $this->$name; + unset($this->$name); + parent::__set($name, $new_value); + $vars = get_object_vars($this); + } + } + /** * Ingest the given datastream. * @@ -373,6 +408,41 @@ class IslandoraFedoraDatastream extends FedoraDatastream { protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; + /** + * Magical magic, to allow recursive modifications. + * + * So... Magic functions in PHP are not re-entrant... Meaning that if you + * have something which tries to call __set on an object anywhere later in + * the callstack after it has already been called, it will not call the + * magic method again; instead, it will set the property on the object + * proper. Here, we detect the property being set on the object proper, and + * restore the magic functionality as long as it keeps getting set... + * + * Not necessary to try to account for this in Tuque proper, as Tuque itself + * does not have a mechanism to trigger modifications resulting from other + * modifications. + * + * @param string $name + * The name of the property being set. + * @param mixed $value + * The value to which the property should be set. + */ + public function __set($name, $value) { + parent::__set($name, $value); + + // XXX: Due to the structure of the code, we cannot use property_exists() + // (because many of the properties are declared in the class, and the magic + // triggers due them being NULLed), nor can we use isset() (because it is + // implemented as another magic function...). + $vars = get_object_vars($this); + while (isset($vars[$name])) { + $new_value = $this->$name; + unset($this->$name); + parent::__set($name, $new_value); + $vars = get_object_vars($this); + } + } + /** * Inherits. * @@ -383,10 +453,8 @@ class IslandoraFedoraDatastream extends FedoraDatastream { protected function modifyDatastream(array $args) { try { parent::modifyDatastream($args); - // XXX: Reload datastream from parent. - $datastream = $this->parent[$this->id]; - islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $this->parent->models, $this->id, $this->parent, $datastream); - if ($datastream->state == 'D') { + islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $this->parent->models, $this->id, $this->parent, $this); + if ($this->state == 'D') { islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $this->parent->models, $this->id, $this->parent, $this->id); } } diff --git a/tests/hooks.test b/tests/hooks.test index d08c537b..b8846c52 100644 --- a/tests/hooks.test +++ b/tests/hooks.test @@ -109,9 +109,11 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->repository->ingestObject($object); $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; $_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; + $_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK] = 0; $object->label = "New Label!"; $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.'); + $this->assertEqual('New Label! + 3', $object->label, 'Re-entered ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.'); // Test blocking the modification. try { @@ -191,10 +193,12 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $ds = $object->constructDatastream('TEST'); $object->ingestDatastream($ds); $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; + $_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = 0; $_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; $ds->label = "New Label!"; $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.'); + $this->assertEqual('New Label! + 3', $ds->label, 'Re-entered ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.'); // Test blocking modifying. try { diff --git a/tests/islandora_hooks_test.module b/tests/islandora_hooks_test.module index a6b8a5b6..cceb4dbc 100644 --- a/tests/islandora_hooks_test.module +++ b/tests/islandora_hooks_test.module @@ -112,6 +112,10 @@ function islandora_hooks_test_islandora_object_ingested(AbstractObject $object) function islandora_hooks_test_islandora_object_modified(AbstractObject $object) { if ($object->id == 'test:testModifiedObjectHook') { $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE; + if ($_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK]++ < 3) { + $new_label = 'New Label! + ' . $_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK]; + $object->label = $new_label; + } } } @@ -139,6 +143,10 @@ function islandora_hooks_test_islandora_datastream_ingested(AbstractObject $obje function islandora_hooks_test_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) { if ($object->id == 'test:testModifiedDatastreamHook' && $datastream->id == "TEST") { $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE; + if ($_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK]++ < 3) { + $new_label = 'New Label! + ' . $_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK]; + $datastream->label = $new_label; + } } } From 6133b0973c082d7a4de1ca65a3b2e4d34cbf7cdb Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Wed, 9 Jul 2014 18:45:30 +0000 Subject: [PATCH 07/10] Magic to get around a core Drupal problem. --- includes/ingest.form.inc | 6 +++++- islandora.module | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index f7979063..b5a4740d 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -706,7 +706,11 @@ function islandora_ingest_form_ingest_button(array &$form_state) { $validate_callback = $form_id . '_validate'; $validate = function_exists($validate_callback) ? array($validate_callback) : NULL; $submit_callback = $form_id . '_submit'; - $submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_submit') : array('islandora_ingest_form_submit'); + $submit = function_exists($submit_callback) ? array( + $submit_callback, + 'islandora_ingest_form_pre_submit', + 'islandora_ingest_form_submit', + ) : array('islandora_ingest_form_pre_submit', 'islandora_ingest_form_submit'); return array( '#type' => 'submit', '#name' => 'ingest', diff --git a/islandora.module b/islandora.module index ff077212..2b678b78 100644 --- a/islandora.module +++ b/islandora.module @@ -1913,3 +1913,19 @@ function islandora_find_package($package_name) { } return $found && user_access('administer site configuration'); } + +/** + * Helper function for ingest steps and batches. + * + * When batches within batches are triggered within ingest steps + * the submit handler becomes out of scope. When it becomes time to execute the + * submit the function cannot be found and fails. This pre-submit is to + * get around this problem. + * + * @see https://www.drupal.org/node/2300367 + * + * @see https://www.drupal.org/node/1300928 + */ +function islandora_ingest_form_pre_submit($form, &$form_state) { + module_load_include('inc', 'islandora', 'includes/ingest.form'); +} From b7b4717e493240d4d4b2ec00318d6ba4ceaa9e14 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 10 Jul 2014 17:24:14 +0000 Subject: [PATCH 08/10] Unused var. --- islandora.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index a626e131..118f7f78 100644 --- a/islandora.module +++ b/islandora.module @@ -184,7 +184,6 @@ function islandora_menu() { ISLANDORA_INGEST, ), 2), ); - $islandora_path = drupal_get_path('module', 'islandora'); $items['islandora/object/%islandora_object/manage/overview'] = array( 'title' => 'Overview', 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -1922,7 +1921,7 @@ function islandora_ingest_form_pre_submit($form, &$form_state) { module_load_include('inc', 'islandora', 'includes/ingest.form'); } -/* +/* * Implements hook_menu_local_tasks_alter(). */ function islandora_menu_local_tasks_alter(&$data, $router_item, $root_path) { From d964ea204275b197138af1494c8aabad3a56c3a4 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 10 Jul 2014 18:06:59 +0000 Subject: [PATCH 09/10] Appease the Travis gods after a merge conflict fail. --- islandora.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index 118f7f78..f0bf796b 100644 --- a/islandora.module +++ b/islandora.module @@ -1921,7 +1921,7 @@ function islandora_ingest_form_pre_submit($form, &$form_state) { module_load_include('inc', 'islandora', 'includes/ingest.form'); } -/* +/** * Implements hook_menu_local_tasks_alter(). */ function islandora_menu_local_tasks_alter(&$data, $router_item, $root_path) { @@ -1954,4 +1954,3 @@ function islandora_menu_local_tasks_alter(&$data, $router_item, $root_path) { } } } - From 29b32e2c073aa8ddd38ef449e7e50b5843c9e0f8 Mon Sep 17 00:00:00 2001 From: willtp87 Date: Mon, 14 Jul 2014 13:32:32 +0000 Subject: [PATCH 10/10] not lying about units --- includes/utilities.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index d0fffa94..26633df5 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -30,16 +30,16 @@ function islandora_convert_bytes_to_human_readable($bytes, $precision = 2) { return $bytes . ' B'; } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) { - return round($bytes / $kilobyte, $precision) . ' KB'; + return round($bytes / $kilobyte, $precision) . ' KiB'; } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) { - return round($bytes / $megabyte, $precision) . ' MB'; + return round($bytes / $megabyte, $precision) . ' MiB'; } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) { - return round($bytes / $gigabyte, $precision) . ' GB'; + return round($bytes / $gigabyte, $precision) . ' GiB'; } elseif ($bytes >= $terabyte) { - return round($bytes / $terabyte, $precision) . ' TB'; + return round($bytes / $terabyte, $precision) . ' TiB'; } else { return $bytes . ' B';