├── .travis.yml ├── .gitignore ├── composer.json ├── LICENSE ├── src └── ngfw │ ├── banned.txt │ └── Recipe.php ├── README.md └── tests └── RecipeTest.php /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | 5 | before_script: 6 | - composer self-update 7 | - composer install --dev 8 | 9 | # Commands you want to run that will verify your build. 10 | script: phpunit --bootstrap src/ngfw/Recipe.php tests/RecipeTest.php 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | composer.phar 2 | /vendor/ 3 | 4 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file 5 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 6 | composer.lock 7 | .idea/ 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngfw/recipe", 3 | "description": "Small Collection of useful PHP functions", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Nick G", 8 | "email": "gejadze@gmail.com" 9 | } 10 | ], 11 | "minimum-stability": "dev", 12 | "require": { 13 | "php": ">=5.3.0" 14 | }, 15 | "require-dev": { 16 | "phpunit/phpunit": "5.7.19" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "ngfw\\": "src/ngfw/" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nick Gejadze 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/ngfw/banned.txt: -------------------------------------------------------------------------------- 1 | 0815.ru 2 | 0clickemail.com 3 | 0-mail.com 4 | 0wnd.net 5 | 0wnd.org 6 | 10minutemail.com 7 | 10minutemail.de 8 | 123-m.com 9 | 126.com 10 | 139.com 11 | 163.com 12 | 1pad.de 13 | 20minutemail.com 14 | 20mm.in 15 | 21cn.com 16 | 2prong.com 17 | 33mail.com 18 | 3d-painting.com 19 | 4warding.com 20 | 4warding.net 21 | 4warding.org 22 | 60minutemail.com 23 | 6paq.com 24 | 7days-printing.com 25 | 7tags.com 26 | 99experts.com 27 | 9ox.net 28 | a-bc.net 29 | acentri.com 30 | advantimo.com 31 | advertfast.com 32 | agedmail.com 33 | aichyna.com 34 | ak.mintemail.com 35 | amilegit.com 36 | ano-mail.net 37 | anonbox.net 38 | anonymbox.com 39 | antichef.com 40 | antichef.net 41 | antispam.de 42 | appixie.com 43 | armyspy.com 44 | baxomale.ht.cx 45 | beefmilk.com 46 | berahe.info 47 | bi-dating.info 48 | bigmir.net 49 | bigstring.com 50 | binkmail.com 51 | bio-muesli.net 52 | bitmessage.ch 53 | bk.ru 54 | blackbox.trillianpro.com 55 | bloatbox.com 56 | bobmail.info 57 | bodhi.lawlita.com 58 | bofthew.com 59 | bookee.com 60 | boxformail.in 61 | brefmail.com 62 | brennendesreich.de 63 | broadbandninja.com 64 | bsnow.net 65 | bspamfree.org 66 | buffemail.com 67 | bugmenot.com 68 | bumpymail.com 69 | bund.us 70 | burnthespam.info 71 | c2.hu 72 | cash.com 73 | cashette.com 74 | cashette.fr 75 | casualdx.com 76 | ccxt.info 77 | ce.mintemail.com 78 | cellurl.com 79 | chammy.info 80 | chcb.info 81 | cheatmail.de 82 | chogmail.com 83 | chong-mail.com 84 | chong-mail.net 85 | chong-mail.org 86 | clixser.com 87 | cmail.com 88 | cmail.net 89 | cmail.org 90 | consumerriot.com 91 | cool.fr.nf 92 | correo.blogos.net 93 | cosmorph.com 94 | courriel.fr.nf 95 | courrieltemporaire.com 96 | crapmail.org 97 | curryworld.de 98 | cust.in 99 | cuvox.de 100 | dacoolest.com 101 | daintly.com 102 | dandikmail.com 103 | dayrep.com 104 | dbunker.com 105 | dcemail.com 106 | deadaddress.com 107 | deagot.com 108 | dealja.com 109 | despam.it 110 | devnullmail.com 111 | dfgh.net 112 | digitalsanctuary.com 113 | dingbone.com 114 | discardmail.com 115 | discardmail.de 116 | disposableaddress.com 117 | disposableinbox.com 118 | dispose.it 119 | disposeamail.com 120 | disposemail.com 121 | dispostable.com 122 | dm.w3internet.co.uk 123 | dodgeit.com 124 | dodgit.com 125 | dodgit.org 126 | domain141.com 127 | domozmail.com 128 | dontreg.com 129 | dontsendmespam.de 130 | drdrb.com 131 | drdrb.net 132 | droplar.com 133 | dudmail.com 134 | dump-email.info 135 | dumpyemail.com 136 | dunflimblag.mailexpire.com 137 | duskmail.com 138 | e4ward.com 139 | easytrashmail.com 140 | easy-trash-mail.com 141 | eco.wretch.twbbs.org 142 | einrot.com 143 | einrot.de 144 | e-mail.com 145 | e-mail.org 146 | email60.com 147 | emailgo.de 148 | emailias.com 149 | emailinfive.com 150 | email-jetable.biz.st 151 | emailjetable.eu 152 | email-jetable.fr 153 | emaillime.com 154 | emailmiser.com 155 | emailsensei.com 156 | emailtemporar.ro 157 | emailtemporario.com.br 158 | emailthe.net 159 | emailtmp.com 160 | emailwarden.com 161 | ephemail.com 162 | ephemail.net 163 | europe.com 164 | example.com 165 | explodemail.com 166 | eyepaste.com 167 | fakeinbox.com 168 | fakeinformation.com 169 | fakemail.fr 170 | fanaticars.info 171 | fantasymail.de 172 | fastacura.com 173 | fatflap.com 174 | faza.ru 175 | fdfdsfds.com 176 | fightallspam.com 177 | filzmail.com 178 | find-love.info 179 | fizmail.com 180 | fleckens.hu 181 | flyspam.com 182 | for-fun.info 183 | foteret.info 184 | fr33mail.info 185 | frapmail.com 186 | freefreemail.info 187 | freenet.de 188 | freestuffo1.com 189 | freestuffo2.com 190 | freestuffo3.com 191 | freestuffo4.com 192 | friendlymail.co.uk 193 | fromru.com 194 | fuckingduh.com 195 | fudgerub.com 196 | garliclife.com 197 | gawab.com 198 | get1mail.com 199 | get2mail.fr 200 | getairmail.com 201 | getmails.eu 202 | getonemail.com 203 | getonemail.net 204 | girlsundertheinfluence.com 205 | gishpuppy.com 206 | goemailgo.com 207 | gold2world.biz 208 | gotmail.com 209 | gotmail.net 210 | gotmail.org 211 | gotti.otherinbox.com 212 | grandmasmail.com 213 | great-host.in 214 | grifon.info 215 | grr.la 216 | gsrv.co.uk 217 | guerillamail.org 218 | guerrillamail.biz 219 | guerrillamail.com 220 | guerrillamail.de 221 | guerrillamail.net 222 | guerrillamail.org 223 | guerrillamailblock.com 224 | gustr.com 225 | hacccc.com 226 | haltospam.com 227 | herp.in 228 | hidzz.com 229 | hochsitze.com 230 | hotpop.com 231 | hulapla.de 232 | hushmail.com 233 | ieatspam.eu 234 | ieatspam.info 235 | iespana.es 236 | ihateyoualot.info 237 | imails.info 238 | imgof.com 239 | inbox.ru 240 | inboxclean.com 241 | inboxclean.org 242 | incognitomail.com 243 | incognitomail.net 244 | incognitomail.org 245 | instant-mail.de 246 | ipoo.org 247 | irish2me.com 248 | isuisse.com 249 | jetable.com 250 | jetable.fr.nf 251 | jetable.net 252 | jetable.org 253 | jnxjn.com 254 | jourrapide.com 255 | jsrsolutions.com 256 | junk.trillianpro.com 257 | junk1e.com 258 | kasmail.com 259 | kaspop.com 260 | klassmaster.com 261 | klzlk.com 262 | korsun.pp.ru 263 | kulturbetrieb.info 264 | kurzepost.de 265 | lavabit.com 266 | letthemeatspam.com 267 | lhsdv.com 268 | lifebyfood.com 269 | link2mail.com 270 | link2mail.net 271 | list.ru 272 | litedrop.com 273 | lookugly.com 274 | lopl.co.cc 275 | lr78.com 276 | lroid.com 277 | m4ilweb.info 278 | maboard.com 279 | mail.by 280 | mail.mezimages.net 281 | mail.ru 282 | mail114.net 283 | mail15.com 284 | mail15.fr 285 | mail333.com 286 | mail4trash.com 287 | mailbidon.com 288 | mailbucket.org 289 | mailcatch.com 290 | maileater.com 291 | mailexpire.com 292 | mail-filter.com 293 | mail-gratuit.com 294 | mailguard.me 295 | mailhazard.com 296 | mailin8r.com 297 | mailinator.com 298 | mailinator.net 299 | mailinator.org 300 | mailinator.us 301 | mailinator2.com 302 | mailincubator.com 303 | mailismagic.com 304 | mailme.lv 305 | mailmetrash.com 306 | mailmoat.com 307 | mailnator.com 308 | mailnesia.com 309 | mailnull.com 310 | mailquack.com 311 | mailscrap.com 312 | mailtemporaire.com 313 | mail-temporaire.com 314 | mail-temporaire.eu 315 | mailtemporaire.fr 316 | mail-temporaire.fr 317 | mailzilla.org 318 | makemetheking.com 319 | manybrain.com 320 | masterhost.ru 321 | mbx.cc 322 | mega.zik.dj 323 | meltmail.com 324 | mierdamail.com 325 | migumail.com 326 | mintemail.com 327 | mobileninja.co.uk 328 | moburl.com 329 | moncourrier.fr.nf 330 | monemail.fr.nf 331 | monmail.fr.nf 332 | moyareklama.ru 333 | msk.su 334 | mt2009.com 335 | mt2014.com 336 | muuh.info 337 | mx0.wwwnew.eu 338 | mycleaninbox.net 339 | myemailboxy.com 340 | mymail-in.net 341 | mypacks.net 342 | mypartyclip.de 343 | mytempemail.com 344 | mytrashmail.com 345 | myxost.com 346 | nepwk.com 347 | ne-quid-nimis.info 348 | nervmich.net 349 | nervtmich.net 350 | neverbox.com 351 | nice-4u.com 352 | nil-admirari.info 353 | nobulk.com 354 | noclickemail.com 355 | nogmailspam.info 356 | nomail.xl.cx 357 | nomail2me.com 358 | no-spam.ws 359 | nospam.ze.tc 360 | nospam4.us 361 | nospamfor.us 362 | nospamthanks.info 363 | notmailinator.com 364 | nowhere.org 365 | nowmymail.com 366 | nwldx.com 367 | objectmail.com 368 | obobbo.com 369 | octivian.com 370 | one.it 371 | one.lt 372 | onewaymail.com 373 | ordinaryamerican.net 374 | otherinbox.com 375 | owlpic.com 376 | paplease.com 377 | pcusers.otherinbox.com 378 | pepbot.com 379 | pisem.net 380 | pochta.ru 381 | poczta.onet.pl 382 | politikerclub.de 383 | pookmail.com 384 | porn.com 385 | pornoroxx.net 386 | portsaid.cc 387 | prescrip.pl 388 | privy-mail.com 389 | proxymail.eu 390 | prtnx.com 391 | punkass.com 392 | putthisinyourspamdatabase.com 393 | pwrby.com 394 | qlfg.com 395 | qq.com 396 | quickinbox.com 397 | rambler.ru 398 | rcpt.at 399 | recode.me 400 | recursor.net 401 | regbypass.com 402 | rhyta.com 403 | rmqkr.net 404 | royal.net 405 | rppkn.com 406 | rtrtr.com 407 | s0ny.net 408 | safe-mail.net 409 | safetymail.info 410 | safetypost.de 411 | sales.trillianpro.com 412 | sandelf.de 413 | saynotospams.com 414 | schafmail.de 415 | selfdestructingmail.com 416 | sendspamhere.com 417 | sharklasers.com 418 | shiftmail.com 419 | shit.trillianpro.com 420 | shitmail.me 421 | shitmail.org 422 | shitware.nl 423 | shortmail.net 424 | sibmail.com 425 | sinnlos-mail.de 426 | siteposter.net 427 | skeefmail.com 428 | skim.com 429 | slopsbox.com 430 | smeh.info 431 | smellfear.com 432 | snakemail.com 433 | sneakemail.com 434 | snkmail.com 435 | sofimail.com 436 | sofort-mail.de 437 | sogetthis.com 438 | soodonims.com 439 | spam.la 440 | spam.su 441 | spam4.me 442 | spamarrest.com 443 | spamavert.com 444 | spambob.com 445 | spambob.net 446 | spambob.org 447 | spambog.com 448 | spambog.de 449 | spambog.ru 450 | spambox.info 451 | spambox.us 452 | spamcannon.net 453 | spamcero.com 454 | spamcorptastic.com 455 | spamday.com 456 | spameater.org 457 | spamex.com 458 | spamfree.eu 459 | spamfree24.com 460 | spamfree24.de 461 | spamfree24.eu 462 | spamfree24.info 463 | spamfree24.net 464 | spamfree24.org 465 | spamgourmet.com 466 | spamgourmet.net 467 | spamgourmet.org 468 | spamh0le.com 469 | spamherelots.com 470 | spamhereplease.com 471 | spamhole.com 472 | spamify.com 473 | spaminator.de 474 | spamkill.info 475 | spaml.com 476 | spaml.de 477 | spammotel.com 478 | spamobox.com 479 | spamsalad.in 480 | spamspot.com 481 | spamthis.co.uk 482 | spamthisplease.com 483 | spamtroll.net 484 | speed.1s.fr 485 | spikio.com 486 | spoofmail.de 487 | squizzy.de 488 | startkeys.com 489 | stinkefinger.net 490 | stuffmail.de 491 | supergreatmail.com 492 | superrito.com 493 | superstachel.de 494 | suremail.info 495 | tagyourself.com 496 | talkinator.com 497 | tapchicuoihoi.com 498 | teewars.org 499 | tele-vision.info 500 | teleworm.com 501 | teleworm.us 502 | temp.emeraldwebmail.com 503 | tempalias.com 504 | tempemail.biz 505 | tempemail.co.za 506 | tempemail.com 507 | tempe-mail.com 508 | tempemail.net 509 | tempinbox.co.uk 510 | tempinbox.com 511 | tempmail.it 512 | tempmaildemo.com 513 | tempomail.com 514 | tempomail.fr 515 | temporaryemail.net 516 | temporaryemail.us 517 | temporaryinbox.com 518 | tempthe.net 519 | thailaaa.org.ua 520 | thanksnospam.info 521 | thankyou2010.com 522 | thecannabishunter.com 523 | thisisnotmyrealemail.com 524 | throwawayemailaddress.com 525 | tilien.com 526 | tittbit.in 527 | tmailinator.com 528 | tormail.org 529 | tradedoubling.co.uk 530 | tradermail.info 531 | trash2009.com 532 | trash2010.com 533 | trash2011.com 534 | trash-amil.com 535 | trashmail.at 536 | trash-mail.at 537 | trashmail.com 538 | trash-mail.com 539 | trash-mail.de 540 | trashmail.me 541 | trashmail.net 542 | trashmail.ws 543 | trashmailer.com 544 | trashymail.com 545 | trashymail.net 546 | trbvm.com 547 | trillianpro.com 548 | tut.by 549 | tyldd.com 550 | uggsrock.com 551 | ukr.net 552 | umail.net 553 | uroid.com 554 | users.1go.dk 555 | veryrealemail.com 556 | vidchart.com 557 | vomoto.com 558 | vubby.com 559 | vxaz.com 560 | webemail.me 561 | webm4il.info 562 | wegwerfadresse.de 563 | wegwerfemail.de 564 | weg-werf-email.de 565 | wegwerf-email-addressen.de 566 | wegwerf-emails.de 567 | wegwerfmail.de 568 | wegwerfmail.info 569 | wegwerfmail.net 570 | wegwerfmail.org 571 | weibo.10086.cn 572 | wh4f.org 573 | whatiaas.com 574 | whyspam.me 575 | willhackforfood.biz 576 | willselfdestruct.com 577 | winemaven.info 578 | wronghead.com 579 | wuzupmail.net 580 | x.trillianpro.com 581 | xoxy.net 582 | xyzfree.net 583 | yahoo.com.ph 584 | yahoo.com.vn 585 | yandex.ru 586 | yeah.net 587 | yogamaven.com 588 | yopmail.com 589 | yopmail.fr 590 | yopmail.net 591 | yopmail.org 592 | ypmail.webarnak.fr.eu.org 593 | yufz.com 594 | yuurok.com 595 | za.com 596 | zippymail.info 597 | zoemail.net 598 | zomg.info -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Recipe :book: 2 | #### Collection of PHP Functions 3 | 4 | ![](https://travis-ci.org/ngfw/Recipe.svg?branch=master) ![](https://img.shields.io/packagist/v/ngfw/recipe.svg?maxAge=259120) ![](https://img.shields.io/badge/code-awesome-brightgreen.svg?maxAge=2592100) ![](https://img.shields.io/badge/language-PHP-blue.svg?maxAge=2592000) [![StyleCI](https://styleci.io/repos/65232201/shield?branch=master)](https://styleci.io/repos/65232201) 5 | 6 | --- 7 | Table of Contents 8 | * [🚀 Quick Start](#quick-start) 9 | * [Favicon](#favicon) 10 | * [QRcode](#qrcode) 11 | * [File extension](#file-extension) 12 | * [Gravatar](#gravatar) 13 | * [Creating Link Tags](#creating-link-tags) 14 | * [Validate email address](#validate-email-address) 15 | * [Validate URL](#validate-url) 16 | * [RSS Reader](#rss-reader) 17 | * [Object to Array](#object-to-array) 18 | * [Array to Object](#array-to-object) 19 | * [Array to String](#array-to-string) 20 | * [HEX to RGB](#hex-to-rgb) 21 | * [RGB to HEX](#rgb-to-hex) 22 | * [Color Name to HEX](#color-name-to-hex) 23 | * [Generate Random Password](#generate-random-password) 24 | * [Simple Encode](#simple-encode) 25 | * [Simple Decode](#simple-decode) 26 | * [Generate Server Specific Hash](#generate-server-specific-hash) 27 | * [Detect HTTPS](#detect-https) 28 | * [Detect AJAX](#detect-ajax) 29 | * [Check if number is odd](#check-if-number-is-odd) 30 | * [Check if number is even](#check-if-number-is-even) 31 | * [Get Current URL](#get-current-url) 32 | * [Get Client IP](#get-client-ip) 33 | * [Detect Mobile](#detect-mobile) 34 | * [Get Browser](#get-browser) 35 | * [Get Client Location](#get-client-location) 36 | * [Number To Word conversion](#number-to-word-conversion) 37 | * [Seconds To Text](#seconds-to-text) 38 | * [Minutes To Text](#minutes-to-text) 39 | * [Hours To Text](#hours-to-text) 40 | * [Shorten String](#shorten-string) 41 | * [CURL](#curl) 42 | * [Shorten URL](#shorten-url) 43 | * [Get Alexa Rank](#ge-alexa-rank) 44 | * [Get Tiny URL](#get-tiny-url) 45 | * [Get Keyword Suggestions From Google](#get-keyword-suggestions-from-google) 46 | * [WIKI Search](#wiki-search) 47 | * [Notification](#notification) 48 | * [Auto Embed](#auto-embed) 49 | * [Make Clickable Links](#make-clickable-links) 50 | * [🔧 Debug](#debug) 51 | * [Get Referer](#get-referer) 52 | * [Compress Page](#compress-page) 53 | * [Ordinal](#ordinal) 54 | * [Number Of Days In Month](#number-of-days-in-month) 55 | * [pr](#pr) 56 | * [Bytes To Human Readable Size](#bytes-to-human-readable-size) 57 | 58 | 59 | --- 60 | ### Quick Start 61 | Run in your terminal: 62 | ```bash 63 | composer require ngfw/recipe 64 | ``` 65 | Create new file and start using the Recipes 66 | ```php 67 | home depot 80 | // [1] => home goods 81 | // [2] => home depot near me 82 | // [3] => homes for sale 83 | // [4] => homeaway 84 | // [5] => homes for rent 85 | // [6] => home advisor 86 | // [7] => home depot credit card 87 | // [8] => home depot coupons 88 | // [9] => homeland 89 | //) 90 | ``` 91 | ### Favicon 92 | Getting remote website Favicon: 93 | ```php 94 | $favIcon = Recipe::getFavicon("http://youtube.com/"); 95 | 96 | echo $favIcon; 97 | // outputs: 98 | ``` 99 | 100 | 101 | Getting remote website Favicon with HTML attributes: 102 | ```php 103 | $favIcon = Recipe::getFavicon( 104 | "http://youtube.com/", 105 | array( 106 | "class" => "favImg" 107 | ) 108 | ); 109 | echo $favIcon; 110 | //outputs: 111 | 112 | ``` 113 | 114 | 115 | 116 | ### QRcode 117 | Generating QR code 118 | ```php 119 | $QRcode = Recipe::getQRcode("ngfw Recipe"); 120 | echo $QRcode; 121 | //outputs: 122 | ``` 123 | 124 | 125 | Generating QR code and adding HTML attributes: 126 | ```php 127 | $QRcode = Recipe::getQRcode( 128 | "ngfw Recipe", 129 | $width = 350, 130 | $height = 350, 131 | $attributes = array( 132 | "class" => "QRCode" 133 | ) 134 | ); 135 | echo $QRcode; 136 | // outputs: 137 | ``` 138 | 139 | 140 | 141 | ### File extension 142 | ```php 143 | $ext = Recipe::getFileExtension(__FILE__); // replace '__FILE__' with your filename 144 | echo $ext; 145 | //outputs: php 146 | ``` 147 | 148 | ### Gravatar 149 | Getting Gravatar: 150 | ```php 151 | $Gravatar = Recipe::getGravatar("gejadze@gmail.com"); 152 | echo $Gravatar; 153 | // outputs: 154 | ``` 155 | 156 | ![https://www.gravatar.com/avatar.php?gravatar_id=9d9d478c3b65d4046a84cf84b4c8bf46&default=mm&size=80&rating=g](https://www.gravatar.com/avatar.php?gravatar_id=9d9d478c3b65d4046a84cf84b4c8bf46&default=mm&size=80&rating=g) 157 | 158 | Getting Gravatar with HTML attributes: 159 | ```php 160 | $Gravatar = Recipe::getGravatar( 161 | "gejadze@gmail.com", 162 | $size = 200, 163 | $default = 'monsterid', 164 | $rating = 'x', 165 | $attributes = array( 166 | "class" => "Gravatar" 167 | ) 168 | ); 169 | echo $Gravatar; 170 | //Outputs: ' 171 | ``` 172 | ![NG Gravatar](http://www.gravatar.com/avatar.php?gravatar_id=9d9d478c3b65d4046a84cf84b4c8bf46&default=monsterid&size=200&rating=x) 173 | 174 | 175 | 176 | ### Creating Link Tags 177 | Simple Link: 178 | ```php 179 | $linkTags = Recipe::createLinkTag("google.com"); 180 | echo $linkTags; 181 | //outputs: google.com 182 | ``` 183 | 184 | Link with title: 185 | ```php 186 | $linkTags = Recipe::createLinkTag("google.com", "Visit Google"); 187 | echo $linkTags; 188 | //outputs: Visit Google 189 | ``` 190 | 191 | Link with title and HTML attributes: 192 | ```php 193 | $linkTags = Recipe::createLinkTag("google.com", "Visit Google", array( 194 | "class" => "outgoingLink" 195 | )); 196 | echo $linkTags; 197 | //outputs: Visit Google 198 | ``` 199 | 200 | 201 | ### Validate email address 202 | ```php 203 | $isValid = Recipe::validateEmail("user@gmail.com"); 204 | var_dump($isValid); 205 | // outputs: true (bool) 206 | ``` 207 | 208 | Check for temporary Email addresses: 209 | 210 | ```php 211 | $isValid = Recipe::validateEmail('user@fakeinbox.com', $tempEmailAllowed = false); 212 | var_dump($isValid); 213 | // outputs: false (bool) 214 | ``` 215 | 216 | ### Validate URL 217 | ```php 218 | $isValid = Recipe::validateURL("http://github.com/"); 219 | var_dump($isValid); 220 | // outputs: true (bool) 221 | ``` 222 | 223 | ### RSS Reader 224 | ```php 225 | $rssArray = Recipe::rssReader("https://github.com/ngfw/Recipe/commits/master.atom"); 226 | var_dump($rssArray); 227 | // Outputs feed as an array 228 | ``` 229 | 230 | ### Object to Array 231 | ```php 232 | $obj = new stdClass; 233 | $obj->foo = 'bar'; 234 | $obj->baz = 'qux'; 235 | $array = Recipe::objectToArray($obj); 236 | var_dump($array); 237 | 238 | // outputs: 239 | // array(2) { 240 | // ["foo"]=> 241 | // string(3) "bar" 242 | // ["baz"]=> 243 | // string(3) "qux" 244 | // } 245 | 246 | ``` 247 | 248 | ### Array to Object 249 | ```php 250 | $array = array( 251 | "foo" => "bar", 252 | "baz" => "qux", 253 | ); 254 | $obj = Recipe::arrayToObject($array); 255 | // outputs: 256 | // object(stdClass)#15 (2) { 257 | // ["foo"]=> 258 | // string(3) "bar" 259 | // ["baz"]=> 260 | // string(3) "qux" 261 | // } 262 | ``` 263 | ### Array to String 264 | ```php 265 | $array = array( 266 | "foo" => "bar", 267 | "baz" => "qux", 268 | ); 269 | $string = Recipe::arrayToString($array); 270 | echo $string; 271 | // outputs: foo="bar" baz="qux" 272 | ``` 273 | ### HEX to RGB 274 | ```php 275 | $rgb = Recipe::hex2rgb("#FFF"); 276 | echo $rgb; 277 | // outputs: rgb(255, 255, 255) 278 | ``` 279 | ### RGB to HEX 280 | ```php 281 | $hex = Recipe::rgb2hex("rgb(123,123,123)"); 282 | // outputs: #7b7b7b 283 | ``` 284 | ### Color Name to HEX 285 | ```php 286 | $hex = Recipe::colorNameToHex('red'); 287 | // outputs: #FF0000 288 | ``` 289 | ### Generate Random Password 290 | ```php 291 | $randomPass = Recipe::generateRandomPassword(10); 292 | echo $randomPass; 293 | // outputs: 10 random character string 294 | ``` 295 | ### Simple Encode 296 | ```php 297 | $encodedString = Recipe::simpleEncode("php recipe"); 298 | echo $encodedString; 299 | // outputs: qcnVhqjKxpuilw== 300 | ``` 301 | ### Simple Decode 302 | ```php 303 | $decodedString = Recipe::simpleDecode("qcnVhqjKxpuilw=="); 304 | echo $decodedString; 305 | // outputs: php recipe 306 | ``` 307 | ### Generate Server Specific Hash 308 | ```php 309 | $serverHash = Recipe::generateServerSpecificHash(); 310 | echo $serverHash; 311 | // outputs: d41d8cd98f00b204e9800998ecf8427e 312 | ``` 313 | ### Detect HTTPS 314 | This method checks for `$_SERVER['HTTPS']` 315 | ```php 316 | $isHttps = Recipe::isHttps(); 317 | var_dump($isHttps); 318 | // outputs: bool 319 | ``` 320 | ### Detect AJAX 321 | This method checks for `$_SERVER['HTTP_X_REQUESTED_WITH']` 322 | ```php 323 | $isAjax = Recipe::isAjax(); 324 | var_dump($isAjax); 325 | // outputs: bool 326 | ``` 327 | 328 | ### Check if number is odd 329 | ```php 330 | $isNumberOdd = Recipe::isNumberOdd(5); 331 | // outputs: bool 332 | ``` 333 | ### Check if number is even 334 | ```php 335 | $isNumberEven = Recipe::isNumberEven(8); 336 | var_dump($isNumberEven); 337 | // outputs: bool 338 | ``` 339 | ### Get Current URL 340 | ```php 341 | $currentURL = Recipe::getCurrentURL(); 342 | var_dump($currentURL); 343 | // outputs: current Request URL 344 | ``` 345 | ### Get Client IP 346 | ```php 347 | $ClientsIP = Recipe::getClientIP(); 348 | echo $ClientsIP; 349 | //OR 350 | // Return Proxy IP if user is behind it 351 | //$ClientsIP = Recipe::getClientIP("HTTP_CLIENT_IP"); //'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED', ... 352 | // outputs: IP address 353 | ``` 354 | ### Detect Mobile 355 | ```php 356 | $isMobile = Recipe::isMobile(); 357 | var_dump($isMobile); 358 | // outputs: true or false 359 | ``` 360 | ### Get Browser 361 | ```php 362 | $Browser = Recipe::getBrowser(); 363 | echo $Browser 364 | // outputs: Browser Details 365 | ``` 366 | ### Get Client Location 367 | ```php 368 | $user_location = Recipe::getClientLocation(); 369 | echo $user_location; 370 | // outputs: Users Location 371 | ``` 372 | ### Number To Word conversion 373 | ```php 374 | $number = "864210"; 375 | $number_in_words = Recipe::numberToWord($number); 376 | echo $number_in_words; 377 | // outputs: eight hundred and sixty-four thousand, two hundred and ten 378 | ``` 379 | ### Seconds To Text 380 | ```php 381 | $seconds = "864210"; 382 | $number_in_words = Recipe::secondsToText($seconds); 383 | echo $number_in_words; 384 | // outputs: 1 hour and 10 seconds 385 | // Recipe::secondsToText($seconds, $returnAsWords = true); 386 | // will return: one hour and ten seconds 387 | ``` 388 | ### Minutes To Text 389 | ```php 390 | $minutes = 60 * 24 * 2; 391 | $duration = Recipe::minutesToText($minutes); 392 | echo $duration; 393 | // outputs: 2 days 394 | // Recipe::minutesToText($minutes, $returnAsWords = true); 395 | // will return: two days 396 | ``` 397 | ### Hours To Text 398 | ```php 399 | $hours = 4.2; 400 | $duration = Recipe::hoursToText($hours); 401 | echo $duration; 402 | // outputs: 4 hours and 12 minutes 403 | // Recipe::hoursToText($hours, $returnAsWords = true); 404 | // will return: four hours and twelve minutes 405 | ``` 406 | ### Shorten String 407 | ```php 408 | $string = "The quick brown fox jumps over the lazy dog"; 409 | $shortenString = Recipe::shortenString($string, 20); 410 | // output: The quick brown f... 411 | // Recipe::shortenString($string, 20, $addEllipsis = false); 412 | // output: "The quick brown fox ", NOTE last space 413 | // Recipe::shortenString($string, 20, $addEllipsis = false, $wordsafe = true); 414 | // output: "The quick brown fox", NOTE, will not break in the middle of the word 415 | ``` 416 | ### CURL 417 | 418 | Simple GET example: 419 | ```php 420 | $data = Recipe::curl("https://api.ipify.org"); 421 | var_dump($data); 422 | // outputs: Curl'ed Data 423 | ``` 424 | POST Example: 425 | ```php 426 | $CurlPOST = Recipe::curl("http://jsonplaceholder.typicode.com/posts", $method = "POST", $data = array( 427 | "title" => 'foo', 428 | "body" => 'bar', 429 | "userId" => 1, 430 | )); 431 | ``` 432 | Custom Headers: 433 | ```php 434 | $curlWithHeaders = Recipe::curl("http://jsonplaceholder.typicode.com/posts", $method = "GET", $data = false, $header = array( 435 | "Accept" => "application/json", 436 | ), $returnInfo = true); 437 | // NOTE $returnInfo argument 438 | // Result will be returned as an array, $curlWithHeaders={ 439 | // info => containing curl information, see curl_getinfo() 440 | // contents => Data from URL 441 | //} 442 | ``` 443 | Basic authentication with CURL: 444 | ```php 445 | $curlBasicAuth = Recipe::curl( 446 | "http://jsonplaceholder.typicode.com/posts", 447 | $method = "GET", 448 | $data = false, 449 | $header = false, 450 | $returnInfo = false, 451 | $auth = array( 452 | 'username' => 'your_login', 453 | 'password' => 'your_password', 454 | ) 455 | ); 456 | ``` 457 | ### Expand Short URL 458 | ```php 459 | $shortURL = "https://goo.gl/rvDnMX"; 460 | $expandedURL = Recipe::expandShortUrl($shortURL); 461 | echo $expendedURL; 462 | // outputs: https://github.com/ngfw/Recipe 463 | ``` 464 | ### Get Alexa Rank 465 | ```php 466 | $AlexaRank = Recipe::getAlexaRank("github.com"); 467 | echo $AlexaRank; 468 | // outputs: Current alexa ranking as position number (example: 52) 469 | ``` 470 | 471 | ### Shorten URL 472 | ```php 473 | $TinyUrl = Recipe::getTinyUrl("https://github.com/ngfw/Recipe"); 474 | echo $TinyUrl; 475 | // outputs: http://tinyurl.com/h2nchjh 476 | ``` 477 | ### Get Keyword Suggestions From Google 478 | ```php 479 | $suggestions = Recipe::getKeywordSuggestionsFromGoogle("Tbilisi, Georgia"); 480 | var_dump($suggestions); 481 | // outputs: 482 | //array(10) { 483 | // [0]=> 484 | // string(15) "tbilisi georgia" 485 | // [1]=> 486 | // string(22) "tbilisi georgia hotels" 487 | // [2]=> 488 | // string(19) "tbilisi georgia map" 489 | // [3]=> 490 | // string(20) "tbilisi georgia time" 491 | // [4]=> 492 | // string(23) "tbilisi georgia airport" 493 | // [5]=> 494 | // string(23) "tbilisi georgia weather" 495 | // [6]=> 496 | // string(24) "tbilisi georgia language" 497 | // [7]=> 498 | // string(24) "tbilisi georgia zip code" 499 | // [8]=> 500 | // string(20) "tbilisi georgia news" 501 | // [9]=> 502 | // string(28) "tbilisi georgia airport code" 503 | //} 504 | ``` 505 | ### WIKI Search 506 | ```php 507 | $wiki = Recipe::wikiSearch("Tbilisi"); 508 | var_dump($wiki); 509 | // outputs: data from wikipedia 510 | ``` 511 | ### Notification 512 | ```php 513 | $notification = Recipe::notification("Test Successful"); 514 | echo $notification; 515 | // outputs:
Test Successful
516 | // NOTE: possible notifications types: success, warning, error and info 517 | // Type is passed as a second parameter 518 | ``` 519 | ### Auto Embed 520 | ```php 521 | $string = "Checkout Solomun, Boiler Room at https://www.youtube.com/watch?v=bk6Xst6euQk"; 522 | echo Recipe::autoEmbed($string); 523 | // outputs: 524 | // Checkout Solomun, Boiler Room at 525 | // supported providers are: youtube.com, blip.tv, vimeo.com, dailymotion.com, flickr.com, smugmug.com, hulu.com, revision3.com, wordpress.tv, funnyordie.com, soundcloud.com, slideshare.net and instagram.com 526 | ``` 527 | ### Make Clickable Links 528 | ```php 529 | $string = "Check PHP Recipes on https://github.com/ngfw/Recipe"; 530 | $clickable = Recipe::makeClickableLinks($string); 531 | echo $clickable; 532 | // outputs: 533 | // Check PHP Recipes on https://github.com/ngfw/Recipe 534 | ``` 535 | ### Debug 536 | `var_dump()` alternative 537 | ```php 538 | $string = "Test me"; 539 | Recipe::debug($string); 540 | ``` 541 | 542 | 543 | ### Get Referer 544 | Get the referer page (last page visited) 545 | ```php 546 | $referrer = Recipe::getReferer(); 547 | echo $referer ; 548 | // outputs an url (http://mywebsite.com/page1) 549 | ``` 550 | 551 | 552 | ### Ordinal 553 | ```php 554 | for($i=1;$i<=10;$i++){ 555 | echo Recipe::ordinal($i); 556 | echo ' '; 557 | } 558 | // outputs 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 559 | 560 | ``` 561 | 562 | ### Number Of Days In Month 563 | ```php 564 | $numDays = Recipe::numberOfDaysInMonth(2, 2012); 565 | echo $numDays; 566 | // outputs: 29 567 | ``` 568 | 569 | ### Compress Page 570 | The `compressPage()` method will register new function on PHP shutdown, remove white space from output and try to gZip it. 571 | 572 | ```php 573 | 577 | 578 | 579 | 580 | 581 | 582 | HTML Page Title 583 | 584 | 585 | 586 | 587 | 588 | 589 | Hello Friend, 590 | 591 | 592 | ``` 593 | 594 | will output: 595 | ```html 596 | HTML Page Title Hello Friend, 597 | ``` 598 | 599 | ### PR 600 | ```php 601 | Recipe::pr( array("he","ll","oo") ); 602 | ``` 603 | will output: 604 | ```html 605 |
Array
606 | (    
607 |     [0] => he
608 |     [1] => ll
609 |     [2] => oo
610 | )
611 | 
612 | ``` 613 | 614 | 615 | ### Bytes To Human Readable Size 616 | ```php 617 | Recipe::bytesToHumanReadableSize( "17179869184" ); 618 | ``` 619 | will output: 620 | ```html 621 | 16 GB 622 | ``` 623 | -------------------------------------------------------------------------------- /tests/RecipeTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(get_class(new Recipe()), $r); 11 | } 12 | 13 | /** 14 | * GetFavicon tests. 15 | * 16 | * @param string $url 17 | * @param string $expectedUrl 18 | * @dataProvider dp_getFavicon 19 | */ 20 | public function test_getFavicon($url, $expectedUrl) 21 | { 22 | $favIcon = Recipe::getFavicon($url); 23 | $this->assertEquals( 24 | '', 25 | $favIcon 26 | ); 27 | } 28 | 29 | public function test_getFavicon_with_attributes() 30 | { 31 | $favIcon = Recipe::getFavicon('http://youtube.com/', [ 32 | 'class' => 'favImg', 33 | ]); 34 | $this->assertEquals( 35 | '', 36 | $favIcon 37 | ); 38 | } 39 | 40 | /** 41 | * Get QRcode Tests. 42 | */ 43 | public function test_getQRcode() 44 | { 45 | $QRcode = Recipe::getQRcode('ngfw Recipe'); 46 | $this->assertEquals( 47 | '', 48 | $QRcode 49 | ); 50 | } 51 | 52 | public function test_getQRcode_with_attributes() 53 | { 54 | $QRcode = Recipe::getQRcode( 55 | 'ngfw Recipe', 56 | $width = 350, 57 | $height = 350, 58 | $attributes = [ 59 | 'class' => 'QRCode', 60 | ] 61 | ); 62 | $this->assertEquals( 63 | '', 64 | $QRcode 65 | ); 66 | } 67 | 68 | /** 69 | * Get FileExtension Test. 70 | */ 71 | public function test_getFileExtension() 72 | { 73 | $ext = Recipe::getFileExtension(__FILE__); 74 | $this->assertEquals( 75 | 'php', 76 | $ext 77 | ); 78 | } 79 | 80 | /** 81 | * Get Gravatar Tests. 82 | */ 83 | public function test_getGravatar() 84 | { 85 | $Gravatar = Recipe::getGravatar('gejadze@gmail.com'); 86 | $this->assertEquals( 87 | '', 88 | $Gravatar 89 | ); 90 | } 91 | 92 | public function test_getGravatar_with_attributes() 93 | { 94 | $Gravatar = Recipe::getGravatar( 95 | 'gejadze@gmail.com', 96 | $size = 200, 97 | $default = 'monsterid', 98 | $rating = 'x', 99 | $attributes = [ 100 | 'class' => 'Gravatar', 101 | ] 102 | ); 103 | $this->assertEquals( 104 | '', 105 | $Gravatar 106 | ); 107 | } 108 | 109 | /** 110 | * Link tags. 111 | */ 112 | public function test_createLinkTag() 113 | { 114 | $linkTags = Recipe::createLinkTag('google.com'); 115 | $this->assertEquals( 116 | 'google.com', 117 | $linkTags 118 | ); 119 | } 120 | 121 | public function test_createLinkTag_with_title() 122 | { 123 | $linkTags = Recipe::createLinkTag('google.com', 'Visit Google'); 124 | $this->assertEquals( 125 | 'Visit Google', 126 | $linkTags 127 | ); 128 | } 129 | 130 | public function test_createLinkTag_with_title_and_attribute() 131 | { 132 | $linkTags = Recipe::createLinkTag('google.com', 'Visit Google', [ 133 | 'class' => 'outgoingLink', 134 | ]); 135 | $this->assertEquals( 136 | 'Visit Google', 137 | $linkTags 138 | ); 139 | } 140 | 141 | /** 142 | * Email validation. 143 | */ 144 | public function test_validateEmail_success() 145 | { 146 | $isValid = Recipe::validateEmail('user@gmail.com'); 147 | $this->assertTrue($isValid); 148 | 149 | $isValid = Recipe::validateEmail('user@fakemail.fr', $tempEmailAllowed = true); 150 | $this->assertTrue($isValid); 151 | } 152 | 153 | public function test_validateEmail_fail() 154 | { 155 | $isValid = Recipe::validateEmail('user@domain'); 156 | $this->assertFalse($isValid); 157 | 158 | $isValid = Recipe::validateEmail('user@veryLongAndNotExistingDomainName132435.com'); 159 | $this->assertFalse($isValid); 160 | 161 | $isValid = Recipe::validateEmail('user@fakeinbox.com', $tempEmailAllowed = false); 162 | $this->assertFalse($isValid); 163 | } 164 | 165 | /** 166 | * URL validation. 167 | */ 168 | public function test_validateURL_success() 169 | { 170 | $isValid = Recipe::validateURL('http://github.com/'); 171 | $this->assertTrue($isValid); 172 | } 173 | 174 | public function test_validateURL_fail() 175 | { 176 | $isValid = Recipe::validateURL('http://github com/'); 177 | $this->assertFalse($isValid); 178 | } 179 | 180 | /** 181 | * RSS Reader. 182 | */ 183 | public function test_rssReader() 184 | { 185 | $rssArray = Recipe::rssReader('https://github.com/ngfw/Recipe/commits/master.atom'); 186 | $this->assertInternalType('array', $rssArray); 187 | } 188 | 189 | /** 190 | * Object to array conversion. 191 | */ 192 | public function test_objectToArray() 193 | { 194 | $obj = new stdClass(); 195 | $obj->foo = 'bar'; 196 | $obj->baz = 'qux'; 197 | $array = Recipe::objectToArray($obj); 198 | $this->assertInternalType('array', $array); 199 | } 200 | 201 | public function test_arrayToObject() 202 | { 203 | $array = [ 204 | 'foo' => 'bar', 205 | 'baz' => 'qux', 206 | ]; 207 | $obj = Recipe::arrayToObject($array); 208 | $this->assertInternalType('object', $obj); 209 | } 210 | 211 | public function test_arrayToString() 212 | { 213 | $array = [ 214 | 'foo' => 'bar', 215 | 'baz' => 'qux', 216 | ]; 217 | $string = Recipe::arrayToString($array); 218 | $this->assertEquals( 219 | 'foo="bar" baz="qux"', 220 | $string 221 | ); 222 | } 223 | 224 | /** 225 | * Colors. 226 | */ 227 | public function test_hex2rgb() 228 | { 229 | $rgb = Recipe::hex2rgb('#FFF'); 230 | $this->assertEquals( 231 | 'rgb(255, 255, 255)', 232 | $rgb 233 | ); 234 | } 235 | 236 | public function test_rgb2hex() 237 | { 238 | $hex = Recipe::rgb2hex('rgb(123,123,123)'); 239 | $this->assertEquals( 240 | '#7b7b7b', 241 | $hex 242 | ); 243 | } 244 | 245 | /** 246 | * Test. 247 | */ 248 | public function test_generateRandomPassword() 249 | { 250 | $randomPass = Recipe::generateRandomPassword(10); 251 | $this->assertTrue(strlen($randomPass) === 10); 252 | } 253 | 254 | /** 255 | * Encode / Decode. 256 | */ 257 | public function test_simpleEncode() 258 | { 259 | $encodedString = Recipe::simpleEncode('php recipe'); 260 | $this->assertEquals( 261 | 'qcnVhqjKxpuilw==', 262 | $encodedString 263 | ); 264 | } 265 | 266 | public function test_simpleDecode() 267 | { 268 | $decodedString = Recipe::simpleDecode('qcnVhqjKxpuilw=='); 269 | $this->assertEquals( 270 | 'php recipe', 271 | $decodedString 272 | ); 273 | } 274 | 275 | public function test_generateServerSpecificHash() 276 | { 277 | $serverHash = Recipe::generateServerSpecificHash(); 278 | $this->assertEquals( 279 | 32, 280 | strlen($serverHash) 281 | ); 282 | } 283 | 284 | /** 285 | * Check if request is on https. 286 | * 287 | * @return [type] [description] 288 | */ 289 | public function test_isHttps() 290 | { 291 | $_SERVER['HTTPS'] = true; 292 | $isHttps = Recipe::isHttps(); 293 | $this->assertTrue($isHttps); 294 | } 295 | 296 | public function test_isAjax() 297 | { 298 | $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest'; 299 | $isAjax = Recipe::isAjax(); 300 | $this->assertTrue($isAjax); 301 | } 302 | 303 | /** 304 | * Numbers. 305 | */ 306 | public function test_isNumberOdd() 307 | { 308 | $number = 5; 309 | $isNumberOdd = Recipe::isNumberOdd($number); 310 | $this->assertTrue($isNumberOdd); 311 | } 312 | 313 | public function test_isNumberEven() 314 | { 315 | $number = 8; 316 | $isNumberEven = Recipe::isNumberEven($number); 317 | $this->assertTrue($isNumberEven); 318 | } 319 | 320 | /** 321 | * Current URL. 322 | */ 323 | public function test_getCurrentURL() 324 | { 325 | $_SERVER['REQUEST_URI'] = 'example.com'; 326 | $currentURL = Recipe::getCurrentURL(); 327 | $this->assertEquals( 328 | 'http://example.com', 329 | $currentURL 330 | ); 331 | } 332 | 333 | /** 334 | * Get Client IP address. 335 | */ 336 | public function test_getClientIP() 337 | { 338 | $_SERVER['REMOTE_ADDR'] = '8.8.8.8'; 339 | $ip = Recipe::getClientIP(); 340 | $this->assertEquals( 341 | '8.8.8.8', 342 | $ip 343 | ); 344 | } 345 | 346 | /** 347 | * Test mobile device. 348 | */ 349 | public function test_isMobile() 350 | { 351 | $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7'; 352 | $isMobile = Recipe::isMobile(); 353 | $this->assertTrue($isMobile); 354 | } 355 | 356 | /** 357 | * Detect user browser. 358 | */ 359 | public function test_getBrowser() 360 | { 361 | $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7'; 362 | $browser = Recipe::getBrowser(); 363 | $this->assertInternalType('string', $browser); 364 | } 365 | 366 | /** 367 | * Get Clients Location. 368 | */ 369 | public function test_getClientLocation() 370 | { 371 | $_SERVER['REMOTE_ADDR'] = '8.8.8.8'; // let's see where is google 372 | $location = Recipe::getClientLocation(); 373 | $this->assertInternalType('string', $location); 374 | } 375 | 376 | /** 377 | * Convert number to word. 378 | */ 379 | public function test_numberToWord() 380 | { 381 | $number = '864210'; 382 | $word = Recipe::numberToWord($number); 383 | $this->assertEquals( 384 | 'eight hundred and sixty-four thousand, two hundred and ten', 385 | $word 386 | ); 387 | } 388 | 389 | /** 390 | * Convert number of seconds to time. 391 | */ 392 | public function test_secondsToText() 393 | { 394 | $seconds = 3610; 395 | $duration = Recipe::secondsToText($seconds); 396 | $this->assertEquals( 397 | '1 hour and 10 seconds', 398 | $duration 399 | ); 400 | $duration = Recipe::secondsToText($seconds, $returnAsWords = true); 401 | $this->assertEquals( 402 | 'one hour and ten seconds', 403 | $duration 404 | ); 405 | } 406 | 407 | /** 408 | * Convert number of minutes to time. 409 | */ 410 | public function test_minutesToText() 411 | { 412 | $minutes = 60 * 24 * 2; 413 | $duration = Recipe::minutesToText($minutes); 414 | $this->assertEquals( 415 | '2 days', 416 | $duration 417 | ); 418 | $duration = Recipe::minutesToText($minutes, $returnAsWords = true); 419 | $this->assertEquals( 420 | 'two days', 421 | $duration 422 | ); 423 | } 424 | 425 | /** 426 | * Convert hours to text. 427 | */ 428 | public function test_hoursToText() 429 | { 430 | $hours = 4.2; 431 | $duration = Recipe::hoursToText($hours); 432 | $this->assertEquals( 433 | '4 hours and 12 minutes', 434 | $duration 435 | ); 436 | $duration = Recipe::hoursToText($hours, $returnAsWords = true); 437 | $this->assertEquals( 438 | 'four hours and twelve minutes', 439 | $duration 440 | ); 441 | } 442 | 443 | /** 444 | * Shorten the string. 445 | */ 446 | public function test_shortenString() 447 | { 448 | $string = 'The quick brown fox jumps over the lazy dog'; 449 | $shortenString = Recipe::shortenString($string, 20); 450 | $this->assertEquals( 451 | 'The quick brown f...', 452 | $shortenString 453 | ); 454 | 455 | $shortenString = Recipe::shortenString($string, 20, $addEllipsis = false); 456 | $this->assertEquals( 457 | 'The quick brown fox ', 458 | $shortenString 459 | ); 460 | 461 | $shortenString = Recipe::shortenString($string, 20, $addEllipsis = false, $wordsafe = true); 462 | $this->assertEquals( 463 | 'The quick brown fox', 464 | $shortenString 465 | ); 466 | } 467 | 468 | /** 469 | * Curl. 470 | */ 471 | public function test_curl() 472 | { 473 | //ipify does not like Travis 474 | // $ipCheck = false; 475 | // $testCurl = Recipe::curl('https://api.ipify.org'); 476 | // if (filter_var($testCurl, FILTER_VALIDATE_IP)) { 477 | // $ipCheck = true; 478 | // } 479 | // $this->assertTrue($ipCheck); 480 | 481 | $testCurlPOST = Recipe::curl('http://jsonplaceholder.typicode.com/posts', $method = 'POST', $data = [ 482 | 'title' => 'foo', 483 | 'body' => 'bar', 484 | 'userId' => 1, 485 | ]); 486 | $POST_obj = json_decode($testCurlPOST); 487 | $this->assertInternalType('object', $POST_obj); 488 | 489 | $testCurlHeaderAndReturnInfo = Recipe::curl('http://jsonplaceholder.typicode.com/posts', $method = 'GET', $data = false, $header = [ 490 | 'Accept' => 'application/json', 491 | ], $returnInfo = true); 492 | $this->assertInternalType('array', $testCurlHeaderAndReturnInfo); 493 | $this->assertInternalType('array', $testCurlHeaderAndReturnInfo['info']); 494 | $this->assertInternalType('string', $testCurlHeaderAndReturnInfo['contents']); 495 | } 496 | 497 | /** 498 | * Expend shortened URLs. 499 | */ 500 | public function test_expandShortUrl() 501 | { 502 | $expandedURL = Recipe::expandShortUrl('https://goo.gl/rvDnMX'); 503 | $this->assertEquals( 504 | 'https://github.com/ngfw/Recipe', 505 | $expandedURL 506 | ); 507 | } 508 | 509 | /** 510 | * get Alexa Ranking. 511 | */ 512 | public function test_getAlexaRank() 513 | { 514 | $AlexaRank = Recipe::getAlexaRank('github.com'); 515 | $this->assertInternalType('int', $AlexaRank); 516 | } 517 | 518 | /** 519 | * Shorten the URL. 520 | */ 521 | public function test_getTinyUrl() 522 | { 523 | $TinyUrl = Recipe::getTinyUrl('https://github.com/ngfw/Recipe'); 524 | $this->assertEquals( 525 | 'http://tinyurl.com/h2nchjh', 526 | $TinyUrl 527 | ); 528 | } 529 | 530 | /** 531 | * Get google keyword suggestions. 532 | */ 533 | public function test_getKeywordSuggestionsFromGoogle() 534 | { 535 | $suggestions = Recipe::getKeywordSuggestionsFromGoogle('Tbilisi, Georgia'); 536 | $this->assertInternalType('array', $suggestions); 537 | $this->assertEquals( 538 | 10, 539 | count($suggestions) 540 | ); 541 | } 542 | 543 | /** 544 | * Wikipedia search. 545 | */ 546 | public function test_wikiSearch() 547 | { 548 | $wiki = Recipe::wikiSearch('Tbilisi'); 549 | $this->assertInternalType('array', $wiki); 550 | $this->assertInternalType('string', $wiki['title']); 551 | } 552 | 553 | /** 554 | * Create HTML notifications. 555 | */ 556 | public function test_notification() 557 | { 558 | $notification = Recipe::notification('Test Successful'); 559 | $this->assertEquals( 560 | '
Test Successful
', 561 | $notification 562 | ); 563 | } 564 | 565 | /** 566 | * Auto Embed. 567 | */ 568 | public function test_autoEmbed() 569 | { 570 | $string = 'Checkout Solomun, Boiler Room at https://www.youtube.com/watch?v=bk6Xst6euQk'; 571 | $converted = Recipe::autoEmbed($string); 572 | $this->assertEquals( 573 | 'Checkout Solomun, Boiler Room at', 574 | $converted 575 | ); 576 | } 577 | 578 | /** 579 | * Make links clickable. 580 | */ 581 | public function test_makeClickableLinks() 582 | { 583 | $string = 'Check PHP Recipes on https://github.com/ngfw/Recipe'; 584 | $clickable = Recipe::makeClickableLinks($string); 585 | 586 | $this->assertEquals( 587 | 'Check PHP Recipes on https://github.com/ngfw/Recipe', 588 | $clickable 589 | ); 590 | } 591 | 592 | /** 593 | * Custom Debug. 594 | */ 595 | public function test_debug() 596 | { 597 | $string = 'Test me'; 598 | ob_start(); 599 | Recipe::debug($string); 600 | $debug = ob_get_clean(); 601 | $this->assertInternalType('string', $debug); 602 | } 603 | 604 | public function test_getReferer() 605 | { 606 | $_SERVER['HTTP_REFERER'] = 'example.com'; 607 | $Referer = Recipe::getReferer(); 608 | $this->assertEquals( 609 | 'example.com', 610 | $Referer 611 | ); 612 | } 613 | 614 | public function test_compressPage() 615 | { 616 | // man, testing this will be painful.. 617 | // Just trust me, it works, ROFL 618 | } 619 | 620 | public function test_ordinal() 621 | { 622 | $ordinal = Recipe::ordinal(2); 623 | $this->assertEquals($ordinal, '2nd'); 624 | } 625 | 626 | public function test_numberOfDaysInMonth() 627 | { 628 | $numDaysFeb = 29; 629 | $numDays = Recipe::numberOfDaysInMonth(2, 2016); 630 | 631 | $this->assertEquals($numDaysFeb, $numDays); 632 | } 633 | 634 | public function test_pr() 635 | { 636 | $this->expectOutputString("
Array\n(\n    [0] => he\n    [1] => ll\n    [2] => oo\n)\n
"); 637 | Recipe::pr(['he', 'll', 'oo']); 638 | } 639 | 640 | public function test_bytesToHumanReadableSize() 641 | { 642 | $HumanReadable = Recipe::bytesToHumanReadableSize('17179869184'); 643 | $this->assertEquals($HumanReadable, '16 GB'); 644 | } 645 | 646 | /** 647 | * @return array 648 | */ 649 | public function dp_getFavicon() 650 | { 651 | return [ 652 | [ 653 | 'http://youtube.com/', 654 | 'http%3A%2F%2Fyoutube.com%2F', 655 | ], 656 | [ 657 | 'http.net', 658 | 'http.net', 659 | ], 660 | [ 661 | 'http://youtube.com/test', 662 | 'http%3A%2F%2Fyoutube.com%2Ftest', 663 | ], 664 | ]; 665 | } 666 | 667 | public function text_colorNameToHex() 668 | { 669 | $colorHex = Recipe::colorNameToHex('red'); 670 | $this->assertEquals($colorHex, '#FF0000'); 671 | } 672 | } 673 | // EOF 674 | -------------------------------------------------------------------------------- /src/ngfw/Recipe.php: -------------------------------------------------------------------------------- 1 | ', 25 | urlencode($url), 26 | $attr 27 | ); 28 | } 29 | 30 | /** 31 | * Get a QR code. 32 | * 33 | * @param string $string String to generate QR code for. 34 | * @param int $width QR code width 35 | * @param int $height QR code height 36 | * @param array $attributes Optional, additional key/value attributes to include in the IMG tag 37 | * 38 | * @return string containing complete image tag 39 | */ 40 | public static function getQRcode($string, $width = 150, $height = 150, $attributes = []) 41 | { 42 | $protocol = 'http://'; 43 | if (self::isHttps()) { 44 | $protocol = 'https://'; 45 | } 46 | 47 | $attr = trim(self::arrayToString($attributes)); 48 | $apiUrl = $protocol.'chart.apis.google.com/chart?chs='.$width.'x'.$height.'&cht=qr&chl='.urlencode($string); 49 | 50 | return ''; 51 | } 52 | 53 | /** 54 | * Get file extension. 55 | * 56 | * @param string $filename File path 57 | * 58 | * @return string file extension 59 | */ 60 | public static function getFileExtension($filename) 61 | { 62 | return pathinfo($filename, PATHINFO_EXTENSION); 63 | } 64 | 65 | /** 66 | * Get a Gravatar for email. 67 | * 68 | * @param string $email The email address 69 | * @param int $size Size in pixels, defaults to 80 (in px), available values from 1 to 2048 70 | * @param string $default Default imageset to use, available values: 404, mm, identicon, monsterid, wavatar 71 | * @param string $rating Maximum rating (inclusive), available values: g, pg, r, x 72 | * @param array $attributes Optional, additional key/value attributes to include in the IMG tag 73 | * 74 | * @return string containing complete image tag 75 | */ 76 | public static function getGravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = []) 77 | { 78 | $attr = trim(self::arrayToString($attributes)); 79 | 80 | $url = 'https://www.gravatar.com/'; 81 | 82 | return sprintf( 83 | '', 84 | $url, 85 | md5(strtolower(trim($email))), 86 | $default, 87 | $size, 88 | $rating, 89 | $size, 90 | $size, 91 | $attr 92 | ); 93 | } 94 | 95 | /** 96 | * Create HTML A Tag. 97 | * 98 | * @param string $link URL or Email address 99 | * @param string $text Optional, If link text is empty, $link variable value will be used by default 100 | * @param array $attributes Optional, additional key/value attributes to include in the IMG tag 101 | * 102 | * @return string containing complete a tag 103 | */ 104 | public static function createLinkTag($link, $text = '', $attributes = []) 105 | { 106 | $linkTag = ''.htmlspecialchars($text, ENT_QUOTES, 'UTF-8').''; 122 | 123 | return $linkTag; 124 | } 125 | 126 | /** 127 | * Validate Email address. 128 | * 129 | * @param string $address Email address to validate 130 | * @param bool $tempEmailAllowed Allow Temporary email addresses? 131 | * 132 | * @return bool True if email address is valid, false is returned otherwise 133 | */ 134 | public static function validateEmail($address, $tempEmailAllowed = true) 135 | { 136 | strpos($address, '@') ? list(, $mailDomain) = explode('@', $address) : $mailDomain = null; 137 | if (filter_var($address, FILTER_VALIDATE_EMAIL) && 138 | !is_null($mailDomain) && 139 | checkdnsrr($mailDomain, 'MX') 140 | ) { 141 | if ($tempEmailAllowed) { 142 | return true; 143 | } else { 144 | $handle = fopen(__DIR__.'/banned.txt', 'r'); 145 | $temp = []; 146 | while (($line = fgets($handle)) !== false) { 147 | $temp[] = trim($line); 148 | } 149 | if (in_array($mailDomain, $temp)) { 150 | return false; 151 | } 152 | 153 | return true; 154 | } 155 | } 156 | 157 | return false; 158 | } 159 | 160 | /** 161 | * Validate URL. 162 | * 163 | * @param string $url Website URL 164 | * 165 | * @return bool True if URL is valid, false is returned otherwise 166 | */ 167 | public static function validateURL($url) 168 | { 169 | return (bool) filter_var($url, FILTER_VALIDATE_URL); 170 | } 171 | 172 | /** 173 | * Read RSS feed as array. 174 | * requires simplexml. 175 | * 176 | * @see http://php.net/manual/en/simplexml.installation.php 177 | * 178 | * @param string $url RSS feed URL 179 | * 180 | * @return array Representation of XML feed 181 | */ 182 | public static function rssReader($url) 183 | { 184 | if (strpos($url, 'http') !== 0) { 185 | $url = 'http://'.$url; 186 | } 187 | 188 | $feed = self::curl($url); 189 | $xml = simplexml_load_string($feed, 'SimpleXMLElement', LIBXML_NOCDATA); 190 | 191 | return self::objectToArray($xml); 192 | } 193 | 194 | /** 195 | * Convert object to the array. 196 | * 197 | * @param object $object PHP object 198 | * 199 | * @throws \Exception 200 | * 201 | * @return array 202 | */ 203 | public static function objectToArray($object) 204 | { 205 | if (is_object($object)) { 206 | return json_decode(json_encode($object), true); 207 | } else { 208 | throw new \Exception('Not an object'); 209 | } 210 | } 211 | 212 | /** 213 | * Convert array to the object. 214 | * 215 | * @param array $array PHP array 216 | * 217 | * @throws \Exception 218 | * 219 | * @return object 220 | */ 221 | public static function arrayToObject(array $array = []) 222 | { 223 | if (!is_array($array)) { 224 | throw new \Exception('Not an array'); 225 | } 226 | 227 | $object = new \stdClass(); 228 | if (is_array($array) && count($array) > 0) { 229 | foreach ($array as $name => $value) { 230 | if (is_array($value)) { 231 | $object->{$name} = self::arrayToObject($value); 232 | } else { 233 | $object->{$name} = $value; 234 | } 235 | } 236 | } 237 | 238 | return $object; 239 | } 240 | 241 | /** 242 | * Convert Array to string. 243 | * 244 | * @param array $array array to convert to string 245 | * @param string $delimiter 246 | * 247 | * @throws \Exception 248 | * 249 | * @return string ="value1" ="value2" 250 | */ 251 | public static function arrayToString(array $array = [], $delimiter = ' ') 252 | { 253 | $pairs = []; 254 | foreach ($array as $key => $value) { 255 | $pairs[] = "$key=\"$value\""; 256 | } 257 | 258 | return implode($delimiter, $pairs); 259 | } 260 | 261 | /** 262 | * Takes HEX color code value and converts to a RGB value. 263 | * 264 | * @param string $color Color hex value, example: #000000, #000 or 000000, 000 265 | * 266 | * @return string color rbd value 267 | */ 268 | public static function hex2rgb($color) 269 | { 270 | $color = str_replace('#', '', $color); 271 | 272 | $hex = strlen($color) == 3 273 | ? [$color[0].$color[0], $color[1].$color[1], $color[2].$color[2]] 274 | : [$color[0].$color[1], $color[2].$color[3], $color[4].$color[5]]; 275 | 276 | list($r, $g, $b) = $hex; 277 | 278 | return sprintf( 279 | 'rgb(%s, %s, %s)', 280 | hexdec($r), 281 | hexdec($g), 282 | hexdec($b) 283 | ); 284 | } 285 | 286 | /** 287 | * Takes RGB color value and converts to a HEX color code 288 | * Could be used as Recipe::rgb2hex("rgb(0,0,0)") or Recipe::rgb2hex(0,0,0). 289 | * 290 | * @param mixed $r Full rgb,rgba string or red color segment 291 | * @param mixed $g null or green color segment 292 | * @param mixed $b null or blue color segment 293 | * 294 | * @return string hex color value 295 | */ 296 | public static function rgb2hex($r, $g = null, $b = null) 297 | { 298 | if (strpos($r, 'rgb') !== false || strpos($r, 'rgba') !== false) { 299 | if (preg_match_all('/\(([^\)]*)\)/', $r, $matches) && isset($matches[1][0])) { 300 | list($r, $g, $b) = explode(',', $matches[1][0]); 301 | } else { 302 | return false; 303 | } 304 | } 305 | 306 | $result = ''; 307 | foreach ([$r, $g, $b] as $c) { 308 | $hex = base_convert($c, 10, 16); 309 | $result .= ($c < 16) ? ('0'.$hex) : $hex; 310 | } 311 | 312 | return '#'.$result; 313 | } 314 | 315 | /** 316 | * Convert Color name to Hex. 317 | * 318 | * @param $color_name Name of the color, example: red 319 | * 320 | * @return string Color hex or color name 321 | */ 322 | public static function colorNameToHex($color_name) 323 | { 324 | $colors = ['aliceblue' => 'F0F8FF', 'antiquewhite' => 'FAEBD7', 'aqua' => '00FFFF', 'aquamarine' => '7FFFD4', 'azure' => 'F0FFFF', 'beige' => 'F5F5DC', 'bisque' => 'FFE4C4', 'black' => '000000', 'blanchedalmond ' => 'FFEBCD', 'blue' => '0000FF', 'blueviolet' => '8A2BE2', 'brown' => 'A52A2A', 'burlywood' => 'DEB887', 'cadetblue' => '5F9EA0', 'chartreuse' => '7FFF00', 'chocolate' => 'D2691E', 'coral' => 'FF7F50', 'cornflowerblue' => '6495ED', 'cornsilk' => 'FFF8DC', 'crimson' => 'DC143C', 'cyan' => '00FFFF', 'darkblue' => '00008B', 'darkcyan' => '008B8B', 'darkgoldenrod' => 'B8860B', 'darkgray' => 'A9A9A9', 'darkgreen' => '006400', 'darkgrey' => 'A9A9A9', 'darkkhaki' => 'BDB76B', 'darkmagenta' => '8B008B', 'darkolivegreen' => '556B2F', 'darkorange' => 'FF8C00', 'darkorchid' => '9932CC', 'darkred' => '8B0000', 'darksalmon' => 'E9967A', 'darkseagreen' => '8FBC8F', 'darkslateblue' => '483D8B', 'darkslategray' => '2F4F4F', 'darkslategrey' => '2F4F4F', 'darkturquoise' => '00CED1', 'darkviolet' => '9400D3', 'deeppink' => 'FF1493', 'deepskyblue' => '00BFFF', 'dimgray' => '696969', 'dimgrey' => '696969', 'dodgerblue' => '1E90FF', 'firebrick' => 'B22222', 'floralwhite' => 'FFFAF0', 'forestgreen' => '228B22', 'fuchsia' => 'FF00FF', 'gainsboro' => 'DCDCDC', 'ghostwhite' => 'F8F8FF', 'gold' => 'FFD700', 'goldenrod' => 'DAA520', 'gray' => '808080', 'green' => '008000', 'greenyellow' => 'ADFF2F', 'grey' => '808080', 'honeydew' => 'F0FFF0', 'hotpink' => 'FF69B4', 'indianred' => 'CD5C5C', 'indigo' => '4B0082', 'ivory' => 'FFFFF0', 'khaki' => 'F0E68C', 'lavender' => 'E6E6FA', 'lavenderblush' => 'FFF0F5', 'lawngreen' => '7CFC00', 'lemonchiffon' => 'FFFACD', 'lightblue' => 'ADD8E6', 'lightcoral' => 'F08080', 'lightcyan' => 'E0FFFF', 'lightgoldenrodyellow' => 'FAFAD2', 'lightgray' => 'D3D3D3', 'lightgreen' => '90EE90', 'lightgrey' => 'D3D3D3', 'lightpink' => 'FFB6C1', 'lightsalmon' => 'FFA07A', 'lightseagreen' => '20B2AA', 'lightskyblue' => '87CEFA', 'lightslategray' => '778899', 'lightslategrey' => '778899', 'lightsteelblue' => 'B0C4DE', 'lightyellow' => 'FFFFE0', 'lime' => '00FF00', 'limegreen' => '32CD32', 'linen' => 'FAF0E6', 'magenta' => 'FF00FF', 'maroon' => '800000', 'mediumaquamarine' => '66CDAA', 'mediumblue' => '0000CD', 'mediumorchid' => 'BA55D3', 'mediumpurple' => '9370D0', 'mediumseagreen' => '3CB371', 'mediumslateblue' => '7B68EE', 'mediumspringgreen' => '00FA9A', 'mediumturquoise' => '48D1CC', 'mediumvioletred' => 'C71585', 'midnightblue' => '191970', 'mintcream' => 'F5FFFA', 'mistyrose' => 'FFE4E1', 'moccasin' => 'FFE4B5', 'navajowhite' => 'FFDEAD', 'navy' => '000080', 'oldlace' => 'FDF5E6', 'olive' => '808000', 'olivedrab' => '6B8E23', 'orange' => 'FFA500', 'orangered' => 'FF4500', 'orchid' => 'DA70D6', 'palegoldenrod' => 'EEE8AA', 'palegreen' => '98FB98', 'paleturquoise' => 'AFEEEE', 'palevioletred' => 'DB7093', 'papayawhip' => 'FFEFD5', 'peachpuff' => 'FFDAB9', 'peru' => 'CD853F', 'pink' => 'FFC0CB', 'plum' => 'DDA0DD', 'powderblue' => 'B0E0E6', 'purple' => '800080', 'red' => 'FF0000', 'rosybrown' => 'BC8F8F', 'royalblue' => '4169E1', 'saddlebrown' => '8B4513', 'salmon' => 'FA8072', 'sandybrown' => 'F4A460', 'seagreen' => '2E8B57', 'seashell' => 'FFF5EE', 'sienna' => 'A0522D', 'silver' => 'C0C0C0', 'skyblue' => '87CEEB', 'slateblue' => '6A5ACD', 'slategray' => '708090', 'slategrey' => '708090', 'snow' => 'FFFAFA', 'springgreen' => '00FF7F', 'steelblue' => '4682B4', 'tan' => 'D2B48C', 'teal' => '008080', 'thistle' => 'D8BFD8', 'tomato' => 'FF6347', 'turquoise' => '40E0D0', 'violet' => 'EE82EE', 'wheat' => 'F5DEB3', 'white' => 'FFFFFF', 'whitesmoke' => 'F5F5F5', 'yellow' => 'FFFF00', 'yellowgreen' => '9ACD32']; 325 | 326 | $color_name = strtolower($color_name); 327 | 328 | return isset($colors[$color_name]) ? '#'.$colors[$color_name] : $color_name; 329 | } 330 | 331 | /** 332 | * Generate Simple Random Password. 333 | * 334 | * @param int $length length of generated password, default 8 335 | * @param string $customAlphabet a custom alphabet string 336 | * 337 | * @return string Generated Password 338 | */ 339 | public static function generateRandomPassword($length = 8, $customAlphabet = null) 340 | { 341 | $pass = []; 342 | if (strlen(trim($customAlphabet))) { 343 | $alphabet = trim($customAlphabet); 344 | } else { 345 | $alphabet = 'abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789'; 346 | } 347 | 348 | $alphaLength = strlen($alphabet) - 1; 349 | for ($i = 0; $i < $length; $i++) { 350 | $n = rand(0, $alphaLength); 351 | $pass[] = $alphabet[$n]; 352 | } 353 | 354 | return implode($pass); 355 | } 356 | 357 | /** 358 | * Simple Encode string. 359 | * 360 | * @param string $string String you would like to encode 361 | * @param string $passkey salt for encoding 362 | * 363 | * @return string 364 | */ 365 | public static function simpleEncode($string, $passkey = null) 366 | { 367 | $key = $passkey; 368 | if (!isset($passkey) || empty($passkey)) { 369 | $key = self::generateServerSpecificHash(); 370 | } 371 | 372 | $result = ''; 373 | for ($i = 0; $i < strlen($string); $i++) { 374 | $char = substr($string, $i, 1); 375 | $keychar = substr($key, ($i % strlen($key)) - 1, 1); 376 | $char = chr(ord($char) + ord($keychar)); 377 | $result .= $char; 378 | } 379 | 380 | return base64_encode($result); 381 | } 382 | 383 | /** 384 | * Simple Decode string. 385 | * 386 | * @param string $string String encoded via Recipe::simpleEncode() 387 | * @param string $passkey salt for encoding 388 | * 389 | * @return string 390 | */ 391 | public static function simpleDecode($string, $passkey = null) 392 | { 393 | $key = $passkey; 394 | if (!isset($passkey) || empty($passkey)) { 395 | $key = self::generateServerSpecificHash(); 396 | } 397 | 398 | $result = ''; 399 | $string = base64_decode($string); 400 | for ($i = 0; $i < strlen($string); $i++) { 401 | $char = substr($string, $i, 1); 402 | $keychar = substr($key, ($i % strlen($key)) - 1, 1); 403 | $char = chr(ord($char) - ord($keychar)); 404 | $result .= $char; 405 | } 406 | 407 | return $result; 408 | } 409 | 410 | /** 411 | * Generate Server Specific hash. 412 | * 413 | * @method generateServerSpecificHash 414 | * 415 | * @return string 416 | */ 417 | public static function generateServerSpecificHash() 418 | { 419 | return (isset($_SERVER['SERVER_NAME']) && !empty($_SERVER['SERVER_NAME'])) 420 | ? md5($_SERVER['SERVER_NAME']) 421 | : md5(pathinfo(__FILE__, PATHINFO_FILENAME)); 422 | } 423 | 424 | /** 425 | * Check to see if the current page is being served over SSL. 426 | * 427 | * @return bool 428 | */ 429 | public static function isHttps() 430 | { 431 | return isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; 432 | } 433 | 434 | /** 435 | * Determine if current page request type is ajax. 436 | * 437 | * @return bool 438 | */ 439 | public static function isAjax() 440 | { 441 | if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) 442 | && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { 443 | return true; 444 | } 445 | 446 | return false; 447 | } 448 | 449 | /** 450 | * Check if number is odd. 451 | * 452 | * @param int $num integer to check 453 | * 454 | * @return bool 455 | */ 456 | public static function isNumberOdd($num) 457 | { 458 | return $num % 2 !== 0; 459 | } 460 | 461 | /** 462 | * Check if number is even. 463 | * 464 | * @param int $num integer to check 465 | * 466 | * @return bool 467 | */ 468 | public static function isNumberEven($num) 469 | { 470 | return $num % 2 == 0; 471 | } 472 | 473 | /** 474 | * Return the current URL. 475 | * 476 | * @return string 477 | */ 478 | public static function getCurrentURL() 479 | { 480 | $url = 'http://'; 481 | if (self::isHttps()) { 482 | $url = 'https://'; 483 | } 484 | 485 | if (isset($_SERVER['PHP_AUTH_USER'])) { 486 | $url .= $_SERVER['PHP_AUTH_USER']; 487 | if (isset($_SERVER['PHP_AUTH_PW'])) { 488 | $url .= ':'.$_SERVER['PHP_AUTH_PW']; 489 | } 490 | $url .= '@'; 491 | } 492 | if (isset($_SERVER['HTTP_HOST'])) { 493 | $url .= $_SERVER['HTTP_HOST']; 494 | } 495 | if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 80) { 496 | $url .= ':'.$_SERVER['SERVER_PORT']; 497 | } 498 | if (!isset($_SERVER['REQUEST_URI'])) { 499 | $url .= substr($_SERVER['PHP_SELF'], 1); 500 | if (isset($_SERVER['QUERY_STRING'])) { 501 | $url .= '?'.$_SERVER['QUERY_STRING']; 502 | } 503 | 504 | return $url; 505 | } 506 | 507 | $url .= $_SERVER['REQUEST_URI']; 508 | 509 | return $url; 510 | } 511 | 512 | /** 513 | * Returns the IP address of the client. 514 | * 515 | * @param bool $headerContainingIPAddress Default false 516 | * 517 | * @return string 518 | */ 519 | public static function getClientIP($headerContainingIPAddress = null) 520 | { 521 | if (!empty($headerContainingIPAddress)) { 522 | return isset($_SERVER[$headerContainingIPAddress]) ? trim($_SERVER[$headerContainingIPAddress]) : false; 523 | } 524 | 525 | $knowIPkeys = [ 526 | 'HTTP_CLIENT_IP', 527 | 'HTTP_X_FORWARDED_FOR', 528 | 'HTTP_X_FORWARDED', 529 | 'HTTP_X_CLUSTER_CLIENT_IP', 530 | 'HTTP_FORWARDED_FOR', 531 | 'HTTP_FORWARDED', 532 | 'REMOTE_ADDR', 533 | ]; 534 | 535 | foreach ($knowIPkeys as $key) { 536 | if (array_key_exists($key, $_SERVER) !== true) { 537 | continue; 538 | } 539 | foreach (explode(',', $_SERVER[$key]) as $ip) { 540 | $ip = trim($ip); 541 | if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) { 542 | return $ip; 543 | } 544 | } 545 | } 546 | 547 | return false; 548 | } 549 | 550 | /** 551 | * Detect if user is on mobile device. 552 | * 553 | * @return bool 554 | * 555 | * @todo Put everything to an array & then implode it? 556 | */ 557 | public static function isMobile() 558 | { 559 | if (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop' 560 | .'|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i' 561 | .'|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)' 562 | .'|vodafone|wap|windows ce|xda|xiino/i', $_SERVER['HTTP_USER_AGENT']) 563 | || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)' 564 | .'|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi' 565 | .'(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co' 566 | .'(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)' 567 | .'|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|' 568 | .'haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|' 569 | .'i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|' 570 | .'kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|' 571 | .'m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|' 572 | .'t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)' 573 | .'\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|' 574 | .'phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|' 575 | .'r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|' 576 | .'mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy' 577 | .'(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)' 578 | .'|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|' 579 | .'70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', 580 | substr($_SERVER['HTTP_USER_AGENT'], 0, 4))) { 581 | return true; 582 | } 583 | 584 | return false; 585 | } 586 | 587 | /** 588 | * Get user browser. 589 | * 590 | * @return string 591 | */ 592 | public static function getBrowser() 593 | { 594 | $u_agent = $_SERVER['HTTP_USER_AGENT']; 595 | $browserName = $ub = $platform = 'Unknown'; 596 | if (preg_match('/linux/i', $u_agent)) { 597 | $platform = 'Linux'; 598 | } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) { 599 | $platform = 'Mac OS'; 600 | } elseif (preg_match('/windows|win32/i', $u_agent)) { 601 | $platform = 'Windows'; 602 | } 603 | 604 | if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) { 605 | $browserName = 'Internet Explorer'; 606 | $ub = 'MSIE'; 607 | } elseif (preg_match('/Firefox/i', $u_agent)) { 608 | $browserName = 'Mozilla Firefox'; 609 | $ub = 'Firefox'; 610 | } elseif (preg_match('/Chrome/i', $u_agent)) { 611 | $browserName = 'Google Chrome'; 612 | $ub = 'Chrome'; 613 | } elseif (preg_match('/Safari/i', $u_agent)) { 614 | $browserName = 'Apple Safari'; 615 | $ub = 'Safari'; 616 | } elseif (preg_match('/Opera/i', $u_agent)) { 617 | $browserName = 'Opera'; 618 | $ub = 'Opera'; 619 | } elseif (preg_match('/Netscape/i', $u_agent)) { 620 | $browserName = 'Netscape'; 621 | $ub = 'Netscape'; 622 | } 623 | 624 | $known = ['Version', $ub, 'other']; 625 | $pattern = '#(?'.implode('|', $known).')[/ ]+(?[0-9.|a-zA-Z.]*)#'; 626 | preg_match_all($pattern, $u_agent, $matches); 627 | $i = count($matches['browser']); 628 | $version = $matches['version'][0]; 629 | if ($i != 1 && strripos($u_agent, 'Version') >= strripos($u_agent, $ub)) { 630 | $version = $matches['version'][1]; 631 | } 632 | if ($version == null || $version == '') { 633 | $version = '?'; 634 | } 635 | 636 | return implode(', ', [$browserName, 'Version: '.$version, $platform]); 637 | } 638 | 639 | /** 640 | * Get client location. 641 | * 642 | * @return string|false 643 | */ 644 | public static function getClientLocation() 645 | { 646 | $result = false; 647 | $ip_data = @json_decode(self::curl('http://www.geoplugin.net/json.gp?ip='.self::getClientIP())); 648 | 649 | if (isset($ip_data) && $ip_data->geoplugin_countryName != null) { 650 | $result = $ip_data->geoplugin_city.', '.$ip_data->geoplugin_countryCode; 651 | } 652 | 653 | return $result; 654 | } 655 | 656 | /** 657 | * Convert number to word representation. 658 | * 659 | * @param int $number number to convert to word 660 | * 661 | * @throws \Exception 662 | * 663 | * @return string converted string 664 | */ 665 | public static function numberToWord($number) 666 | { 667 | $hyphen = '-'; 668 | $conjunction = ' and '; 669 | $separator = ', '; 670 | $negative = 'negative '; 671 | $decimal = ' point '; 672 | $fraction = null; 673 | $dictionary = [ 674 | 0 => 'zero', 675 | 1 => 'one', 676 | 2 => 'two', 677 | 3 => 'three', 678 | 4 => 'four', 679 | 5 => 'five', 680 | 6 => 'six', 681 | 7 => 'seven', 682 | 8 => 'eight', 683 | 9 => 'nine', 684 | 10 => 'ten', 685 | 11 => 'eleven', 686 | 12 => 'twelve', 687 | 13 => 'thirteen', 688 | 14 => 'fourteen', 689 | 15 => 'fifteen', 690 | 16 => 'sixteen', 691 | 17 => 'seventeen', 692 | 18 => 'eighteen', 693 | 19 => 'nineteen', 694 | 20 => 'twenty', 695 | 30 => 'thirty', 696 | 40 => 'fourty', 697 | 50 => 'fifty', 698 | 60 => 'sixty', 699 | 70 => 'seventy', 700 | 80 => 'eighty', 701 | 90 => 'ninety', 702 | 100 => 'hundred', 703 | 1000 => 'thousand', 704 | 1000000 => 'million', 705 | 1000000000 => 'billion', 706 | 1000000000000 => 'trillion', 707 | 1000000000000000 => 'quadrillion', 708 | 1000000000000000000 => 'quintillion', 709 | ]; 710 | 711 | if (!is_numeric($number)) { 712 | throw new \Exception('NaN'); 713 | } 714 | 715 | if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) { 716 | throw new \Exception('numberToWord only accepts numbers between -'.PHP_INT_MAX.' and '.PHP_INT_MAX); 717 | } 718 | 719 | if ($number < 0) { 720 | return $negative.self::numberToWord(abs($number)); 721 | } 722 | 723 | if (strpos($number, '.') !== false) { 724 | list($number, $fraction) = explode('.', $number); 725 | } 726 | 727 | switch (true) { 728 | case $number < 21: 729 | $string = $dictionary[$number]; 730 | break; 731 | 732 | case $number < 100: 733 | $tens = ((int) ($number / 10)) * 10; 734 | $units = $number % 10; 735 | $string = $dictionary[$tens]; 736 | 737 | if ($units) { 738 | $string .= $hyphen.$dictionary[$units]; 739 | } 740 | 741 | break; 742 | 743 | case $number < 1000: 744 | $hundreds = $number / 100; 745 | $remainder = $number % 100; 746 | $string = $dictionary[$hundreds].' '.$dictionary[100]; 747 | 748 | if ($remainder) { 749 | $string .= $conjunction.self::numberToWord($remainder); 750 | } 751 | 752 | break; 753 | 754 | default: 755 | $baseUnit = pow(1000, floor(log($number, 1000))); 756 | $numBaseUnits = (int) ($number / $baseUnit); 757 | $remainder = $number % $baseUnit; 758 | $string = self::numberToWord($numBaseUnits).' '.$dictionary[$baseUnit]; 759 | 760 | if ($remainder) { 761 | $string .= $remainder < 100 ? $conjunction : $separator; 762 | $string .= self::numberToWord($remainder); 763 | } 764 | 765 | break; 766 | } 767 | 768 | if (null !== $fraction && is_numeric($fraction)) { 769 | $string .= $decimal; 770 | $words = []; 771 | 772 | foreach (str_split((string) $fraction) as $number) { 773 | $words[] = $dictionary[$number]; 774 | } 775 | 776 | $string .= implode(' ', $words); 777 | } 778 | 779 | return $string; 780 | } 781 | 782 | /** 783 | * Convert seconds to real time. 784 | * 785 | * @param int $seconds time in seconds 786 | * @param bool $returnAsWords return time in words (example one minute and 20 seconds) if value is True or (1 minute and 20 seconds) if value is false, default false 787 | * 788 | * @return string 789 | */ 790 | public static function secondsToText($seconds, $returnAsWords = false) 791 | { 792 | $periods = [ 793 | 'year' => 3.156e+7, 794 | 'month' => 2.63e+6, 795 | 'week' => 604800, 796 | 'day' => 86400, 797 | 'hour' => 3600, 798 | 'minute' => 60, 799 | 'second' => 1, 800 | ]; 801 | 802 | $parts = []; 803 | foreach ($periods as $name => $dur) { 804 | $div = floor($seconds / $dur); 805 | 806 | if ($div == 0) { 807 | continue; 808 | } 809 | 810 | if ($div == 1) { 811 | $parts[] = ($returnAsWords ? self::numberToWord($div) : $div).' '.$name; 812 | } else { 813 | $parts[] = ($returnAsWords ? self::numberToWord($div) : $div).' '.$name.'s'; 814 | } 815 | 816 | $seconds %= $dur; 817 | } 818 | 819 | $last = array_pop($parts); 820 | 821 | if (empty($parts)) { 822 | return $last; 823 | } 824 | 825 | return implode(', ', $parts).' and '.$last; 826 | } 827 | 828 | /** 829 | * Convert minutes to real time. 830 | * 831 | * @param int $minutes time in minutes 832 | * @param bool $returnAsWords return time in words (example one hour and 20 minutes) if value is True or (1 hour and 20 minutes) if value is false, default false 833 | * 834 | * @return string 835 | */ 836 | public static function minutesToText($minutes, $returnAsWords = false) 837 | { 838 | return self::secondsToText($minutes * 60, $returnAsWords); 839 | } 840 | 841 | /** 842 | * Convert hours to real time. 843 | * 844 | * @param int $hours time in hours 845 | * @param bool $returnAsWords return time in words (example one hour) if value is True or (1 hour) if value is false, default false 846 | * 847 | * @return string 848 | */ 849 | public static function hoursToText($hours, $returnAsWords = false) 850 | { 851 | return self::secondsToText($hours * 3600, $returnAsWords); 852 | } 853 | 854 | /** 855 | * Truncate String (shorten) with or without ellipsis. 856 | * 857 | * @param string $string String to truncate 858 | * @param int $maxLength Maximum length of string 859 | * @param bool $addEllipsis if True, "..." is added in the end of the string, default true 860 | * @param bool $wordsafe if True, Words will not be cut in the middle 861 | * 862 | * @return string Shortened Text 863 | */ 864 | public static function shortenString($string, $maxLength, $addEllipsis = true, $wordsafe = false) 865 | { 866 | $ellipsis = ''; 867 | $maxLength = max($maxLength, 0); 868 | 869 | if (mb_strlen($string) <= $maxLength) { 870 | return $string; 871 | } 872 | 873 | if ($addEllipsis) { 874 | $ellipsis = mb_substr('...', 0, $maxLength); 875 | $maxLength -= mb_strlen($ellipsis); 876 | $maxLength = max($maxLength, 0); 877 | } 878 | 879 | $string = mb_substr($string, 0, $maxLength); 880 | 881 | if ($wordsafe) { 882 | $string = preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $maxLength)); 883 | } 884 | 885 | if ($addEllipsis) { 886 | $string .= $ellipsis; 887 | } 888 | 889 | return $string; 890 | } 891 | 892 | /** 893 | * Make a Curl call. 894 | * 895 | * @param string $url URL to curl 896 | * @param string $method GET or POST, Default GET 897 | * @param mixed $data Data to post, Default false 898 | * @param mixed $headers Additional headers, example: array ("Accept: application/json") 899 | * @param bool $returnInfo Whether or not to retrieve curl_getinfo() 900 | * @param bool|array $auth Basic authentication params. If array with keys 'username' and 'password' specified, CURLOPT_USERPWD cURL option will be set 901 | * 902 | * @return array|string if $returnInfo is set to True, array is returned with two keys, contents (will contain response) and info (information regarding a specific transfer), otherwise response content is returned 903 | */ 904 | public static function curl($url, $method = 'GET', $data = false, $headers = false, $returnInfo = false, $auth = false) 905 | { 906 | $ch = curl_init(); 907 | $info = null; 908 | if (strtoupper($method) == 'POST') { 909 | curl_setopt($ch, CURLOPT_URL, $url); 910 | curl_setopt($ch, CURLOPT_POST, true); 911 | if ($data !== false) { 912 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 913 | } 914 | } else { 915 | if ($data !== false) { 916 | if (is_array($data)) { 917 | $dataTokens = []; 918 | foreach ($data as $key => $value) { 919 | array_push($dataTokens, urlencode($key).'='.urlencode($value)); 920 | } 921 | $data = implode('&', $dataTokens); 922 | } 923 | curl_setopt($ch, CURLOPT_URL, $url.'?'.$data); 924 | } else { 925 | curl_setopt($ch, CURLOPT_URL, $url); 926 | } 927 | } 928 | 929 | curl_setopt($ch, CURLOPT_HEADER, false); 930 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 931 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 932 | curl_setopt($ch, CURLOPT_TIMEOUT, 10); 933 | 934 | if ($headers !== false) { 935 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 936 | } 937 | 938 | if ($auth !== false && strlen($auth['username']) > 0 && strlen($auth['password']) > 0) { 939 | curl_setopt($ch, CURLOPT_USERPWD, $auth['username'].':'.$auth['password']); 940 | } 941 | 942 | $contents = curl_exec($ch); 943 | if ($returnInfo) { 944 | $info = curl_getinfo($ch); 945 | } 946 | 947 | curl_close($ch); 948 | 949 | if ($returnInfo) { 950 | return ['contents' => $contents, 'info' => $info]; 951 | } 952 | 953 | return $contents; 954 | } 955 | 956 | /** 957 | * Get information on a short URL. Find out where it forwards. 958 | * 959 | * @param string $shortURL shortened URL 960 | * 961 | * @return mixed full url or false 962 | */ 963 | public static function expandShortUrl($shortURL) 964 | { 965 | if (empty($shortURL)) { 966 | return false; 967 | } 968 | 969 | $headers = get_headers($shortURL, 1); 970 | if (isset($headers['Location'])) { 971 | return $headers['Location']; 972 | } 973 | 974 | $data = self::curl($shortURL); 975 | 976 | preg_match_all('/<[\s]*meta[\s]*http-equiv="?'.'([^>"]*)"?[\s]*'.'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', $data, $match); 977 | 978 | if (isset($match) && is_array($match) && count($match) == 3) { 979 | $originals = $match[0]; 980 | $names = $match[1]; 981 | $values = $match[2]; 982 | if ((isset($originals) && isset($names) && isset($values)) && count($originals) == count($names) && count($names) == count($values)) { 983 | $metaTags = []; 984 | for ($i = 0, $limit = count($names); $i < $limit; $i++) { 985 | $metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]]; 986 | } 987 | } 988 | } 989 | 990 | if (isset($metaTags['refresh']['value']) && !empty($metaTags['refresh']['value'])) { 991 | $returnData = explode('=', $metaTags['refresh']['value']); 992 | if (isset($returnData[1]) && !empty($returnData[1])) { 993 | return $returnData[1]; 994 | } 995 | } 996 | 997 | return false; 998 | } 999 | 1000 | /** 1001 | * Get Alexa ranking for a domain name. 1002 | * 1003 | * @param string $domain Domain name to get ranking for 1004 | * 1005 | * @return mixed false if ranking is found, otherwise integer 1006 | */ 1007 | public static function getAlexaRank($domain) 1008 | { 1009 | $domain = preg_replace('~^https?://~', '', $domain); 1010 | $alexa = 'http://data.alexa.com/data?cli=10&dat=s&url=%s'; 1011 | $request_url = sprintf($alexa, urlencode($domain)); 1012 | $xml = simplexml_load_file($request_url); 1013 | 1014 | if (!isset($xml->SD[1])) { 1015 | return false; 1016 | } 1017 | 1018 | $nodeAttributes = $xml->SD[1]->POPULARITY->attributes(); 1019 | $text = (int) $nodeAttributes['TEXT']; 1020 | 1021 | return $text; 1022 | } 1023 | 1024 | /** 1025 | * Shorten URL via tinyurl.com service. 1026 | * 1027 | * @param string $url URL to shorten 1028 | * 1029 | * @return mixed shortened url or false 1030 | */ 1031 | public static function getTinyUrl($url) 1032 | { 1033 | if (strpos($url, 'http') !== 0) { 1034 | $url = 'http://'.$url; 1035 | } 1036 | 1037 | $gettiny = self::curl('http://tinyurl.com/api-create.php?url='.$url); 1038 | 1039 | if (isset($gettiny) && !empty($gettiny)) { 1040 | return $gettiny; 1041 | } 1042 | 1043 | return false; 1044 | } 1045 | 1046 | /** 1047 | * Get keyword suggestion from Google. 1048 | * 1049 | * @param string $keyword keyword to get suggestions for 1050 | * 1051 | * @return mixed array of keywords or false 1052 | */ 1053 | public static function getKeywordSuggestionsFromGoogle($keyword) 1054 | { 1055 | $data = self::curl('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.urlencode($keyword)); 1056 | if (($data = json_decode($data, true)) !== null && !empty($data[1])) { 1057 | return $data[1]; 1058 | } 1059 | 1060 | return false; 1061 | } 1062 | 1063 | /** 1064 | * Search wikipedia. 1065 | * 1066 | * @param string $keyword Keywords to search in wikipedia 1067 | * 1068 | * @return mixed Array or false 1069 | */ 1070 | public static function wikiSearch($keyword) 1071 | { 1072 | $apiurl = 'http://wikipedia.org/w/api.php?action=opensearch&search='.urlencode($keyword).'&format=xml&limit=1'; 1073 | $data = self::curl($apiurl); 1074 | $xml = simplexml_load_string($data); 1075 | if ((string) $xml->Section->Item->Description) { 1076 | $array = []; 1077 | $array['title'] = (string) $xml->Section->Item->Text; 1078 | $array['description'] = (string) $xml->Section->Item->Description; 1079 | $array['url'] = (string) $xml->Section->Item->Url; 1080 | if (isset($xml->Section->Item->Image)) { 1081 | $img = (string) $xml->Section->Item->Image->attributes()->source; 1082 | $array['image'] = str_replace('/50px-', '/200px-', $img); 1083 | } 1084 | 1085 | return $array; 1086 | } 1087 | 1088 | return false; 1089 | } 1090 | 1091 | /** 1092 | * Build (HTML) notification message. 1093 | * 1094 | * @param string $notification Text to display in notification 1095 | * @param string $type Notification type, available notifications: success, warning, error and info 1096 | * @param array $attributes Optional, additional key/value attributes to include in the DIV tag 1097 | * 1098 | * @return string containing complete div tag 1099 | */ 1100 | public static function notification($notification, $type = null, $attributes = []) 1101 | { 1102 | $attr = self::arrayToString($attributes); 1103 | if (isset($notification) && !empty($notification)) { 1104 | switch (strtolower($type)) { 1105 | case 'success': 1106 | $css = 'border-color: #bdf2a6;color: #2a760a;background-color: #eefde7;'; 1107 | break; 1108 | 1109 | case 'warning': 1110 | $css = 'border-color: #f2e5a6;color: #76640a;background-color: #fdf9e7;'; 1111 | break; 1112 | 1113 | case 'error': 1114 | $css = 'border-color: #f2a6a6;color: #760a0a;background-color: #fde7e7;'; 1115 | break; 1116 | 1117 | case 'info': 1118 | default: 1119 | $css = 'border-color: #a6d9f2;color: #0a5276;background-color: #e7f6fd;'; 1120 | break; 1121 | } 1122 | 1123 | return '
'.$notification.'
'; 1124 | } 1125 | 1126 | return false; 1127 | } 1128 | 1129 | /** 1130 | * Parse text to find URL's for embed enabled services like: youtube.com, blip.tv, vimeo.com, dailymotion.com, flickr.com, smugmug.com, hulu.com, revision3.com, wordpress.tv, funnyordie.com, soundcloud.com, slideshare.net and instagram.com and embed elements automatically. 1131 | * 1132 | * @param string $string text to parse 1133 | * @param string $width max width of embedded element 1134 | * @param string $height max height of embedded element 1135 | * 1136 | * @return string 1137 | */ 1138 | public static function autoEmbed($string, $width = '560', $height = '315') 1139 | { 1140 | $providers = ['~https?://(?:[0-9A-Z-]+\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)[?=&+%\w.-]*~ix' => 'http://www.youtube.com/oembed', '#https?://blip\.tv/(.+)#i' => 'http://blip.tv/oembed/', '~https?://(?:[0-9A-Z-]+\.)?(?:vimeo.com\S*[^\w\s-])([\w-]{1,20})(?=[^\w-]|$)[?=&+%\w.-]*~ix' => 'http://vimeo.com/api/oembed.{format}', '#https?://(www\.)?dailymotion\.com/.*#i' => 'http://www.dailymotion.com/services/oembed', '#https?://(www\.)?flickr\.com/.*#i' => 'http://www.flickr.com/services/oembed/', '#https?://(.+\.)?smugmug\.com/.*#i' => 'http://api.smugmug.com/services/oembed/', '#https?://(www\.)?hulu\.com/watch/.*#i' => 'http://www.hulu.com/api/oembed.{format}', '#https?://revision3\.com/(.+)#i' => 'http://revision3.com/api/oembed/', '#https?://wordpress\.tv/(.+)#i' => 'http://wordpress.tv/oembed/', '#https?://(www\.)?funnyordie\.com/videos/.*#i' => 'http://www.funnyordie.com/oembed', '#https?://(www\.)?soundcloud\.com/.*#i' => 'http://soundcloud.com/oembed', '#https?://(www\.)?slideshare.net/*#' => 'http://www.slideshare.net/api/oembed/2', '#http://instagr(\.am|am\.com)/p/.*#i' => 'http://api.instagram.com/oembed']; 1141 | $string = preg_replace_callback('@(^|[^"|^\'])(https?://?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@', function ($matches) use ($providers, $width, $height) { 1142 | $url = trim($matches[0]); 1143 | $url = explode('#', $url); 1144 | $url = reset($url); 1145 | 1146 | $requestURL = false; 1147 | 1148 | foreach ($providers as $pattern => $provider) { 1149 | if (preg_match($pattern, $url)) { 1150 | if ($provider == 'http://www.youtube.com/oembed') { 1151 | $url = str_replace('www.youtu.be/', 'www.youtube.com/watch?v=', $url); 1152 | } 1153 | 1154 | $requestURL = str_replace('{format}', 'json', $provider); 1155 | break; 1156 | } 1157 | } 1158 | if ($requestURL !== false) { 1159 | $params = ['maxwidth' => $width, 'maxheight' => $height, 'format' => 'json']; 1160 | 1161 | $requestURL = $requestURL.'?url='.$url.'&'.http_build_query($params); 1162 | $data = json_decode(self::curl($requestURL), true); 1163 | 1164 | switch ($data['type']) { 1165 | case 'photo': 1166 | if (empty($data['url']) || empty($data['width']) || empty($data['height']) || !is_string($data['url']) || !is_numeric($data['width']) || !is_numeric($data['height'])) { 1167 | return $matches[0]; 1168 | } 1169 | 1170 | $title = !empty($data['title']) && is_string($data['title']) ? $data['title'] : ''; 1171 | 1172 | return ''.htmlspecialchars($title, ENT_QUOTES, 'UTF-8').''; 1173 | 1174 | case 'video': 1175 | case 'rich': 1176 | if (!empty($data['html']) && is_string($data['html'])) { 1177 | return $data['html']; 1178 | } 1179 | break; 1180 | 1181 | case 'link': 1182 | if (!empty($data['title']) && is_string($data['title'])) { 1183 | return self::createLinkTag($url, $data['title']); 1184 | } 1185 | break; 1186 | 1187 | default: 1188 | return $matches[0]; 1189 | } 1190 | } 1191 | 1192 | return $matches[0]; 1193 | }, $string); 1194 | 1195 | return $string; 1196 | } 1197 | 1198 | /** 1199 | * Parse text to find all URLs that are not linked and create A tag. 1200 | * 1201 | * @param string $string Text to parse 1202 | * @param array $attributes Optional, additional key/value attributes to include in the A tag 1203 | * 1204 | * @return string 1205 | */ 1206 | public static function makeClickableLinks($string, $attributes = []) 1207 | { 1208 | return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '$1', $string); 1209 | } 1210 | 1211 | /** 1212 | * Dump information about a variable. 1213 | * 1214 | * @param mixed $variable Variable to debug 1215 | * 1216 | * @return void 1217 | */ 1218 | public static function debug($variable) 1219 | { 1220 | ob_start(); 1221 | var_dump($variable); 1222 | $output = ob_get_clean(); 1223 | $maps = ['string' => "/(string\((?P\d+)\)) (?P\"(? "/\[\"(?P.+)\"(?:\:\"(?P[a-z0-9_\\\]+)\")?(?:\:(?Ppublic|protected|private))?\]=>/Ui", 'countable' => "/(?Parray|int|string)\((?P\d+)\)/", 'resource' => "/resource\((?P\d+)\) of type \((?P[a-z0-9_\\\]+)\)/", 'bool' => "/bool\((?Ptrue|false)\)/", 'float' => "/float\((?P[0-9\.]+)\)/", 'object' => "/object\((?P\S+)\)\#(?P\d+) \((?P\d+)\)/i"]; 1224 | foreach ($maps as $function => $pattern) { 1225 | $output = preg_replace_callback($pattern, function ($matches) use ($function) { 1226 | switch ($function) { 1227 | case 'string': 1228 | $matches['value'] = htmlspecialchars($matches['value']); 1229 | 1230 | return 'string('.$matches['length'].') '.$matches['value'].''; 1231 | 1232 | case 'array': 1233 | $key = '"'.$matches['key'].'"'; 1234 | $class = ''; 1235 | $scope = ''; 1236 | if (isset($matches['class']) && !empty($matches['class'])) { 1237 | $class = ':"'.$matches['class'].'"'; 1238 | } 1239 | if (isset($matches['scope']) && !empty($matches['scope'])) { 1240 | $scope = ':'.$matches['scope'].''; 1241 | } 1242 | 1243 | return '['.$key.$class.$scope.']=>'; 1244 | 1245 | case 'countable': 1246 | $type = ''.$matches['type'].''; 1247 | $count = '('.$matches['count'].')'; 1248 | 1249 | return $type.$count; 1250 | 1251 | case 'bool': 1252 | return 'bool('.$matches['value'].')'; 1253 | 1254 | case 'float': 1255 | return 'float('.$matches['value'].')'; 1256 | 1257 | case 'resource': 1258 | return 'resource('.$matches['count'].') of type ('.$matches['class'].')'; 1259 | 1260 | case 'object': 1261 | return 'object('.$matches['class'].')#'.$matches['id'].' ('.$matches['count'].')'; 1262 | 1263 | } 1264 | }, $output); 1265 | } 1266 | $header = ''; 1267 | list($debugfile) = debug_backtrace(); 1268 | 1269 | if (!empty($debugfile['file'])) { 1270 | $header = '

'.$debugfile['file'].'

'; 1271 | } 1272 | 1273 | echo '
'.$header.$output.'
'; 1274 | } 1275 | 1276 | /** 1277 | * Return referer page. 1278 | * 1279 | * @return string|false 1280 | */ 1281 | public static function getReferer() 1282 | { 1283 | return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false; 1284 | } 1285 | 1286 | /** 1287 | * Captures output via ob_get_contents(), tries to enable gzip, removes whitespace from captured output and echos back. 1288 | * 1289 | * @return string whitespace stripped output 1290 | */ 1291 | public static function compressPage() 1292 | { 1293 | register_shutdown_function(function () { 1294 | $buffer = preg_replace(['/\>[^\S ]+/s', '/[^\S ]+\', '<', '\\1'], ob_get_contents()); 1295 | ob_end_clean(); 1296 | if (!((ini_get('zlib.output_compression') == 'On' || 1297 | ini_get('zlib.output_compression_level') > 0) || 1298 | ini_get('output_handler') == 'ob_gzhandler') && 1299 | !empty($_SERVER['HTTP_ACCEPT_ENCODING']) && 1300 | extension_loaded('zlib') && 1301 | strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false 1302 | ) { 1303 | ob_start('ob_gzhandler'); 1304 | } 1305 | echo $buffer; 1306 | }); 1307 | } 1308 | 1309 | /** 1310 | * Takes a number and adds “th, st, nd, rd, th” after it. 1311 | * 1312 | * @param int $cardinal Number to add termination 1313 | * 1314 | * @return string 1315 | */ 1316 | public static function ordinal($cardinal) 1317 | { 1318 | $test_c = abs($cardinal) % 10; 1319 | $ext = ((abs($cardinal) % 100 < 21 && abs($cardinal) % 100 > 4) 1320 | ? 'th' 1321 | : (($test_c < 4) 1322 | ? ($test_c < 3) 1323 | ? ($test_c < 2) 1324 | ? ($test_c < 1) 1325 | ? 'th' 1326 | : 'st' 1327 | : 'nd' 1328 | : 'rd' 1329 | : 'th')); 1330 | 1331 | return $cardinal.$ext; 1332 | } 1333 | 1334 | /** 1335 | * Returns the number of days for the given month and year. 1336 | * 1337 | * @param int $month Month to check 1338 | * @param int $year Year to check 1339 | * 1340 | * @return int 1341 | */ 1342 | public static function numberOfDaysInMonth($month = 0, $year = 0) 1343 | { 1344 | if ($month < 1 or $month > 12) { 1345 | return 0; 1346 | } 1347 | 1348 | if (!is_numeric($year) or strlen($year) != 4) { 1349 | $year = date('Y'); 1350 | } 1351 | 1352 | if ($month == 2) { 1353 | if ($year % 400 == 0 or ($year % 4 == 0 and $year % 100 != 0)) { 1354 | return 29; 1355 | } 1356 | } 1357 | 1358 | $days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 1359 | 1360 | return $days_in_month[$month - 1]; 1361 | } 1362 | 1363 | /** 1364 | * print_r's Variable in
 tags.
1365 |      *
1366 |      * @param mixed $variable variable to print_r
1367 |      *
1368 |      * @return void
1369 |      */
1370 |     public static function pr($variable)
1371 |     {
1372 |         echo '
';
1373 |         print_r($variable);
1374 |         echo '
'; 1375 | } 1376 | 1377 | /** 1378 | * Sanitize FileName from special chart. 1379 | * 1380 | * @method sanitizeFileName 1381 | * 1382 | * @param string $filename filename to sanitize 1383 | * 1384 | * @return string Sanitized filename 1385 | */ 1386 | public static function sanitizeFileName($filename) 1387 | { 1388 | return str_replace([' ', '"', "'", '&', '/', '\\', '?', '#'], '_', $filename); 1389 | } 1390 | 1391 | /** 1392 | * Converts bytes to human readable size. 1393 | * 1394 | * @method bytesToHumanReadableSize 1395 | * 1396 | * @param int $size Size in bytes 1397 | * @param int $precision returned value precision 1398 | * 1399 | * @return string Human readable size 1400 | */ 1401 | public static function bytesToHumanReadableSize($size, $precision = 2) 1402 | { 1403 | for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) { 1404 | } 1405 | 1406 | return round($size, $precision).' '.['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i]; 1407 | } 1408 | } 1409 | --------------------------------------------------------------------------------