|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace App\Helpers; |
| 4 | + |
| 5 | +use Illuminate\Support\Arr; |
| 6 | + |
| 7 | +class Publication |
| 8 | +{ |
| 9 | + /** @var array Default citation formats (keyed in order) */ |
| 10 | + const CITATION_FORMAT_AUTHOR_NAMES = [ |
| 11 | + 'APA' => ['last_name', 'comma', 'space', 'first_initial', 'space', 'middle_initial'], |
| 12 | + //'MLA' => ['last_name', 'comma', 'space', 'first_name'], // Example ONLY, for testing purposes |
| 13 | + //'Chicago' => ['first_name', 'space', 'last_name'], // Example ONLY, for testing purposes |
| 14 | + ]; |
| 15 | + |
| 16 | + /** @var array */ |
| 17 | + const REGEX_PATTERNS = [ |
| 18 | + 'APA' => "/^[A-Za-z][\s\w\p{L}\p{M}áéíóúüññÑ'-]+,\s[A-Z][\.\s\b][\s]?[A-Z]?[\.\s\b]?$/", |
| 19 | + 'last_name_initials' => "/^[A-Za-z][\s\w\p{L}\p{M}áéíóúüññÑ'-]+,?\s[A-Z]{1,2}\b$/", |
| 20 | + 'first_name_last_name' => "/^[A-Za-z][\s\w\p{L}\p{M}áéíóúüññÑ'-]+\s[A-Za-z][\s\w\p{L}\p{M}áéíóúüññÑ'-]+$/", |
| 21 | + // 'MLA' => "/^[\p{L}ñÑ'., -]+, [\p{Lu}ñÑ]\. ?[\p{Lu}ñÑ]?\.?$/", // Example ONLY, for testing purposes |
| 22 | + // 'Chicago' => "/^[\p{L}ñÑ'., -]+, [\p{Lu}ñÑ]\. ?[\p{Lu}ñÑ]?\.?$/", // Example ONLY, for testing purposes |
| 23 | + ]; |
| 24 | + |
| 25 | + /** @var array */ |
| 26 | + const SEPARATORS = [ |
| 27 | + 'comma' => ',', |
| 28 | + 'ellipsis' => '...', |
| 29 | + 'ampersand' => '&', |
| 30 | + 'space' => ' ', |
| 31 | + 'period' => '.', |
| 32 | + ]; |
| 33 | + |
| 34 | + public static function citationFormats(): array |
| 35 | + { |
| 36 | + return static::CITATION_FORMAT_AUTHOR_NAMES; |
| 37 | + } |
| 38 | + |
| 39 | + public static function citationFormatRegex(): array |
| 40 | + { |
| 41 | + return static::REGEX_PATTERNS; |
| 42 | + } |
| 43 | + |
| 44 | + public static function matchesRegexPattern($citation_format, $formatted_author_name) : int |
| 45 | + { |
| 46 | + return preg_match(static::citationFormatRegex()[$citation_format], $formatted_author_name); |
| 47 | + } |
| 48 | + |
| 49 | + public static function firstName(array $author_name_array, $pattern = null) : string |
| 50 | + { |
| 51 | + if (!is_null($pattern) && $pattern === 'last_name_initials') { |
| 52 | + return $author_name_array[1]; |
| 53 | + } |
| 54 | + return $author_name_array[0]; |
| 55 | + } |
| 56 | + |
| 57 | + public static function lastName(array $author_name_array, $pattern = null) : string |
| 58 | + { |
| 59 | + if (!is_null($pattern) && $pattern === 'last_name_initials') { |
| 60 | + return $author_name_array[0]; |
| 61 | + } |
| 62 | + |
| 63 | + if (count($author_name_array) == 3) { |
| 64 | + return $author_name_array[2]; |
| 65 | + } |
| 66 | + return Arr::last($author_name_array); |
| 67 | + } |
| 68 | + |
| 69 | + public static function middleName(array $author_name_array, $pattern = null) : string |
| 70 | + { |
| 71 | + if (!is_null($pattern) && $pattern === 'last_name_initials') { |
| 72 | + return strlen($author_name_array[1]) == 2 ? $author_name_array[1][1] : ''; |
| 73 | + } |
| 74 | + |
| 75 | + if (count($author_name_array) == 3) { |
| 76 | + return $author_name_array[1]; |
| 77 | + } |
| 78 | + return ''; |
| 79 | + } |
| 80 | + |
| 81 | + public static function initial(string $name) : string |
| 82 | + { |
| 83 | + return strlen($name) > 0 ? "{$name[0]}." : ''; |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + * Return a string with the authors names in APA format |
| 88 | + * @param array $authors |
| 89 | + * @return string |
| 90 | + */ |
| 91 | + public static function formatAuthorsApa(array $authors) : string |
| 92 | + { |
| 93 | + $authors = static::formatAuthorsNames($authors); |
| 94 | + |
| 95 | + $string_authors_names = ""; |
| 96 | + $greater_than_20 = false; |
| 97 | + $authors_count = count($authors); |
| 98 | + |
| 99 | + if ($authors_count > 1) { |
| 100 | + $last = $authors[$authors_count - 1]; |
| 101 | + |
| 102 | + if ($authors_count >= 20) { |
| 103 | + $greater_than_20 = true; |
| 104 | + array_splice($authors, 20); |
| 105 | + } |
| 106 | + else { |
| 107 | + array_splice($authors, $authors_count - 1); |
| 108 | + } |
| 109 | + |
| 110 | + foreach ($authors as $key => $author) { |
| 111 | + $string_authors_names = "{$string_authors_names} {$author['APA']}"; |
| 112 | + |
| 113 | + if ($key < count($authors) - 1) { |
| 114 | + $string_authors_names = $string_authors_names . static::SEPARATORS['comma'] . static::SEPARATORS['space']; |
| 115 | + } |
| 116 | + else { |
| 117 | + if ($greater_than_20) { |
| 118 | + $string_authors_names = $string_authors_names . static::SEPARATORS['space'] . static::SEPARATORS['ellipsis'] . static::SEPARATORS['space']; |
| 119 | + } |
| 120 | + else { |
| 121 | + $string_authors_names = $string_authors_names . static::SEPARATORS['space'] . static::SEPARATORS['ampersand'] . static::SEPARATORS['space']; |
| 122 | + } |
| 123 | + $string_authors_names = "{$string_authors_names} {$last['APA']}"; |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + else { |
| 128 | + $string_authors_names = $authors[0]['APA']; |
| 129 | + } |
| 130 | + |
| 131 | + return $string_authors_names; |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Return a string with the authors names in MLA format |
| 136 | + * @param array $authors |
| 137 | + */ |
| 138 | + public static function formatAuthorsMla(array $authors) |
| 139 | + { |
| 140 | + |
| 141 | + } |
| 142 | + |
| 143 | + /** |
| 144 | + * Return a string with the authors names in Chicago format |
| 145 | + * @param array $authors |
| 146 | + */ |
| 147 | + public static function formatAuthorsChicago(array $authors) |
| 148 | + { |
| 149 | + |
| 150 | + } |
| 151 | + |
| 152 | + /** |
| 153 | + * Receive an array of author names, assuming each name is either already formatted or in the form of First Name Middle initial. Last Name |
| 154 | + * Return an array formatted author name for each citation format |
| 155 | + * |
| 156 | + * @param $author_names |
| 157 | + * @return array |
| 158 | + */ |
| 159 | + public static function formatAuthorsNames(array $author_names): array |
| 160 | + { |
| 161 | + /** @var array<array> */ |
| 162 | + $formatted_author_names = []; |
| 163 | + |
| 164 | + foreach ($author_names as $author_name) { |
| 165 | + $raw_author_name = trim($author_name); |
| 166 | + |
| 167 | + foreach (array_keys(static::citationFormats()) as $key => $citation_format) { |
| 168 | + //If matches given citation format pattern |
| 169 | + if (static::matchesRegexPattern($citation_format, $raw_author_name)) { |
| 170 | + $formatted_author_name[$citation_format] = ucwords($raw_author_name); |
| 171 | + } //If matches last name first initial middle initial pattern |
| 172 | + elseif (static::matchesRegexPattern('last_name_initials', $raw_author_name)) { |
| 173 | + $formatted_author_name[$citation_format] = static::formatAuthorName($citation_format, $author_name, 'last_name_initials'); |
| 174 | + } |
| 175 | + else { //If matches any other pattern, it will use the first name last name pattern by default to format the name |
| 176 | + $formatted_author_name[$citation_format] = static::formatAuthorName($citation_format, $author_name); |
| 177 | + |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + $formatted_author_names[] = $formatted_author_name; |
| 182 | + } |
| 183 | + return $formatted_author_names; |
| 184 | + } |
| 185 | + |
| 186 | + /** |
| 187 | + * Format an author name according to a given citation format |
| 188 | + * |
| 189 | + * @param $citation_format |
| 190 | + * @param $full_name |
| 191 | + * @return string |
| 192 | + */ |
| 193 | + public static function formatAuthorName($citation_format, $full_name, $pattern = null) : string |
| 194 | + { |
| 195 | + $result = ''; |
| 196 | + $format_components = static::citationFormats()[$citation_format]; |
| 197 | + $full_name_array = explode(" ", $full_name); |
| 198 | + $first_name = static::firstName($full_name_array, $pattern); |
| 199 | + $middle_name = static::middleName($full_name_array, $pattern); |
| 200 | + $last_name = static::lastName($full_name_array, $pattern); |
| 201 | + $first_initial = static::initial($first_name); |
| 202 | + $middle_initial = static::initial($middle_name); |
| 203 | + $comma = static::SEPARATORS['comma']; |
| 204 | + $space = static::SEPARATORS['space']; |
| 205 | + |
| 206 | + foreach ($format_components as $key => $value) { |
| 207 | + $result = $result . array_values(compact($value))[0]; |
| 208 | + } |
| 209 | + |
| 210 | + return trim($result); |
| 211 | + } |
| 212 | + |
| 213 | +} |
0 commit comments