├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── docs └── index.html └── src ├── Ar ├── Strings.php ├── Tafkit.php ├── Tawkit.php └── data │ ├── strings │ ├── json │ │ ├── en_unique.json │ │ ├── english_letters.json │ │ ├── letters.json │ │ ├── map.json │ │ └── uniques.json │ └── loader.php │ ├── tafkit │ ├── json │ │ ├── extra.json │ │ ├── hundreds.json │ │ ├── levels.json │ │ ├── numbers.json │ │ ├── ones.json │ │ ├── order.json │ │ ├── spaced_ones.json │ │ ├── tens.json │ │ ├── trimed_tens.json │ │ ├── trimed_uniques.json │ │ ├── uniqes.json │ │ └── zero_to_20.json │ └── loader.php │ └── tawkit │ ├── json │ ├── days.json │ ├── hijri_months.json │ ├── months.json │ ├── relative.json │ ├── time.json │ ├── uniques.json │ └── units.json │ └── loader.php ├── Arabic.php ├── ArabicServiceProvider.php ├── Caller.php └── helpers.php /.gitignore: -------------------------------------------------------------------------------- 1 | /src/Ar/Grammar.php 2 | /src/Ar/data/grammar 3 | .phpunit.result.cache 4 | /tests 5 | /phpunit.xml 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `laravel-speaks-arabic` will be documented in this file 4 | ## 1.0.3 - 2021-05-10 5 | - bug fixes . 6 | - enhancing methods . 7 | - adding blade directives . 8 | 9 | ## 1.0.2 - 2021-03-27 10 | - enhancing package with new methods [fromHijri ,fromRelative ,countWords ,containsAr ,fromWords] . 11 | - bug fixes . 12 | - change methods default names [toWords ,toOrdinal ,toHijri ,fromHijri ,toRelative ,fromRelative , toSpelled] 13 | 14 | ## 1.0 - 2021-03-23 15 | - Initial release for the package -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ## لارافيل يتحدث العربي - Laravel Speaks Arabic 4 | 5 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/adnane/laravel-speaks-arabic.svg?style=flat-square)](https://packagist.org/packages/adnane/laravel-speaks-arabic) 6 | [![MIT Licensed](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/adnane/laravel-speaks-arabic.svg?style=flat-square)](https://packagist.org/packages/adnane/laravel-speaks-arabic) 8 | 9 | **حزمة خفيفة الوزن تسهل التعامل مع المفاهيم العربية في لارافيل، بإستخدام مجموعة من الفئات، الأساليب والتوابع لجعل لارافل يتحدث العربي! مفاهيم من مثل السلاسل النصية العربي والتواريخ الهجرية وغيرها** 10 | 11 | **مثال** 12 | 13 |
14 | 15 | ```php 16 | @toWords(12078437); 17 | // اثنا عشر مليون و ثمان و سبعون ألف و أربع مئة و سبع و ثلاثون 18 | ``` 19 | 20 |
21 | 22 | 23 | ## التثبيت 24 | 25 | 1. التثبيت عن طريق مدير الحزم composer 26 | 27 |
28 | 29 | ``` 30 | composer require adnane/laravel-speaks-arabic 31 | ``` 32 | 33 |
34 | 35 | 2. قم بإضافة مزود خدمة الحزمة الى مصفوفة providers في ملف `config\app.php` كالتالي: 36 | 37 |
38 | 39 | ```php 40 | 'providers' => [ 41 | Adnane\Arabic\ArabicServiceProvider::class, 42 | ] 43 | ``` 44 | 45 |
46 | 47 | ## كيفية الاستعمال 48 | - بعد التأكد من تثبيت الحزمة على نحو صحيح، سيمكنك تضمين الفئة الرئيسية ```Adnane\Arabic\Arabic``` واستعمال توابعها بشكل عادي 49 | 50 | > قم بتغيير ```method``` إلى التابع المراد كـ: ```Arabic::toWords(643646)``` أو كـ: ```arabic()->toWords(643646)``` 51 | 52 |
53 | 54 | ```php 55 | use Adnane\Arabic\Arabic; 56 | Arabic::method($params) 57 | 58 | // او مباشرة عن طريق الدالة المساعدة 59 | arabic()::method($params) 60 | ``` 61 | 62 |
63 | 64 | ## التوابع المتوفرة 65 | 66 | **1.التعامل مع الأعداد** 67 | 68 |
69 | 70 | ```php 71 | /** 72 | * اعادة كتابة الاعداد كتابة لفظية انطلاقا من كتابة رمزية 73 | * يسمى أيضا "تفقيط" 74 | * 75 | * @return string 76 | */ 77 | Arabic::toWords(int $integer) 78 | 79 | /** 80 | * اعادة كتابة الاعداد كتابة رمزية انطلاقا من كتابة لفظية 81 | * هو عكس العملية السابقة 82 | * 83 | * @return int 84 | */ 85 | Arabic::fromWords(string $str) 86 | 87 | /** 88 | * جلب العدد الترتيبي انطلاقا من كتابة رمزية لعدد ما 89 | * مثال: أول، ثان، ثالث 90 | * 91 | * @return string 92 | */ 93 | Arabic::toOrdinal(int $int) 94 | 95 | /** 96 | * اعادة كتابة الارقام الموجودة في سلسلة نصية ما 97 | * كأرقام هندية (۰ - ۱ - ۲ - ۳ - ٤ - ٥ - ٦ - ٧ - ۸ - ۹) 98 | * 99 | * @return string 100 | */ 101 | Arabic::toIndianNums(string $str) 102 | ``` 103 | 104 |
105 | 106 | **2.التعامل مع التواريخ والتواقيت** 107 | 108 |
109 | 110 | ```php 111 | /** 112 | * تحويل تاريخ مكتوب بالتقويم الميلادي 113 | * الى تاريخ مكتوب بالتقويم الهجري 114 | * مكتوبا بصيغة معينة 115 | * 116 | * (الصيغ المدعومة : f , s , n ) 117 | * @return string 118 | */ 119 | Arabic::toHijri(string $format = 'f' ,string $date) 120 | 121 | /** 122 | * تحويل تاريخ مكتوب بالتقوم الهجري 123 | * الى تاريخ مكتوب بالتقويم الميلادي 124 | * 125 | * @return string 126 | */ 127 | Arabic::fromHijri(string $date /*Y/m/d*/); 128 | 129 | /** 130 | * جلب فرق التوقيت بين وقتين او تاريخين. 131 | * تمرير المعامل details بالقيمة true 132 | * سيقوم باعادة فرق تفصيلي بين هاذين التوقيتين 133 | * 134 | * @return string 135 | */ 136 | Arabic::toRelative(string $date ,string $date2 = null ,boolean $detailed = false); 137 | 138 | /** 139 | * جلب توقيت ما انطلاقا من فرق مرفق 140 | * مثال: 141 | * Arabic::fromRelative('زد سنة') 142 | * @return string 143 | */ 144 | Arabic::fromRelative(string $relative); 145 | 146 | ``` 147 | 148 |
149 | 150 | **3. التعامل مع السلاسل النصية** 151 | 152 |
153 | 154 | ```php 155 | /** 156 | * ازالة التشكيل من سلسلة نصية ما 157 | * 158 | * @return string 159 | */ 160 | Arabic::removeHarakat(string $str) 161 | 162 | /** 163 | * اعادة كتابة سلسلة نصية ما مكتوبة باللغة الانجليزية 164 | * الى المرافق لها بلوحة مفاتيح عربية 165 | * يمكن استعمال هاته الوظيفة في تحسين عمليات البحث داخل الموقع 166 | * 167 | * @return string 168 | */ 169 | Arabic::toKeyboardInput(string $str) 170 | 171 | /** 172 | * اعادة كتابة سلسلة نصية عربية ما 173 | * بحروف انجليزية 174 | * يمكن استعمال هاته الوظيفة في انشاء روابط صديقة البحث 175 | * @return string 176 | */ 177 | Arabic::toSpelled(string $str) 178 | 179 | /** 180 | * المكافئ للدالة str_word_count في PHP 181 | * من المهم جدا ملاحظة ان دالة ال PHP 182 | * str_word_count 183 | * لا تدعم اللغى العربية 184 | * ولذلك ان هاته الوظيفة تعتبرا بديلا عنها في اللغة العريبة 185 | * @return int 186 | */ 187 | Arabic::countWords(string $str); 188 | 189 | /** 190 | * التحقق من ما ان كانت سلسلة نصية ما تحوي على الأقل حرفا عربيا واحدا 191 | * @return boolean 192 | */ 193 | Arabic::containsAr(string $str); 194 | ``` 195 | 196 |
197 | 198 | ## أمثلة عن عدة استعمالات 199 | 200 |
201 | 202 | ```php 203 | Arabic::toWords(56) 204 | // ست وخمسون 205 | 206 | Arabic::fromWords("ثمان مئة و خمسة") 207 | // 805 208 | 209 | Arabic::toOrdinal(12) 210 | // الثاني عشر 211 | 212 | Arabic::toIndianNums("ولد عليه الصلاة في 12 ربيع الأول") 213 | // ولد عليه الصلاة في ۱۲ ربيع الاول 214 | 215 | Arabic::toHijri('f' ,'2021/12/12') 216 | // الثامن من جمادى الأولى من السنة الهجرية ألف و أربع مئة و ثلاث و أربعون 217 | 218 | Arabic::fromHijri('1442/01/08') 219 | // 8/27/2020 220 | 221 | Arabic::toRelative('2010/01/10') 222 | // منذ أحد عشر سنة 223 | 224 | Arabic::toRelative('2010/01/10' ,'2008/01/10') 225 | // ثلاث سنين 226 | 227 | Arabic::toRelative('2010/01/10' ,'2008/01/10' ,true) 228 | // [ "y" => 3 , "m" => 39 ,"w" => 156 , "d" => 1096 ,"h" => 26304 ,"mn" => 1578240 ,"s" => 94694400 ] 229 | 230 | Arabic::fromRelative('زد سنة') 231 | // 2022/03/28 232 | 233 | Arabic::fromRelative('قل ست اشهر') 234 | // 2020/09/28 235 | 236 | Arabic::removeHarakat('لا حسَدَ إلَّا في اثنتيْنِ: رجلٌ آتاهُ اللهُ مالًا، فسلَّطَهُ على هلَكتِه في الحقِّ، ورجلٌ آتاهُ اللهُ الحِكمةَ، فهوَ يقضِي بِها، ويُعلِّمُها') 237 | // لا حسد إلا في اثنتين: رجل آتاه الله مالا، فسلطه على هلكته في الحق، ورجل آتاه الله الحكمة، فهو يقضي بها، ويعلمها 238 | 239 | Arabic::toKeyboardInput('dl;k hsjulhg ihji hg]hgm td jpsdk ulgdhj hgfpe fl,ru!') 240 | // يمكن استعمال هاته الدالة في تحسين عمليات البحث بموقع! 241 | 242 | Arabic::toSpelled("قد تساعد هاته الدالة في عمل slugs أو تحسين عمليات البحث") 243 | // qd tsaaad haath āldaalt fii aml slugs āoo thsiin amliiāt ālbhth 244 | 245 | Arabic::countWords("هاته الدالة هي المكافئة لاخرى بالبي اتش بي غير ان هاته لا تتجاهل ترميز اليو تي اف ايت") 246 | // 18 247 | 248 | Arabic::containsAr("this method checks if a given string contains arabic words or charachters , for example : if we mentioned لارفيل يتحدث عربي it will return true!") 249 | // true 250 | ``` 251 | 252 |
253 | 254 | ## الاستعمال في ملفات blade 255 | > قم بتغيير ```method``` إلى التابع المراد كـ: ```Arabic::toWords(643646)``` أو كـ: ```arabic()->toWords(643646)``` 256 | 257 |
258 | 259 | ```php 260 | {{ Arabic::method($input) }} 261 | 262 | // أو 263 | 264 | {{ arabic()->method($input) }} 265 | ``` 266 | 267 |
268 | 269 | كما سيمكنك استعمال متغيرات القالب التالية لشيفرة أنظف 270 | 271 |
272 | 273 | ```php 274 | @toWords(4367) 275 | @toOrdinal(564) 276 | @toIndianNums(ولد عليه الصلاة في 12 ربيع الأول) 277 | @toHijri(2020/12/12) 278 | @toRelative(2019/12/01) 279 | @removeHarakat(فهوَ يقضِي بِها، ويُعلِّمُها) 280 | ``` 281 | 282 |
283 | 284 | ## المساهمة 285 | 286 | **لا تتردد في المساهمة أو مساعدتنا في جعل Laravel يتحدث اللغة العربية بشكل أفضل من خلال فتح مناقشة أو إضافة بعض الطرق الإضافية أو إصلاح خطأ أو المساعدة في تحسين بعض الأساليب!** 287 | 288 |
-------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "adnane/laravel-speaks-arabic", 3 | "description": "a light weight ,open-source laravel package . It facilitates dealing with arabic concepts in Laravel Framework using a set of classes and methods to make laravel speaks arabic! ", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "adnane-ka", 8 | "email": "dannykadri0@gmail.com", 9 | "homepage":"https://github.com/adnane-ka", 10 | "role": "Developer" 11 | }, 12 | { 13 | "name": "muath-ye", 14 | "email": "muathye@gmail.com", 15 | "homepage": "https://muath-ye.github.io" 16 | } 17 | ], 18 | "autoload": { 19 | "psr-4": { 20 | "Adnane\\Arabic\\": "/src" 21 | }, 22 | "files": [ 23 | "/src/helpers.php" 24 | ] 25 | }, 26 | "require": {} 27 | } 28 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "34a7189230824aea246ed2b02f77e9b7", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": [], 16 | "platform-dev": [], 17 | "plugin-api-version": "2.0.0" 18 | } 19 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Laravel Speaks Arabic | laravel-speaks-arabic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/Ar/Strings.php: -------------------------------------------------------------------------------- 1 | 0) 127 | { 128 | $words = self::toPhrase($level); 129 | 130 | if($level > 1 && $level < 11) 131 | { 132 | array_push($decription ,$words.' '.$data['levels'][$index]['plural']); 133 | } 134 | else 135 | { 136 | array_push($decription ,$words.' '.$data['levels'][$index]['singular']); 137 | } 138 | } 139 | else 140 | { 141 | array_push($decription ,self::toPhrase($level)); 142 | } 143 | } 144 | 145 | return $decription; 146 | } 147 | 148 | /** 149 | * gets the levels of the target integer 150 | * as we need to reverse the result array to be easy when it comes to naming 151 | * 152 | * @param $int (int) 153 | * @return array 154 | */ 155 | private static function getLevels($int) 156 | { 157 | $number = number_format($int , 0 ,"." ,","); 158 | 159 | $levels = explode(',' ,$number); 160 | 161 | $levels = array_reverse($levels); 162 | 163 | return $levels; 164 | } 165 | 166 | /** 167 | * this function basiclly use other methods in certain order with certain logic 168 | * it takes the array of named levels , combine it and clean it 169 | * 170 | * 171 | * @param $decription (array) 172 | * @return string 173 | */ 174 | private static function process($decription) 175 | { 176 | $decription = array_reverse($decription); 177 | 178 | $digit = implode(self::$seperator , $decription); 179 | 180 | $digit = self::clean($digit); 181 | 182 | $digit = self::handleSpecialChars($digit); 183 | 184 | $digit = self::organize($digit); 185 | 186 | return $digit; 187 | } 188 | 189 | /** 190 | * cleans the result string after being proccessed 191 | * 192 | * 193 | * @param $str (string) 194 | * @return string 195 | */ 196 | private static function clean($str) 197 | { 198 | $spliced = loader::load()['extra']; 199 | 200 | foreach($spliced as $replaced) 201 | { 202 | $str = str_replace($spliced ,'' ,$str); 203 | } 204 | return $str; 205 | } 206 | 207 | /** 208 | * handle special and unique named chrachters in the result string 209 | * 210 | * as known , the arabic language follows a completly different 211 | * naming rules . for example " Two Hundred " in English must be " اثنان مئة " 212 | * in arabic right ? well , that's not actually , Two hundreds is completly different thing 213 | * it is : مئتان, and so are alot of other numbers .. 214 | * 215 | * @param $str (string) 216 | * @return string 217 | */ 218 | private static function handleSpecialChars($str) 219 | { 220 | $uniques = loader::load()['uniques']; 221 | 222 | foreach(array_keys($uniques) as $unique) 223 | { 224 | $str = str_replace($unique ,$uniques[$unique] ,$str); 225 | } 226 | return $str; 227 | } 228 | 229 | /** 230 | * organize and re-shape final result 231 | * 232 | * due to the dont proccess we may find a lot of spaces . thus , making it a bit cleaner 233 | * looks so much better ! 234 | * @param $str (string) 235 | * @return string 236 | */ 237 | private static function organize($str) 238 | { 239 | $str = explode(' ',$str); 240 | 241 | $str = array_filter($str); 242 | 243 | return implode(' ',$str); 244 | } 245 | 246 | /** 247 | * validate incoming input , check if a given string is allowed to be translated to words 248 | * 249 | * @param $num (int) 250 | * @return boolean 251 | */ 252 | private static function validate($num) 253 | { 254 | if(is_int($num)) 255 | { 256 | if($num > self::$maxNumber) 257 | { 258 | return false; 259 | } 260 | return true; 261 | } 262 | return false; 263 | } 264 | 265 | /** 266 | * convert ones ,tens & hundreds numbers to phrases 267 | * 268 | * @param $data (array) , $num (int) 269 | * @return int 270 | */ 271 | private static function toPhrase($num) 272 | { 273 | # load data 274 | $data = loader::load(); 275 | 276 | # handle ones 277 | if(self::hasDigits($num ,1)) { return $data['ones'][$num]; } 278 | 279 | # handle tens 280 | elseif(self::hasDigits($num ,2)) { return self::handleTens($data ,$num); } 281 | 282 | # handle hundreds 283 | elseif(self::hasDigits($num ,3)) { return self::handleHunds($data ,$num); } 284 | 285 | #otherwise return null 286 | return null; 287 | } 288 | 289 | /** 290 | * handle tens and name them 291 | * 292 | * @param $data (array) , $num (int) 293 | * @return int 294 | */ 295 | private static function handleTens($data ,$num) 296 | { 297 | if(!array_key_exists($num ,$data['tens'])) 298 | { 299 | $ones = self::getOnes($num); 300 | $tens = self::getTens($num); 301 | 302 | if(is_int($tens)) 303 | { 304 | return $data['ones'][$ones] .self::$seperator. $data['tens'][$tens]; 305 | } 306 | return $data['ones'][$ones].' '.$data['tens'][$tens]; 307 | } 308 | return $data['tens'][$num].' '; 309 | } 310 | 311 | /** 312 | * handle Hundreds and name them 313 | * 314 | * @param $data (array) , $num (int) 315 | * @return int 316 | */ 317 | private static function handleHunds($data ,$num) 318 | { 319 | if(!array_key_exists($num ,$data['hundreds'])) 320 | { 321 | $ones = self::getOnes($num); 322 | 323 | $tens = substr(self::getTens($num),-2); 324 | 325 | $hundreds = self::getHundreds($num); 326 | 327 | if(intval($ones) > 0) 328 | { 329 | $ones = self::toPhrase($ones); 330 | 331 | if(intval($tens) > 0){ 332 | 333 | $tens = substr(self::getTens($num) , -2 ,-1).'0'; 334 | 335 | $tens = self::toPhrase($tens); 336 | 337 | $hundreds = self::toPhrase($hundreds); 338 | 339 | return $hundreds .self::$seperator. $ones . self::$seperator . $tens; 340 | } 341 | else 342 | { 343 | return self::toPhrase($hundreds) .self::$seperator. $ones; 344 | } 345 | 346 | } 347 | else 348 | { 349 | if(intval($tens) > 0){ 350 | 351 | $hundreds = intval(substr($hundreds ,0,-2)); 352 | 353 | $hundreds = self::toPhrase($hundreds).' '.$data['hundreds'][100]; 354 | 355 | $tens = substr(self::getTens($num) , -2 ,-1).'0'; 356 | 357 | $tens = self::toPhrase($tens); 358 | 359 | return $hundreds.self::$seperator.$tens; 360 | } 361 | else 362 | { 363 | return self::toPhrase(substr($hundreds , 0 ,-2)).' '.$data['hundreds'][100]; 364 | } 365 | } 366 | } 367 | return $data['hundreds'][$num]; 368 | } 369 | 370 | /** 371 | * check if a given integer has certain number of numbers 372 | * 373 | * @param $int (int) , $target (int) 374 | * @return boolean 375 | */ 376 | private static function hasDigits($int ,$target) 377 | { 378 | if(strlen($int) > $target){ 379 | return false; 380 | } 381 | 382 | return true; 383 | } 384 | 385 | /** 386 | * return the ones of a given integer 387 | * 388 | * @param $int (int) 389 | * @return int 390 | */ 391 | private static function getOnes($int) 392 | { 393 | return intval(substr($int , -1)); 394 | } 395 | 396 | /** 397 | * get the tens of a given integer 398 | * 399 | * example : the tens of 311 is 10 400 | * 401 | * notice that numbers from 11 to 19 follows a different 402 | * naming rule , giving a unique value will be much helpful 403 | * when it comes to naming numbers like 13 404 | * 405 | * @param $int 406 | * @return string,int 407 | */ 408 | private static function getTens($int) 409 | { 410 | $ones = self::getOnes($int); 411 | 412 | $tens = intval(substr($int , 0 ,-1).'0'); 413 | 414 | if($tens == 10 && $ones > 2 && $tens < 20) 415 | { 416 | $tens = 'unique'; // عشر 417 | } 418 | 419 | return $tens; 420 | } 421 | 422 | /** 423 | * return the hundred of a given integer 424 | * 425 | * @param $int (int) 426 | * @return int 427 | */ 428 | private static function getHundreds($int) 429 | { 430 | $hundreds = intval(substr($int , 0,-2).'00'); 431 | 432 | return $hundreds; 433 | } 434 | 435 | 436 | /* 437 | | =============================== 438 | | Reversed methods 439 | | =============================== 440 | */ 441 | 442 | /** 443 | * this method is listerally the reversed method 444 | * of Tafkit::toWords(), as it follows the same 445 | * logic 446 | * 447 | * @param $str (string) 448 | * @return int 449 | */ 450 | public static function fromWords($str) 451 | { 452 | $levelsWithExtra = self::divideIntoLevels($str); 453 | 454 | return self::readFromWrittenLevels($levelsWithExtra); 455 | } 456 | 457 | /** 458 | * this method is kinda the equivalent of number_format($int) 459 | * the only non-common point is that this method chills with 460 | * strings instead of integers :) 461 | * 462 | * @param $str (string) 463 | * @return int 464 | */ 465 | private static function divideIntoLevels($str) 466 | { 467 | $uniques = [ 468 | "اثنان الاف" => "ألفان", 469 | "اثنان ملايين" => "مليونان", 470 | "اثنان ملايير" => "ملياران", 471 | "اثنان ترليونات" => "ترليونان", 472 | ]; 473 | 474 | foreach(array_keys($uniques) as $unique) 475 | { 476 | $str = str_replace($uniques[$unique] ,$unique ,$str); 477 | } 478 | 479 | $returned = []; 480 | $levels = array_reverse([ 481 | 'الاف' => 3, 482 | 'ألف' => 3, 483 | 'الف'=>3, 484 | 'ملايين' => 6, 485 | 'مليون' => 6, 486 | 'ملايير' => 9, 487 | 'مليار' => 9, 488 | 'ترليونات' =>12 , 489 | 'ترليون' =>12 490 | ]); 491 | // foreach level do the following 492 | // get the amount in the level example : 300 [amount :3 ,level :2] 493 | foreach(array_keys($levels) as $level) 494 | { 495 | if(strpos($str ,$level) !== false) 496 | { 497 | // get amount 498 | $lastPos = strpos($str ,$level); 499 | $amount = substr($str , 0 ,$lastPos); 500 | 501 | if(strlen($amount) == 0) $amount = 1; 502 | 503 | // push results in array 504 | $returned[ $levels [ $level ] ] = $amount; 505 | 506 | // cut string and complete loop 507 | $str = substr($str ,$lastPos + strlen($level)); 508 | } 509 | } 510 | 511 | 512 | return [ $returned , $str ]; 513 | } 514 | 515 | /** 516 | * this method handle reading strings divided into 517 | * many levels , a level can be hundreds , thousands and so on 518 | * 519 | * @param $levelsWithExtra (array) 520 | * @return int 521 | */ 522 | private static function readFromWrittenLevels($levelsWithExtra) 523 | { 524 | $levels = $levelsWithExtra[0]; 525 | $extra = $levelsWithExtra[1]; 526 | 527 | $num = 0; 528 | foreach (array_keys($levels) as $level) { 529 | 530 | if($levels[$level] == 1) 531 | { 532 | $piece = 1; 533 | } 534 | else 535 | { 536 | $piece = self::readThreeDigits($levels[$level]); 537 | } 538 | $piece .= ''.str_repeat('0', $level); 539 | 540 | $num .= intval($num + $piece); 541 | } 542 | return intval($num + self::readThreeDigits($extra)); 543 | } 544 | 545 | /** 546 | * three digits numbers are the principal 547 | * unit in naming levels and reading numbers formats 548 | * in arabic 549 | * notice that this follows follows the same logic 550 | * of the reversed method using in Tafkit::fromNumbers(int) 551 | * 552 | * @param $str (string) 553 | * @return int 554 | */ 555 | private static function readThreeDigits($str) 556 | { 557 | # files located at : data/tafkit/json/ 558 | $uniques = loader::load()['trimed_uniques']; 559 | 560 | # change مئتان to اثنان مئة to be more logical when it comes to processing it 561 | foreach(array_keys($uniques) as $unique) 562 | { 563 | $str = str_replace($uniques[$unique] ,$unique ,$str); 564 | } 565 | # read hundreds and conclue the tens 566 | $amount = self::readHundreds($str)[0]; 567 | $str = self::readHundreds($str)[1]; 568 | 569 | # read tens with hundreds 570 | return self::readTens($str) + $amount; 571 | } 572 | 573 | /** 574 | * Tens in arabic concepts are the considered units 575 | * in naming numbers 576 | * so naming certain levels with tens makes it easier 577 | * to get the target number 578 | * @param $str (string) 579 | * @return int 580 | */ 581 | private static function readTens($str) 582 | { 583 | // files located at : data/tafkit/json/ 584 | $zero_to_20 = loader::load()['zero_to_20']; 585 | $tens = loader::load()['trimed_tens']; 586 | $ones = loader::load()['spaced_ones']; 587 | 588 | // trim string 589 | $str = self::trimFromAnds($str); 590 | 591 | // handle zero to 20 592 | if(array_key_exists(trim($str ,' '),$zero_to_20)) 593 | { 594 | return $zero_to_20 [ trim($str ,' ') ]; 595 | } 596 | 597 | // otherwise ,loop and name 20 to 99 598 | foreach (array_keys($tens) as $ten) { 599 | foreach (array_keys($ones) as $one) { 600 | if(strpos($str ,$ones[$one] . $tens[$ten]) !== false) 601 | { 602 | return intval($ten)+intval($one); 603 | } 604 | } 605 | } 606 | return 0; 607 | } 608 | 609 | /** 610 | * notice that all numbers in arabic 611 | * follows the naming manner : 612 | * number followed by n digits (max (n) == 3) is a unit to name a level 613 | * ex : 300,000 , is ثلاث مئة 614 | * so naming levels requires naming handreds + name of level (ثلاث مئة ألف) 615 | * @param $str 616 | * @return array (hundreds + left tens) 617 | */ 618 | private static function readHundreds($str) 619 | { 620 | $hunds = [ 'مئة', 'مائة' ]; 621 | $amount = 0; // an amount is like 3 in 300 (3 * 100) 622 | foreach($hunds as $h) 623 | { 624 | $pos = strpos($str ,$h); 625 | if($pos !== false) 626 | { 627 | $amount = substr($str ,0,$pos); 628 | $subStr = str_replace(['و' ,' '],'', $amount); 629 | if(strlen($subStr) == 0) 630 | { 631 | $amount = 1; 632 | } 633 | else 634 | { 635 | $amount = self::readTens($amount); 636 | } 637 | $amount = intval($amount . '00'); 638 | 639 | if(strlen($amount) == 0) $amount = 1; 640 | 641 | $str = substr($str ,$pos + strlen($h)); 642 | } 643 | } 644 | return [ $amount , $str ]; 645 | } 646 | 647 | /** 648 | * due to the previous proccess 649 | * a one string can be given with alot of seperators 650 | * and connectors ,thus it needs to be trimmed and 651 | * cleaned from spaces & seperators 652 | * @param $str (string) 653 | * @return string 654 | */ 655 | private static function trimFromAnds($str) 656 | { 657 | $subStr = self::$and.' '.self::$one; 658 | // if string starts with و واحد dont right trim it 659 | if(strpos($str, $subStr) !== false) 660 | { 661 | $str = str_replace($subStr ,self::$one ,$str); 662 | 663 | return $str; 664 | } 665 | // otherwise it needs to be trimmed 666 | $str = trim($str ,' '); 667 | $str = rtrim($str ,self::$and.' '); 668 | $str = ltrim($str ,self::$and.' '); 669 | $str = ltrim($str ,' '.self::$and.' '); 670 | $str = rtrim($str ,' '.self::$and.' '); 671 | $str = rtrim($str ,' '.self::$and); 672 | $str = ltrim($str ,' '.self::$and); 673 | return $str; 674 | } 675 | 676 | } -------------------------------------------------------------------------------- /src/Ar/Tawkit.php: -------------------------------------------------------------------------------- 1 | full date 86 | | s : stands for -> standard date 87 | | n : stands for -> numeric date 88 | | 89 | */ 90 | # method 91 | public static function GregorianToHijri($format = 'f' ,$date = null) 92 | { 93 | if(!$date) $time = time(); 94 | else $time = strtotime($date); 95 | 96 | self::$hijri = self::GreToHijri($time); 97 | 98 | switch ($format) { 99 | case 'f': 100 | return self::formatFull(); 101 | break; 102 | case 's': 103 | return self::formatStandard(); 104 | break; 105 | case 'n': 106 | return self::formatNumeric(); 107 | break; 108 | default: 109 | return self::formatFull(); 110 | break; 111 | } 112 | } 113 | 114 | # reverse 115 | public static function HijriToGregorian($date) 116 | { 117 | return jdtogregorian(self::HijriToJD($date)); 118 | } 119 | /* 120 | | these methods converts gregorian time from/to hijri time 121 | | 122 | | it uses the functions cal_to_jd / jdtogregorian 123 | | 124 | | a jd is The Julian day ,which is the continuous count 125 | | of days since the beginning of the Julian period 126 | | julian period starts from : Jan , 1 , 4713 BC 127 | | 128 | | the method cal_to_jd , handles that and counts the days 129 | | past between 4713 BC and the target time 130 | | 131 | | & jdtogregorian does the reverse 132 | | 133 | */ 134 | 135 | # method // response : array 136 | private static function GreToHijri($time = null) 137 | { 138 | if ($time === null) { $time = time(); } 139 | 140 | $date = [ 141 | 'm'=> date('m', $time), 142 | 'd'=> date('d', $time), 143 | 'y'=> date('Y', $time), 144 | ]; 145 | 146 | $julian_day_count = cal_to_jd(CAL_GREGORIAN, $date['m'], $date['d'], $date['y']); 147 | 148 | return self::JDToHijri($julian_day_count); 149 | } 150 | # reverse 151 | private static function HijriToJD($date) 152 | { 153 | $levels = explode('/' ,$date); 154 | 155 | $y = $levels[0]; 156 | $m = $levels[1]; 157 | $d = $levels[2]; 158 | 159 | return (int)((11 * $y + 3) / 30) + 160 | 354 * $y + 30 * $m - 161 | (int)(($m - 1) / 2) + $d + 1948440 - 385; 162 | } 163 | 164 | /* 165 | | this function converts julian day count to hijri month , year , day 166 | | 167 | | as know , the islamic takwim started at : 16 july 622 168 | | that means , a 197 days from 622 were past since the takwim started 169 | | 170 | | thus : ( 612 After Birth + 4713 Before Birth ) years plus the 197 days 171 | | is the julian day count between the two periods 172 | | 173 | | this equals to 1948440 174 | */ 175 | private static function JDToHijri($jd) 176 | { 177 | $jd = $jd - 1948440 + 10633; 178 | 179 | $n = (int)(($jd - 1) / 10631); 180 | 181 | $jd = $jd - 10631 * $n + 354; 182 | 183 | $j = ((int)((10985 - $jd) / 5316)) * 184 | ((int)(50 * $jd / 17719)) + 185 | ((int)($jd / 5670)) * 186 | ((int)(43 * $jd / 15238)); 187 | 188 | $jd = $jd - ((int)((30 - $j) / 15)) * 189 | ((int)((17719 * $j) / 50)) - 190 | ((int)($j / 16)) * 191 | ((int)((15238 * $j) / 43)) + 29; 192 | 193 | $m = (int)(24 * $jd / 709); 194 | 195 | $d = $jd - (int)(709 * $m / 24); 196 | 197 | $y = 30 * $n + $j - 30; 198 | 199 | return [$m, $d, $y]; 200 | } 201 | 202 | /* 203 | | =================================================== 204 | | 205 | | Working With Relative time 206 | | 207 | | =================================================== 208 | */ 209 | 210 | /* 211 | | manage different related class's functions and return simplified results 212 | | count time between two given dates 213 | | example : 1900/12/12 -> "منذ مئة و عشرون سنة" 214 | */ 215 | public static function toRelative($date ,$date2 = null,$detailed = false) 216 | { 217 | $r = self::standardRelative($date ,$date2); 218 | $r = self::handleSpecials($r); 219 | 220 | if($date2) 221 | { 222 | 223 | if($detailed) return self::diff($date ,$date2); 224 | 225 | return $r; 226 | } 227 | 228 | if($detailed) return self::diff($date ,$date2); 229 | 230 | if(strtotime($date) - time() > 0) return self::$in.' '.$r; 231 | 232 | if(strtotime($date) - time() == 0) return self::$now; 233 | 234 | return self::$since.' '.$r; 235 | } 236 | 237 | /* 238 | | handle and clean string depending on unique strings in arabic 239 | | example : منذ اثنان سنة will be منذ سنتين 240 | */ 241 | private static function handleSpecials($str) 242 | { 243 | $data = loader::load()['uniques']; 244 | 245 | foreach ($data as $u) { 246 | $str = str_replace(array_search($u ,$data), $u ,$str); 247 | } 248 | 249 | return $str; 250 | } 251 | 252 | /* 253 | | count the difference between two given dates : 254 | | seconds , years , months ,weeks , days , hours , minutes 255 | | from a date 256 | | example : diff("1900/12/12") 257 | | [ 258 | | "y" => 120, 259 | | "m" => 1568, 260 | | "w" => 6275, 261 | | "d" => 43931, 262 | | "h" => 1054360, 263 | | "mn" => 63261602, 264 | | "s" => 3795696173 265 | |] 266 | */ 267 | private static function diff($date ,$date2 = null) 268 | { 269 | $time = time(); 270 | 271 | if($date2) $time = strtotime($date2); 272 | 273 | $seconds = abs(strtotime($date) - $time); 274 | return 275 | [ 276 | 'y' => intval(floor($seconds / (3600 * 24 * 365.25))), 277 | 'm' => intval(floor($seconds / (3600 * 24 * 7 * 4))), 278 | 'w' => intval(floor($seconds / (3600 * 24 * 7))), 279 | 'd' => intval(floor($seconds / (3600 * 24))), 280 | 'h' => intval(floor($seconds / (3600))), 281 | 'mn' => intval(floor($seconds / (60))), 282 | 's' => intval(floor($seconds)), 283 | ]; 284 | } 285 | 286 | /* 287 | | get the relative time , depending on the greatest level found in diff() 288 | | example : 289 | | [ 290 | | "y" => 120, 291 | | "m" => 1568, 292 | | "w" => 6275, 293 | | "d" => 43931, 294 | | "h" => 1054360, 295 | | "mn" => 63261602, 296 | | "s" => 3795696173 297 | | ] 298 | | == > no need for saying 120 years and 1586 months and ... ect 299 | | == > we better say : since 120 years 300 | */ 301 | private static function standardRelative($date ,$date2 = null) 302 | { 303 | $levels = self::diff($date ,$date2); 304 | 305 | $data = loader::load()['time']; 306 | 307 | foreach($levels as $level) 308 | { 309 | if($level !== 0) 310 | { 311 | $levelSymbol = array_search($level ,$levels); 312 | 313 | if($level > 1) 314 | { 315 | if($level <= 9 && $level > 1) 316 | { 317 | return Tafkit::toWords( $level ) .' '. $data[$levelSymbol]['p']; 318 | } 319 | return Tafkit::toWords( $level ) .' '. $data[$levelSymbol]['s']; 320 | } 321 | else 322 | { 323 | return $data[$levelSymbol]['s']; 324 | } 325 | 326 | } 327 | } 328 | } 329 | 330 | /* 331 | | =================================================================== 332 | | 333 | | REVERSED METHODS 334 | | 335 | |=================================================================== 336 | | 337 | */ 338 | 339 | /* 340 | | from relative to Dates 341 | | this functions is kinda the equivilant of the example bellow 342 | | date('Y/m/d' ,strtotime('+1 days')) 343 | | 344 | | @params $str require (valid strings looks like : زد ثلاث اشهر , قل سنتين) 345 | | 346 | */ 347 | public static function fromRelative($str) 348 | { 349 | // + / - 350 | $indicator = self::detectIndicator($str); 351 | 352 | // قل سنين to سنتين and so on .. 353 | $str = self::detectAndGetRidOfRelative($str); 354 | 355 | // سنة , شهر , اسبوع .. الخ and so on .. 356 | $targetUnit = self::detectAndGetRidOfUnit($str)[0]; 357 | 358 | // قل سنتين to سنتين and so on .. 359 | $str = self::detectAndGetRidOfUnit($str)[1]; 360 | if(strlen(trim($str)) == 0) $str = 'واحد'; 361 | 362 | // ثلاث to 3 and so on .. 363 | $amount = Tafkit::fromWords($str); 364 | 365 | return date('Y/m/d' ,strtotime($indicator.$amount.' '.$targetUnit)); 366 | } 367 | /* 368 | | Detect indicator in relative strings ( + / - ) 369 | | depending on presence of certain strings 370 | | 371 | | @params $str require (valid strings looks like : زد ثلاث اشهر , قل سنتين) 372 | | @return - / + 373 | */ 374 | private static function detectIndicator($str) 375 | { 376 | $indicator = '+'; 377 | 378 | if(strpos($str ,self::$decrease) !== false) $indicator = '-'; 379 | 380 | return $indicator; 381 | } 382 | 383 | /* 384 | | Detect The relative in relative strings ( add / decrease ) 385 | | depending on presence of certain strings 386 | | 387 | | @params $str require (valid strings looks like : زد ثلاث اشهر , قل سنتين) 388 | | 389 | | @return add / decrease 390 | */ 391 | private static function detectAndGetRidOfRelative($str) 392 | { 393 | $relative = self::$add; 394 | 395 | if(strpos($str ,self::$decrease) !== false) $relative = self::$decrease; 396 | 397 | return str_replace($relative ,'',$str); 398 | } 399 | 400 | /* 401 | | Detect The relative unit in relative strings ( months / years / weeks ..ect ) 402 | | as it gets rid of the unit found , 403 | | 404 | | @params $str require (valid strings looks like : زد ثلاث اشهر , قل سنتين) 405 | | 406 | | @return [ $unit , $str (given string trimed from unit) ] 407 | */ 408 | private static function detectAndGetRidOfUnit($str) 409 | { 410 | $units = loader::load()['units']; 411 | foreach (array_keys($units) as $unit) { 412 | if(strpos($str ,$unit) !== false) 413 | { 414 | return [ 415 | $units[$unit], 416 | str_replace($unit,'',$str) 417 | ]; 418 | } 419 | } 420 | } 421 | 422 | 423 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/json/en_unique.json: -------------------------------------------------------------------------------- 1 | { 2 | "o":"و", 3 | "i":"ي" 4 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/json/english_letters.json: -------------------------------------------------------------------------------- 1 | { 2 | "aa":"ع", 3 | "th":"ث", 4 | "sh":"ش", 5 | "ch":"ش", 6 | "a":"ا", 7 | "b":"ب", 8 | "c":"س", 9 | "d":"د", 10 | "e":"", 11 | "f":"ف", 12 | "g":"ج", 13 | "h":"ه", 14 | "i":"ا", 15 | "j":"ج", 16 | "k":"ك", 17 | "l":"ل", 18 | "m":"م", 19 | "n":"ن", 20 | "o":"", 21 | "p":"ب", 22 | "q":"ق", 23 | "r":"ر", 24 | "s":"س", 25 | "t":"ت", 26 | "u":"", 27 | "v":"ف", 28 | "w":"و", 29 | "x":"اكس", 30 | "y":"ي", 31 | "z":"ز" 32 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/json/letters.json: -------------------------------------------------------------------------------- 1 | { 2 | "ا" : "ā", 3 | "أ" : "ā", 4 | "ب" : "b", 5 | "ت" : "t", 6 | "ث" : "th", 7 | "ج" : "j", 8 | "ح" : "h", 9 | "خ" : "kh", 10 | "د" : "d", 11 | "ذ" : "z", 12 | "ر" : "r", 13 | "ز" : "z", 14 | "س" : "s", 15 | "ش" : "sh", 16 | "ص" : "s", 17 | "ض" : "d", 18 | "ط" : "t", 19 | "ظ" : "ẓ", 20 | "ع" : "a", 21 | "غ" : "gh", 22 | "ف" : "f", 23 | "ق" : "q", 24 | "ك" : "k", 25 | "ل" : "l", 26 | "م" : "m", 27 | "ن" : "n", 28 | "ه" : "h", 29 | "و" : "w", 30 | "ي" : "y", 31 | "ة" : "t", 32 | "إ" : "i", 33 | "ى" : "a" 34 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/json/map.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": "ش", 3 | "b": "ﻻ", 4 | "c": "ؤ", 5 | "d": "ي", 6 | "e": "ث", 7 | "f": "ب", 8 | "g": "ل", 9 | "h": "ا", 10 | "i": "ه", 11 | "j": "ت", 12 | "k": "ن", 13 | "l": "م", 14 | "m": "ة", 15 | "n": "ى", 16 | "o": "خ", 17 | "p": "ح", 18 | "q": "ض", 19 | "r": "ق", 20 | "s": "س", 21 | "t": "ف", 22 | "u": "ع", 23 | "v": "ر", 24 | "w": "ص", 25 | "x": "ء", 26 | "y": "غ", 27 | "z": "ئ", 28 | "H":"أ", 29 | "'":"ط", 30 | ";":"ك", 31 | ".":"ز", 32 | "/":"ظ", 33 | "]":"د", 34 | "[":"ج", 35 | ",":"و", 36 | "`":"ذ" 37 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/json/uniques.json: -------------------------------------------------------------------------------- 1 | { 2 | "و":"oo", 3 | "ي":"ii", 4 | "ا":"aa" 5 | } -------------------------------------------------------------------------------- /src/Ar/data/strings/loader.php: -------------------------------------------------------------------------------- 1 | self::toAssoc('letters.json'), 13 | 'en_letters'=> self::toAssoc('english_letters.json'), 14 | 'en_unique'=> self::toAssoc('en_unique.json'), 15 | 16 | 'uniques' => self::toAssoc('uniques.json'), 17 | 18 | 'map' => self::toAssoc('map.json'), 19 | ]; 20 | } 21 | /* 22 | | including the file and converting to associative array 23 | | 24 | */ 25 | private static function toAssoc($filename) 26 | { 27 | self::$rootDir = dirname(__FILE__).'/json'; 28 | 29 | return json_decode(file_get_contents(self::$rootDir.'/'.$filename) ,true); 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/extra.json: -------------------------------------------------------------------------------- 1 | { 2 | "7":"و صفر مئة ألف", 3 | "0":"و صفر مئة الاف", 4 | "1":"و صفر عشر الاف", 5 | "2":"و صفر الاف", 6 | "3":"و صفر مئة", 7 | "5":"و صفر ألف", 8 | "8":"و صفر مليون", 9 | "9":"و صفر مليار", 10 | "10":"و صفر ترليون", 11 | "11":"و صفر" 12 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/hundreds.json: -------------------------------------------------------------------------------- 1 | { 2 | "100":"مئة", 3 | "200":"مئتان" 4 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/levels.json: -------------------------------------------------------------------------------- 1 | { 2 | "1":{ 3 | "plural":"الاف", 4 | "singular":"ألف" 5 | }, 6 | "2":{ 7 | "plural":"ملايين", 8 | "singular":"مليون" 9 | }, 10 | "3":{ 11 | "plural":"ملايير", 12 | "singular":"مليار" 13 | }, 14 | "4":{ 15 | "plural":"ترليونات", 16 | "singular":"ترليون" 17 | } 18 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/numbers.json: -------------------------------------------------------------------------------- 1 | { 2 | "0":"۰" , 3 | "1":"۱" , 4 | "2":"۲" , 5 | "3":"۳" , 6 | "4":"٤", 7 | "5":"٥" , 8 | "6":"٦", 9 | "7":"٧", 10 | "8":"۸", 11 | "9":"۹" 12 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/ones.json: -------------------------------------------------------------------------------- 1 | { 2 | "0":"صفر", 3 | "1":"واحد", 4 | "2":"اثنان", 5 | "3":"ثلاث", 6 | "4":"أربع", 7 | "5":"خمس", 8 | "6":"ست", 9 | "7":"سبع", 10 | "8":"ثمان", 11 | "9":"تسع" 12 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/order.json: -------------------------------------------------------------------------------- 1 | { 2 | "1":{ 3 | "unique":"الأول", 4 | "standard":"الواحد" 5 | }, 6 | "2":"الثاني", 7 | "3": "الثالث", 8 | "4":"الرابع", 9 | "5": "الخامس", 10 | "6": "السادس", 11 | "7": "السابع", 12 | "8": "الثامن", 13 | "9":"التاسع", 14 | "10": "العاشر", 15 | "11":"الحادي عشر", 16 | "12":"الثاني عشر", 17 | "13":"الثالث عشر", 18 | "14":"الرابع عشر", 19 | "15":"الخامس عشر", 20 | "16":"السادس عشر", 21 | "17":"السابع عشر", 22 | "18":"الثامن عشر", 23 | "19":"التاسع عشر", 24 | "20": "العشرون", 25 | "30": "الثلاثون", 26 | "40": "الأربعون", 27 | "50": "الخمسون", 28 | "60": "الستون", 29 | "70": "السبعون", 30 | "80": "الثمانون", 31 | "90": "التسعون", 32 | "100":"المئة" 33 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/spaced_ones.json: -------------------------------------------------------------------------------- 1 | { 2 | "1" : "واحد و ", 3 | "2" : "اثنان و ", 4 | "3" : "ثلاث و ", 5 | "4" : "أربع و ", 6 | "5" : "خمس و ", 7 | "6" : "ست و ", 8 | "7" : "سبع و ", 9 | "8" : "ثمان و ", 10 | "9" : "تسع و ", 11 | "0" : "" 12 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/tens.json: -------------------------------------------------------------------------------- 1 | { 2 | "unique":"عشر", 3 | 4 | "10":"عشرة", 5 | "11":"أحد عشر", 6 | "12":"اثنا عشر", 7 | "20":"عشرون", 8 | "30":"ثلاثون", 9 | "40":"أربعون", 10 | "50":"خمسون", 11 | "60": "ستون", 12 | "70": "سبعون", 13 | "80": "ثمانون", 14 | "90": "تسعون" 15 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/trimed_tens.json: -------------------------------------------------------------------------------- 1 | { 2 | "20":"عشرون", 3 | "30":"ثلاثون", 4 | "40":"أربعون", 5 | "50":"خمسون", 6 | "60": "ستون", 7 | "70": "سبعون", 8 | "80": "ثمانون", 9 | "90": "تسعون" 10 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/trimed_uniques.json: -------------------------------------------------------------------------------- 1 | { 2 | "اثنان مئة" : "مئتان", 3 | "اثنان الاف" : "ألفان", 4 | "اثنان ملايين" : "مليونان", 5 | "اثنان ملايير" : "ملياران", 6 | "اثنان ترليونات" : "ترليونان" 7 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/uniqes.json: -------------------------------------------------------------------------------- 1 | { 2 | "واحد مئة":"مئة", 3 | "اثنان مئة":"مئتان", 4 | 5 | "واحد و عشرة":"أحدا عشر", 6 | "اثنان و عشرة":"اثنا عشر", 7 | "و عشرة ":" عشر", 8 | 9 | "واحد ألف":"ألف", 10 | "اثنان الاف":"ألفان" , 11 | 12 | "واحد مليون":"مليون", 13 | "اثنان ملايين":"مليونان", 14 | 15 | "واحد مليار":"مليار", 16 | "اثنان ملايير":"ملياران", 17 | 18 | "واحد ترليون":"ترليون", 19 | "اثنان ترليونات":"ترليونان" 20 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/json/zero_to_20.json: -------------------------------------------------------------------------------- 1 | { 2 | "صفر": "0" , 3 | "واحد": "1", 4 | "احد": "1", 5 | "اثنان": "2", 6 | 7 | "اثنتان": "2", 8 | "ثلاث": "3", 9 | "ثلاثة": "3", 10 | "أربع": "4", 11 | 12 | "أربعة": "4", 13 | "خمس": "5", 14 | "خمسة": "5", 15 | "ست": "6", 16 | "ستة": "6", 17 | "سبع": "7", 18 | "سبعة": "7", 19 | "ثمان": "8", 20 | "ثمانية": "8", 21 | "تسعة": "9", 22 | "تسع": "9", 23 | 24 | "عشرة":"10", 25 | "عشر":"10", 26 | 27 | "أحد عشر":"11", 28 | "احد عشر":"11", 29 | "احدا عشرة":"11", 30 | "أحدا عشر":"11", 31 | 32 | "اثنا عشر":"12", 33 | "اثنا عشرة":"12", 34 | 35 | "ثلاثة عشر":"13", 36 | "ثلاث عشر":"13", 37 | 38 | "اربع عشر":"14", 39 | "اربعة عشرة":"14", 40 | "أربعة عشرة":"14", 41 | "أربعة عشر":"14", 42 | "أربع عشر":"14", 43 | 44 | "خمس عشرة":"15", 45 | "خمسة عشر":"15", 46 | "خمس عشر":"15", 47 | 48 | "ست عشر":"16", 49 | "ستة عشرة":"16", 50 | 51 | "سبع عشر":"17", 52 | "سبعة عشرة":"17", 53 | 54 | "ثمان عشرة":"18", 55 | "ثمان عشر":"18", 56 | "ثمانية عشرة":"18", 57 | 58 | "تسعة عشرة":"19", 59 | "تسع عشرة":"19", 60 | "تسع عشر":"19" 61 | } -------------------------------------------------------------------------------- /src/Ar/data/tafkit/loader.php: -------------------------------------------------------------------------------- 1 | self::toAssoc('ones.json'), 13 | 'tens' => self::toAssoc('tens.json'), 14 | 'hundreds' => self::toAssoc('hundreds.json'), 15 | 16 | 'levels' => self::toAssoc('levels.json'), 17 | 'uniques' => self::toAssoc('uniqes.json'), 18 | 'extra' => self::toAssoc('extra.json'), 19 | 20 | 'order' => self::toAssoc('order.json'), 21 | 22 | 'numbers' => self::toAssoc('numbers.json'), 23 | 24 | 'zero_to_20' => self::toAssoc('zero_to_20.json'), 25 | 'spaced_ones' => self::toAssoc('spaced_ones.json'), 26 | 'trimed_uniques' => self::toAssoc('trimed_uniques.json'), 27 | 'trimed_tens' => self::toAssoc('trimed_tens.json'), 28 | ]; 29 | } 30 | /* 31 | | including the file and converting to associative array 32 | | 33 | */ 34 | private static function toAssoc($filename) 35 | { 36 | self::$rootDir = dirname(__FILE__).'/json'; 37 | 38 | return json_decode(file_get_contents(self::$rootDir.'/'.$filename) ,true); 39 | } 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/days.json: -------------------------------------------------------------------------------- 1 | { 2 | "0":"الاثنين", 3 | "1":"الثلاثاء", 4 | "2":"الأربعاء", 5 | "3":"الخميس", 6 | "4":"الجمعة", 7 | "5":"السبت", 8 | "6":"الأحد" 9 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/hijri_months.json: -------------------------------------------------------------------------------- 1 | { 2 | "1":"محرم", 3 | "2":"صفر", 4 | "3":"ربيع الأول", 5 | "4":"ربيع الاخر", 6 | "5":"جمادى الأولى", 7 | "6":"جمادى الاخرة", 8 | "7":"رجب", 9 | "8":"شعبان", 10 | "9":"رمضان", 11 | "10":"شوال", 12 | "11":"ذو القعدة", 13 | "12":"ذو الحجة" 14 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/months.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adnane-ka/laravel-speaks-arabic/b4bb88b3c09f0c749d0e4a6e67dd5c71a8b76c7e/src/Ar/data/tawkit/json/months.json -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/relative.json: -------------------------------------------------------------------------------- 1 | { 2 | "today":"اليوم", 3 | "tomorrow":"الغد", 4 | "yesterday":"البارحة", 5 | "AM":"صباحا", 6 | "PM":"مساءا", 7 | "year":"العام", 8 | "month":"الشهر", 9 | "hour":"الساعة" 10 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/time.json: -------------------------------------------------------------------------------- 1 | { 2 | "s":{ 3 | "s":"ثانية", 4 | "p":"ثواني" 5 | }, 6 | "mn": { 7 | "s":"دقيقة", 8 | "p":"دقائق" 9 | }, 10 | "h": { 11 | "s":"ساعة", 12 | "p":"ساعات" 13 | }, 14 | "d": { 15 | "s":"يوم", 16 | "p":"أيام" 17 | }, 18 | "w":{ 19 | "s":"أسبوع", 20 | "p":"أسابيع" 21 | }, 22 | "m":{ 23 | "s":"شهر", 24 | "p":"أشهر" 25 | }, 26 | "y":{ 27 | "s":"سنة", 28 | "p":"سنين" 29 | } 30 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/uniques.json: -------------------------------------------------------------------------------- 1 | { 2 | "اثنان أيام":"يومين", 3 | "اثنان ساعة":"ساعتين", 4 | "اثنان ثانية":"ثانيتين", 5 | "اثنان دقيقة":"دقيقتين", 6 | "اثنان أسابيع":"أسبوعين", 7 | "اثنان أشهر":"شهرين", 8 | "اثنان سنة":"سنتين", 9 | "مئتان سنة":"قرنين" 10 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/json/units.json: -------------------------------------------------------------------------------- 1 | { 2 | "أشهر":"months", 3 | "اشهر":"months", 4 | "شهر":"months", 5 | 6 | "سنوات":"years", 7 | "سنين":"years", 8 | "سنة":"years", 9 | 10 | "يوم" : "days", 11 | "ايام" : "days", 12 | "أيام" : "days", 13 | 14 | "دقيقة" : "minutes", 15 | "دقائق" : "minutes", 16 | 17 | "ساعات":"hours", 18 | "ساعة":"hours", 19 | 20 | "أسبوع":"weeks", 21 | "أسابيع":"weeks", 22 | "اسابيع":"weeks", 23 | "اسبوع":"weeks" 24 | } -------------------------------------------------------------------------------- /src/Ar/data/tawkit/loader.php: -------------------------------------------------------------------------------- 1 | self::toAssoc('hijri_months.json'), 13 | 14 | 'time' => self::toAssoc('time.json'), 15 | 'uniques' => self::toAssoc('uniques.json'), 16 | 17 | 'days' => self::toAssoc('days.json'), 18 | 'relative' => self::toAssoc('relative.json'), 19 | 'units' => self::toAssoc('units.json'), 20 | 21 | ]; 22 | } 23 | /* 24 | | including the file and converting to associative array 25 | | 26 | */ 27 | private static function toAssoc($filename) 28 | { 29 | self::$rootDir = dirname(__FILE__).'/json'; 30 | 31 | return json_decode(file_get_contents(self::$rootDir.'/'.$filename) ,true); 32 | } 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/Arabic.php: -------------------------------------------------------------------------------- 1 | [ Ar\Tafkit::class ,'toWords' ], 20 | 'fromWords' => [ Ar\Tafkit::class ,'fromWords' ], 21 | 'toOrdinal' => [ Ar\Tafkit::class ,'toOrdinal' ], 22 | 'toIndianNums' => [ Ar\Tafkit::class ,'toIndianNums' ], 23 | 'toHijri' => [ Ar\Tawkit::class ,'GregorianToHijri' ], 24 | 'fromHijri' => [ Ar\Tawkit::class ,'HijriToGregorian' ], 25 | 'toRelative' => [ Ar\Tawkit::class ,'toRelative' ], 26 | 'fromRelative' => [ Ar\Tawkit::class ,'fromRelative' ], 27 | 'removeHarakat' => [ Ar\Strings::class ,'removeHarakat' ], 28 | 'toKeyboardInput' => [ Ar\Strings::class ,'toKeyboardInput' ], 29 | 'toSpelled' => [ Ar\Strings::class ,'toSpelled' ], 30 | 'countWords' => [ Ar\Strings::class ,'utf8WordCount'], 31 | 'containsAr' => [ Ar\Strings::class ,'containsArabic'], 32 | ]; 33 | } 34 | -------------------------------------------------------------------------------- /src/ArabicServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->make('Adnane\Arabic\Arabic'); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Caller.php: -------------------------------------------------------------------------------- 1 |