diff --git a/bl-kernel/admin/themes/default/index.php b/bl-kernel/admin/themes/default/index.php index 00b57c89..4a7ff7e5 100644 --- a/bl-kernel/admin/themes/default/index.php +++ b/bl-kernel/admin/themes/default/index.php @@ -18,7 +18,7 @@ - + diff --git a/bl-kernel/admin/themes/default/login.php b/bl-kernel/admin/themes/default/login.php index fa73c40e..8ca05b37 100644 --- a/bl-kernel/admin/themes/default/login.php +++ b/bl-kernel/admin/themes/default/login.php @@ -8,12 +8,12 @@ Bludit - + - + diff --git a/bl-kernel/css/font-awesome/css/font-awesome.min.css b/bl-kernel/css/font-awesome/css/font-awesome.min.css new file mode 100644 index 00000000..ee906a81 --- /dev/null +++ b/bl-kernel/css/font-awesome/css/font-awesome.min.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/bl-kernel/css/font-awesome/font-awesome.min.css b/bl-kernel/css/font-awesome/font-awesome.min.css deleted file mode 100644 index 921ba006..00000000 --- a/bl-kernel/css/font-awesome/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('./fonts/fontawesome-webfont.eot?v=4.5.0');src:url('./fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'),url('./fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'),url('./fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'),url('./fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'),url('./fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"} diff --git a/bl-kernel/css/font-awesome/fonts/FontAwesome.otf b/bl-kernel/css/font-awesome/fonts/FontAwesome.otf index 3ed7f8b4..401ec0f3 100644 Binary files a/bl-kernel/css/font-awesome/fonts/FontAwesome.otf and b/bl-kernel/css/font-awesome/fonts/FontAwesome.otf differ diff --git a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.eot b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.eot index a30335d7..e9f60ca9 100644 Binary files a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.eot and b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.svg b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.ttf b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.ttf index 26dea795..35acda2f 100644 Binary files a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.ttf and b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff index dc35ce3c..400014a4 100644 Binary files a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff and b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff2 b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff2 index 500e5172..4d13fc60 100644 Binary files a/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff2 and b/bl-kernel/css/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/install.php b/install.php index 5863aaac..ae2bb9b7 100644 --- a/install.php +++ b/install.php @@ -586,7 +586,7 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' ) { <?php echo $Language->get('Bludit Installer') ?> - + diff --git a/phpcs.phar b/phpcs.phar deleted file mode 100644 index 323bada4..00000000 Binary files a/phpcs.phar and /dev/null differ diff --git a/phpdcd.phar b/phpdcd.phar deleted file mode 100644 index bfd16fb3..00000000 --- a/phpdcd.phar +++ /dev/null @@ -1,20310 +0,0 @@ -#!/usr/bin/env php - '/php-timer/Timer.php', - 'php_token' => '/php-token-stream/Token.php', - 'php_token_abstract' => '/php-token-stream/Token.php', - 'php_token_ampersand' => '/php-token-stream/Token.php', - 'php_token_and_equal' => '/php-token-stream/Token.php', - 'php_token_array' => '/php-token-stream/Token.php', - 'php_token_array_cast' => '/php-token-stream/Token.php', - 'php_token_as' => '/php-token-stream/Token.php', - 'php_token_at' => '/php-token-stream/Token.php', - 'php_token_backtick' => '/php-token-stream/Token.php', - 'php_token_bad_character' => '/php-token-stream/Token.php', - 'php_token_bool_cast' => '/php-token-stream/Token.php', - 'php_token_boolean_and' => '/php-token-stream/Token.php', - 'php_token_boolean_or' => '/php-token-stream/Token.php', - 'php_token_break' => '/php-token-stream/Token.php', - 'php_token_callable' => '/php-token-stream/Token.php', - 'php_token_caret' => '/php-token-stream/Token.php', - 'php_token_case' => '/php-token-stream/Token.php', - 'php_token_catch' => '/php-token-stream/Token.php', - 'php_token_character' => '/php-token-stream/Token.php', - 'php_token_class' => '/php-token-stream/Token.php', - 'php_token_class_c' => '/php-token-stream/Token.php', - 'php_token_class_name_constant' => '/php-token-stream/Token.php', - 'php_token_clone' => '/php-token-stream/Token.php', - 'php_token_close_bracket' => '/php-token-stream/Token.php', - 'php_token_close_curly' => '/php-token-stream/Token.php', - 'php_token_close_square' => '/php-token-stream/Token.php', - 'php_token_close_tag' => '/php-token-stream/Token.php', - 'php_token_colon' => '/php-token-stream/Token.php', - 'php_token_comma' => '/php-token-stream/Token.php', - 'php_token_comment' => '/php-token-stream/Token.php', - 'php_token_concat_equal' => '/php-token-stream/Token.php', - 'php_token_const' => '/php-token-stream/Token.php', - 'php_token_constant_encapsed_string' => '/php-token-stream/Token.php', - 'php_token_continue' => '/php-token-stream/Token.php', - 'php_token_curly_open' => '/php-token-stream/Token.php', - 'php_token_dec' => '/php-token-stream/Token.php', - 'php_token_declare' => '/php-token-stream/Token.php', - 'php_token_default' => '/php-token-stream/Token.php', - 'php_token_dir' => '/php-token-stream/Token.php', - 'php_token_div' => '/php-token-stream/Token.php', - 'php_token_div_equal' => '/php-token-stream/Token.php', - 'php_token_dnumber' => '/php-token-stream/Token.php', - 'php_token_do' => '/php-token-stream/Token.php', - 'php_token_doc_comment' => '/php-token-stream/Token.php', - 'php_token_dollar' => '/php-token-stream/Token.php', - 'php_token_dollar_open_curly_braces' => '/php-token-stream/Token.php', - 'php_token_dot' => '/php-token-stream/Token.php', - 'php_token_double_arrow' => '/php-token-stream/Token.php', - 'php_token_double_cast' => '/php-token-stream/Token.php', - 'php_token_double_colon' => '/php-token-stream/Token.php', - 'php_token_double_quotes' => '/php-token-stream/Token.php', - 'php_token_echo' => '/php-token-stream/Token.php', - 'php_token_else' => '/php-token-stream/Token.php', - 'php_token_elseif' => '/php-token-stream/Token.php', - 'php_token_empty' => '/php-token-stream/Token.php', - 'php_token_encapsed_and_whitespace' => '/php-token-stream/Token.php', - 'php_token_end_heredoc' => '/php-token-stream/Token.php', - 'php_token_enddeclare' => '/php-token-stream/Token.php', - 'php_token_endfor' => '/php-token-stream/Token.php', - 'php_token_endforeach' => '/php-token-stream/Token.php', - 'php_token_endif' => '/php-token-stream/Token.php', - 'php_token_endswitch' => '/php-token-stream/Token.php', - 'php_token_endwhile' => '/php-token-stream/Token.php', - 'php_token_equal' => '/php-token-stream/Token.php', - 'php_token_eval' => '/php-token-stream/Token.php', - 'php_token_exclamation_mark' => '/php-token-stream/Token.php', - 'php_token_exit' => '/php-token-stream/Token.php', - 'php_token_extends' => '/php-token-stream/Token.php', - 'php_token_file' => '/php-token-stream/Token.php', - 'php_token_final' => '/php-token-stream/Token.php', - 'php_token_finally' => '/php-token-stream/Token.php', - 'php_token_for' => '/php-token-stream/Token.php', - 'php_token_foreach' => '/php-token-stream/Token.php', - 'php_token_func_c' => '/php-token-stream/Token.php', - 'php_token_function' => '/php-token-stream/Token.php', - 'php_token_global' => '/php-token-stream/Token.php', - 'php_token_goto' => '/php-token-stream/Token.php', - 'php_token_gt' => '/php-token-stream/Token.php', - 'php_token_halt_compiler' => '/php-token-stream/Token.php', - 'php_token_if' => '/php-token-stream/Token.php', - 'php_token_implements' => '/php-token-stream/Token.php', - 'php_token_inc' => '/php-token-stream/Token.php', - 'php_token_include' => '/php-token-stream/Token.php', - 'php_token_include_once' => '/php-token-stream/Token.php', - 'php_token_includes' => '/php-token-stream/Token.php', - 'php_token_inline_html' => '/php-token-stream/Token.php', - 'php_token_instanceof' => '/php-token-stream/Token.php', - 'php_token_insteadof' => '/php-token-stream/Token.php', - 'php_token_int_cast' => '/php-token-stream/Token.php', - 'php_token_interface' => '/php-token-stream/Token.php', - 'php_token_is_equal' => '/php-token-stream/Token.php', - 'php_token_is_greater_or_equal' => '/php-token-stream/Token.php', - 'php_token_is_identical' => '/php-token-stream/Token.php', - 'php_token_is_not_equal' => '/php-token-stream/Token.php', - 'php_token_is_not_identical' => '/php-token-stream/Token.php', - 'php_token_is_smaller_or_equal' => '/php-token-stream/Token.php', - 'php_token_isset' => '/php-token-stream/Token.php', - 'php_token_line' => '/php-token-stream/Token.php', - 'php_token_list' => '/php-token-stream/Token.php', - 'php_token_lnumber' => '/php-token-stream/Token.php', - 'php_token_logical_and' => '/php-token-stream/Token.php', - 'php_token_logical_or' => '/php-token-stream/Token.php', - 'php_token_logical_xor' => '/php-token-stream/Token.php', - 'php_token_lt' => '/php-token-stream/Token.php', - 'php_token_method_c' => '/php-token-stream/Token.php', - 'php_token_minus' => '/php-token-stream/Token.php', - 'php_token_minus_equal' => '/php-token-stream/Token.php', - 'php_token_mod_equal' => '/php-token-stream/Token.php', - 'php_token_mul_equal' => '/php-token-stream/Token.php', - 'php_token_mult' => '/php-token-stream/Token.php', - 'php_token_namespace' => '/php-token-stream/Token.php', - 'php_token_new' => '/php-token-stream/Token.php', - 'php_token_ns_c' => '/php-token-stream/Token.php', - 'php_token_ns_separator' => '/php-token-stream/Token.php', - 'php_token_num_string' => '/php-token-stream/Token.php', - 'php_token_object_cast' => '/php-token-stream/Token.php', - 'php_token_object_operator' => '/php-token-stream/Token.php', - 'php_token_open_bracket' => '/php-token-stream/Token.php', - 'php_token_open_curly' => '/php-token-stream/Token.php', - 'php_token_open_square' => '/php-token-stream/Token.php', - 'php_token_open_tag' => '/php-token-stream/Token.php', - 'php_token_open_tag_with_echo' => '/php-token-stream/Token.php', - 'php_token_or_equal' => '/php-token-stream/Token.php', - 'php_token_paamayim_nekudotayim' => '/php-token-stream/Token.php', - 'php_token_percent' => '/php-token-stream/Token.php', - 'php_token_pipe' => '/php-token-stream/Token.php', - 'php_token_plus' => '/php-token-stream/Token.php', - 'php_token_plus_equal' => '/php-token-stream/Token.php', - 'php_token_print' => '/php-token-stream/Token.php', - 'php_token_private' => '/php-token-stream/Token.php', - 'php_token_protected' => '/php-token-stream/Token.php', - 'php_token_public' => '/php-token-stream/Token.php', - 'php_token_question_mark' => '/php-token-stream/Token.php', - 'php_token_require' => '/php-token-stream/Token.php', - 'php_token_require_once' => '/php-token-stream/Token.php', - 'php_token_return' => '/php-token-stream/Token.php', - 'php_token_semicolon' => '/php-token-stream/Token.php', - 'php_token_sl' => '/php-token-stream/Token.php', - 'php_token_sl_equal' => '/php-token-stream/Token.php', - 'php_token_sr' => '/php-token-stream/Token.php', - 'php_token_sr_equal' => '/php-token-stream/Token.php', - 'php_token_start_heredoc' => '/php-token-stream/Token.php', - 'php_token_static' => '/php-token-stream/Token.php', - 'php_token_stream' => '/php-token-stream/Token/Stream.php', - 'php_token_stream_cachingfactory' => '/php-token-stream/Token/Stream/CachingFactory.php', - 'php_token_string' => '/php-token-stream/Token.php', - 'php_token_string_cast' => '/php-token-stream/Token.php', - 'php_token_string_varname' => '/php-token-stream/Token.php', - 'php_token_switch' => '/php-token-stream/Token.php', - 'php_token_throw' => '/php-token-stream/Token.php', - 'php_token_tilde' => '/php-token-stream/Token.php', - 'php_token_trait' => '/php-token-stream/Token.php', - 'php_token_trait_c' => '/php-token-stream/Token.php', - 'php_token_try' => '/php-token-stream/Token.php', - 'php_token_unset' => '/php-token-stream/Token.php', - 'php_token_unset_cast' => '/php-token-stream/Token.php', - 'php_token_use' => '/php-token-stream/Token.php', - 'php_token_var' => '/php-token-stream/Token.php', - 'php_token_variable' => '/php-token-stream/Token.php', - 'php_token_while' => '/php-token-stream/Token.php', - 'php_token_whitespace' => '/php-token-stream/Token.php', - 'php_token_xor_equal' => '/php-token-stream/Token.php', - 'php_token_yield' => '/php-token-stream/Token.php', - 'php_tokenwithscope' => '/php-token-stream/Token.php', - 'php_tokenwithscopeandvisibility' => '/php-token-stream/Token.php', - 'sebastianbergmann\\finderfacade\\configuration' => '/finder-facade/Configuration.php', - 'sebastianbergmann\\finderfacade\\finderfacade' => '/finder-facade/FinderFacade.php', - 'sebastianbergmann\\phpdcd\\analyser' => '/src/Analyser.php', - 'sebastianbergmann\\phpdcd\\cli\\application' => '/src/CLI/Application.php', - 'sebastianbergmann\\phpdcd\\cli\\command' => '/src/CLI/Command.php', - 'sebastianbergmann\\phpdcd\\detector' => '/src/Detector.php', - 'sebastianbergmann\\phpdcd\\log\\text' => '/src/Log/Text.php', - 'sebastianbergmann\\version' => '/version/Version.php', - 'symfony\\component\\console\\application' => '/symfony/console/Symfony/Component/Console/Application.php', - 'symfony\\component\\console\\command\\command' => '/symfony/console/Symfony/Component/Console/Command/Command.php', - 'symfony\\component\\console\\command\\helpcommand' => '/symfony/console/Symfony/Component/Console/Command/HelpCommand.php', - 'symfony\\component\\console\\command\\listcommand' => '/symfony/console/Symfony/Component/Console/Command/ListCommand.php', - 'symfony\\component\\console\\consoleevents' => '/symfony/console/Symfony/Component/Console/ConsoleEvents.php', - 'symfony\\component\\console\\descriptor\\applicationdescription' => '/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php', - 'symfony\\component\\console\\descriptor\\descriptor' => '/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php', - 'symfony\\component\\console\\descriptor\\descriptorinterface' => '/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php', - 'symfony\\component\\console\\descriptor\\jsondescriptor' => '/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php', - 'symfony\\component\\console\\descriptor\\markdowndescriptor' => '/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php', - 'symfony\\component\\console\\descriptor\\textdescriptor' => '/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php', - 'symfony\\component\\console\\descriptor\\xmldescriptor' => '/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php', - 'symfony\\component\\console\\event\\consolecommandevent' => '/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php', - 'symfony\\component\\console\\event\\consoleevent' => '/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php', - 'symfony\\component\\console\\event\\consoleexceptionevent' => '/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php', - 'symfony\\component\\console\\event\\consoleterminateevent' => '/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php', - 'symfony\\component\\console\\formatter\\outputformatter' => '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php', - 'symfony\\component\\console\\formatter\\outputformatterinterface' => '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php', - 'symfony\\component\\console\\formatter\\outputformatterstyle' => '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php', - 'symfony\\component\\console\\formatter\\outputformatterstyleinterface' => '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php', - 'symfony\\component\\console\\formatter\\outputformatterstylestack' => '/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php', - 'symfony\\component\\console\\helper\\descriptorhelper' => '/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php', - 'symfony\\component\\console\\helper\\dialoghelper' => '/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php', - 'symfony\\component\\console\\helper\\formatterhelper' => '/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php', - 'symfony\\component\\console\\helper\\helper' => '/symfony/console/Symfony/Component/Console/Helper/Helper.php', - 'symfony\\component\\console\\helper\\helperinterface' => '/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php', - 'symfony\\component\\console\\helper\\helperset' => '/symfony/console/Symfony/Component/Console/Helper/HelperSet.php', - 'symfony\\component\\console\\helper\\inputawarehelper' => '/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php', - 'symfony\\component\\console\\helper\\progresshelper' => '/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php', - 'symfony\\component\\console\\helper\\tablehelper' => '/symfony/console/Symfony/Component/Console/Helper/TableHelper.php', - 'symfony\\component\\console\\input\\argvinput' => '/symfony/console/Symfony/Component/Console/Input/ArgvInput.php', - 'symfony\\component\\console\\input\\arrayinput' => '/symfony/console/Symfony/Component/Console/Input/ArrayInput.php', - 'symfony\\component\\console\\input\\input' => '/symfony/console/Symfony/Component/Console/Input/Input.php', - 'symfony\\component\\console\\input\\inputargument' => '/symfony/console/Symfony/Component/Console/Input/InputArgument.php', - 'symfony\\component\\console\\input\\inputawareinterface' => '/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php', - 'symfony\\component\\console\\input\\inputdefinition' => '/symfony/console/Symfony/Component/Console/Input/InputDefinition.php', - 'symfony\\component\\console\\input\\inputinterface' => '/symfony/console/Symfony/Component/Console/Input/InputInterface.php', - 'symfony\\component\\console\\input\\inputoption' => '/symfony/console/Symfony/Component/Console/Input/InputOption.php', - 'symfony\\component\\console\\input\\stringinput' => '/symfony/console/Symfony/Component/Console/Input/StringInput.php', - 'symfony\\component\\console\\output\\bufferedoutput' => '/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php', - 'symfony\\component\\console\\output\\consoleoutput' => '/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php', - 'symfony\\component\\console\\output\\consoleoutputinterface' => '/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php', - 'symfony\\component\\console\\output\\nulloutput' => '/symfony/console/Symfony/Component/Console/Output/NullOutput.php', - 'symfony\\component\\console\\output\\output' => '/symfony/console/Symfony/Component/Console/Output/Output.php', - 'symfony\\component\\console\\output\\outputinterface' => '/symfony/console/Symfony/Component/Console/Output/OutputInterface.php', - 'symfony\\component\\console\\output\\streamoutput' => '/symfony/console/Symfony/Component/Console/Output/StreamOutput.php', - 'symfony\\component\\console\\shell' => '/symfony/console/Symfony/Component/Console/Shell.php', - 'symfony\\component\\console\\tester\\applicationtester' => '/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php', - 'symfony\\component\\console\\tester\\commandtester' => '/symfony/console/Symfony/Component/Console/Tester/CommandTester.php', - 'symfony\\component\\finder\\adapter\\abstractadapter' => '/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php', - 'symfony\\component\\finder\\adapter\\abstractfindadapter' => '/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php', - 'symfony\\component\\finder\\adapter\\adapterinterface' => '/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php', - 'symfony\\component\\finder\\adapter\\bsdfindadapter' => '/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php', - 'symfony\\component\\finder\\adapter\\gnufindadapter' => '/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php', - 'symfony\\component\\finder\\adapter\\phpadapter' => '/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php', - 'symfony\\component\\finder\\comparator\\comparator' => '/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php', - 'symfony\\component\\finder\\comparator\\datecomparator' => '/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php', - 'symfony\\component\\finder\\comparator\\numbercomparator' => '/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php', - 'symfony\\component\\finder\\exception\\accessdeniedexception' => '/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php', - 'symfony\\component\\finder\\exception\\adapterfailureexception' => '/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php', - 'symfony\\component\\finder\\exception\\exceptioninterface' => '/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php', - 'symfony\\component\\finder\\exception\\operationnotpermitedexception' => '/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php', - 'symfony\\component\\finder\\exception\\shellcommandfailureexception' => '/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php', - 'symfony\\component\\finder\\expression\\expression' => '/symfony/finder/Symfony/Component/Finder/Expression/Expression.php', - 'symfony\\component\\finder\\expression\\glob' => '/symfony/finder/Symfony/Component/Finder/Expression/Glob.php', - 'symfony\\component\\finder\\expression\\regex' => '/symfony/finder/Symfony/Component/Finder/Expression/Regex.php', - 'symfony\\component\\finder\\expression\\valueinterface' => '/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php', - 'symfony\\component\\finder\\finder' => '/symfony/finder/Symfony/Component/Finder/Finder.php', - 'symfony\\component\\finder\\glob' => '/symfony/finder/Symfony/Component/Finder/Glob.php', - 'symfony\\component\\finder\\iterator\\customfilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php', - 'symfony\\component\\finder\\iterator\\daterangefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php', - 'symfony\\component\\finder\\iterator\\depthrangefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php', - 'symfony\\component\\finder\\iterator\\excludedirectoryfilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php', - 'symfony\\component\\finder\\iterator\\filecontentfilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php', - 'symfony\\component\\finder\\iterator\\filenamefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php', - 'symfony\\component\\finder\\iterator\\filepathsiterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php', - 'symfony\\component\\finder\\iterator\\filetypefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php', - 'symfony\\component\\finder\\iterator\\filteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php', - 'symfony\\component\\finder\\iterator\\multiplepcrefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php', - 'symfony\\component\\finder\\iterator\\pathfilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php', - 'symfony\\component\\finder\\iterator\\recursivedirectoryiterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php', - 'symfony\\component\\finder\\iterator\\sizerangefilteriterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php', - 'symfony\\component\\finder\\iterator\\sortableiterator' => '/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php', - 'symfony\\component\\finder\\shell\\command' => '/symfony/finder/Symfony/Component/Finder/Shell/Command.php', - 'symfony\\component\\finder\\shell\\shell' => '/symfony/finder/Symfony/Component/Finder/Shell/Shell.php', - 'symfony\\component\\finder\\splfileinfo' => '/symfony/finder/Symfony/Component/Finder/SplFileInfo.php', - 'symfony\\component\\yaml\\dumper' => '/symfony/yaml/Symfony/Component/Yaml/Dumper.php', - 'symfony\\component\\yaml\\escaper' => '/symfony/yaml/Symfony/Component/Yaml/Escaper.php', - 'symfony\\component\\yaml\\exception\\dumpexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php', - 'symfony\\component\\yaml\\exception\\exceptioninterface' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php', - 'symfony\\component\\yaml\\exception\\parseexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php', - 'symfony\\component\\yaml\\exception\\runtimeexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php', - 'symfony\\component\\yaml\\inline' => '/symfony/yaml/Symfony/Component/Yaml/Inline.php', - 'symfony\\component\\yaml\\parser' => '/symfony/yaml/Symfony/Component/Yaml/Parser.php', - 'symfony\\component\\yaml\\unescaper' => '/symfony/yaml/Symfony/Component/Yaml/Unescaper.php', - 'symfony\\component\\yaml\\yaml' => '/symfony/yaml/Symfony/Component/Yaml/Yaml.php', - 'theseer\\fdom\\css\\dollarequalrule' => '/fdomdocument/css/DollarEqualRule.php', - 'theseer\\fdom\\css\\notrule' => '/fdomdocument/css/NotRule.php', - 'theseer\\fdom\\css\\nthchildrule' => '/fdomdocument/css/NthChildRule.php', - 'theseer\\fdom\\css\\regexrule' => '/fdomdocument/css/RegexRule.php', - 'theseer\\fdom\\css\\ruleinterface' => '/fdomdocument/css/RuleInterface.php', - 'theseer\\fdom\\css\\translator' => '/fdomdocument/css/Translator.php', - 'theseer\\fdom\\fdomdocument' => '/fdomdocument/fDOMDocument.php', - 'theseer\\fdom\\fdomdocumentfragment' => '/fdomdocument/fDOMDocumentFragment.php', - 'theseer\\fdom\\fdomelement' => '/fdomdocument/fDOMElement.php', - 'theseer\\fdom\\fdomexception' => '/fdomdocument/fDOMException.php', - 'theseer\\fdom\\fdomnode' => '/fdomdocument/fDOMNode.php', - 'theseer\\fdom\\fdomxpath' => '/fdomdocument/fDOMXPath.php', - 'theseer\\fdom\\xpathquery' => '/fdomdocument/XPathQuery.php', - 'theseer\\fdom\\xpathqueryexception' => '/fdomdocument/XPathQueryException.php' - ); - } - - $class = strtolower($class); - - if (isset($classes[$class])) { - require 'phar://phpdcd-1.0.2.phar' . $classes[$class]; - } - } -); - -Phar::mapPhar('phpdcd-1.0.2.phar'); - -if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') { - print file_get_contents(__PHPDCD_PHAR_ROOT__ . '/manifest.txt'); - exit; -} - -$application = new SebastianBergmann\PHPDCD\CLI\Application; -$application->run(); - -__HALT_COMPILER(); ?> -³)|phpdcd-1.0.2.pharCsymfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php§\S… ¶Bsymfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.phpæ -§\Sæ -â}]¶Bsymfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.phpñ -§\Sñ -èÝkA¶Gsymfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php˜)§\S˜)QJ>symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php{ -§\S{ -9!2¶Dsymfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php± §\S± Г¶0symfony/finder/Symfony/Component/Finder/Glob.phpb §\Sb œg@M¶Fsymfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php’ -§\S’ -¸›É”¶Ksymfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.phpb§\Sbýn ¶Esymfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.phpñ §\Sñ þíjû¶Csymfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.phpŸ§\SŸã½,G¶Nsymfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.phpž§\SžÂʽ¶Lsymfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php¥§\S¥x¹P»¶Ssymfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.phpœ§\Sœ±d”¶Msymfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.phpñ§\Sñils_¶Osymfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.phpî§\Sî - -²¶Osymfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.phpç §\Sç éŸ6s¶Ksymfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php½§\S½{à^ǶIsymfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php§\S¼z"¶Gsymfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php¨§\S¨…±Æ)¶Lsymfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.phpµ§\Sµ ÎàU¶Gsymfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php -§\S -¾PÁ¶Asymfony/finder/Symfony/Component/Finder/Comparator/Comparator.php -§\S -|F z¶Esymfony/finder/Symfony/Component/Finder/Comparator/DateComparator.phpº§\Sº§ÓÑ ¶9symfony/finder/Symfony/Component/Finder/Shell/Command.php˜§\S˜5‹´K¶7symfony/finder/Symfony/Component/Finder/Shell/Shell.php…§\S…á4˵¶Ssymfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php¢§\S¢P¶£™¶Msymfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php§\S>Ã@¶Ksymfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php«§\S«ÊcWÞ¶Hsymfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.phpï§\Sï€7¶Rsymfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php9§\S9²¼¶2symfony/finder/Symfony/Component/Finder/Finder.phpÞV§\SÞV»d¶7symfony/finder/Symfony/Component/Finder/SplFileInfo.php§\Sþ59¶Esymfony/finder/Symfony/Component/Finder/Expression/ValueInterface.phpH§\SHÐø"¶;symfony/finder/Symfony/Component/Finder/Expression/Glob.php§\SŠE±¶Asymfony/finder/Symfony/Component/Finder/Expression/Expression.php& -§\S& - 뇶<symfony/finder/Symfony/Component/Finder/Expression/Regex.php§\S¶É(Ú¶,symfony/yaml/Symfony/Component/Yaml/Yaml.php §\S 7MÓº¶/symfony/yaml/Symfony/Component/Yaml/Escaper.phpm §\Sm )%È,¶.symfony/yaml/Symfony/Component/Yaml/Parser.php–[§\S–[û¿X½¶.symfony/yaml/Symfony/Component/Yaml/Dumper.php” §\S” 8¹n¶1symfony/yaml/Symfony/Component/Yaml/Unescaper.phpŸ§\SŸ6£H ¶?symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.phpÒ§\SÒؙ՚¶Dsymfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.phpƧ\SÆî+­l¶@symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.phpî §\Sî ®¿œ›¶Bsymfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.phpð§\SðÏ|-¶.symfony/yaml/Symfony/Component/Yaml/Inline.php£?§\S£?q+Î3¶;symfony/console/Symfony/Component/Console/ConsoleEvents.phpø§\Sø\0ÂE¶Gsymfony/console/Symfony/Component/Console/Formatter/OutputFormatter.phpŧ\SůŒlì¶Psymfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.phpã§\SãJpù˶Lsymfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php&§\S&oÇŒŒ¶Usymfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.phpŸ§\SŸ5¦¶Qsymfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.phpä -§\Sä -ùv ª¶Dsymfony/console/Symfony/Component/Console/Helper/HelperInterface.phpó§\Só z…׶Dsymfony/console/Symfony/Component/Console/Helper/FormatterHelper.php¼§\S¼g¶se¶@symfony/console/Symfony/Component/Console/Helper/TableHelper.php2§\S2ë¡¿¶Esymfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php -§\S -"U¥1¶Esymfony/console/Symfony/Component/Console/Helper/InputAwareHelper.phpë§\Sësß H¶Csymfony/console/Symfony/Component/Console/Helper/ProgressHelper.phpo.§\So.|p¶Asymfony/console/Symfony/Component/Console/Helper/DialogHelper.php>@§\S>@&â¶;symfony/console/Symfony/Component/Console/Helper/Helper.php«§\S«Z\§¶>symfony/console/Symfony/Component/Console/Helper/HelperSet.phpÞ §\SÞ •¹¶Bsymfony/console/Symfony/Component/Console/Tester/CommandTester.php§\S~H(R¶Fsymfony/console/Symfony/Component/Console/Tester/ApplicationTester.phpf §\Sf ƒhr¥¶Ksymfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.phpK§\SKìÅ0ž¶;symfony/console/Symfony/Component/Console/Output/Output.php;§\S;séÁQ¶Asymfony/console/Symfony/Component/Console/Output/StreamOutput.phpM §\SM Œ,Q«¶Bsymfony/console/Symfony/Component/Console/Output/ConsoleOutput.php} §\S} Ãϱ¶?symfony/console/Symfony/Component/Console/Output/NullOutput.phpÔ§\SÔF£$_¶Csymfony/console/Symfony/Component/Console/Output/BufferedOutput.phph§\Sht|X4¶Dsymfony/console/Symfony/Component/Console/Output/OutputInterface.phpM §\SM ŽÕzˆ¶Csymfony/console/Symfony/Component/Console/Descriptor/Descriptor.php¼ §\S¼ ‰mª¶Fsymfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.phpð%§\Sð%ﶲͶGsymfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.phpø§\Sø¹ø¶Ksymfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php.§\S.ªlP¾¶Osymfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php¹ §\S¹ ¿s¤X¶Gsymfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.phpu§\SuD„®¶Lsymfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.phpá§\SáJZ0<¶Isymfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php&§\S&´Z–¤¶@symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php¸§\S¸¾õ -ž¶Gsymfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.phpÀ§\SÀ||-&¶Isymfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.phpA§\SAs¤K¶>symfony/console/Symfony/Component/Console/Input/ArrayInput.php%§\S%p¶²—¶?symfony/console/Symfony/Component/Console/Input/StringInput.phpû -§\Sû -«Î‚=¶Csymfony/console/Symfony/Component/Console/Input/InputDefinition.php(0§\S(01áE¶Bsymfony/console/Symfony/Component/Console/Input/InputInterface.php6§\S6ÅAM¶Asymfony/console/Symfony/Component/Console/Input/InputArgument.php× §\S× ‚š'¶Gsymfony/console/Symfony/Component/Console/Input/InputAwareInterface.php^§\S^9Kèh¶?symfony/console/Symfony/Component/Console/Input/InputOption.phpV§\SV¬ÓOö9symfony/console/Symfony/Component/Console/Input/Input.php§\Sgm(¶=symfony/console/Symfony/Component/Console/Input/ArgvInput.php¸)§\S¸)ÑQ¶Asymfony/console/Symfony/Component/Console/Command/HelpCommand.php_ -§\S_ -’m¶=symfony/console/Symfony/Component/Console/Command/Command.php7@§\S7@ðƘª¶Asymfony/console/Symfony/Component/Console/Command/ListCommand.phpÀ -§\SÀ - x­¶9symfony/console/Symfony/Component/Console/Application.phpÒŠ§\SÒŠ­LûU¶3symfony/console/Symfony/Component/Console/Shell.phpû§\Sû2V¶src/Log/Text.php §\S nÙ¶Ú¶src/Analyser.phpE7§\SE7Ë0Qð¶src/Detector.phpá§\SáwHx?¶src/CLI/Command.php&§\S&âUIñ¶src/CLI/Application.php,§\S,<»U¶ manifest.txtÔ§\SԜʵͶversion/Version.php §\S YÓ ¶finder-facade/FinderFacade.phpѧ\SÑÕ­±¶finder-facade/Configuration.php{§\S{r˜¡¾¶fdomdocument/fDOMElement.php@0§\S@0œÛ,G¶fdomdocument/fDOMNode.phpí§\Sí¢ו¶fdomdocument/XPathQuery.phpj§\Sj€÷–¶fdomdocument/css/NotRule.php˜§\S˜ª!8_¶fdomdocument/css/Translator.php‚§\S‚0²L3¶!fdomdocument/css/NthChildRule.phpk§\Skf²]œ¶fdomdocument/css/RegexRule.phpǧ\SÇù®s¶$fdomdocument/css/DollarEqualRule.phpw§\Sw} ض"fdomdocument/css/RuleInterface.phpЧ\SÐÎ,—á¶fdomdocument/fDOMXPath.phpç§\S窮<[¶$fdomdocument/XPathQueryException.phpø§\SøÙÖ¶fdomdocument/fDOMException.php¨§\S¨BÕ%¶fdomdocument/autoload.php¾§\S¾!åH¶fdomdocument/fDOMDocument.php¯R§\S¯Re?¶%fdomdocument/fDOMDocumentFragment.php: §\S: §<še¶php-timer/Timer.php6§\S6#X6ñ¶0php-token-stream/Token/Stream/CachingFactory.phpø §\Sø Ó’Õ¶!php-token-stream/Token/Stream.phpuD§\SuDršSͶphp-token-stream/Token.php\§\S\C2ÿ}¶ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -/** - * Interface for finder engine implementations. - * - * @author Jean-François Simon - */ -abstract class AbstractAdapter implements AdapterInterface -{ - protected $followLinks = false; - protected $mode = 0; - protected $minDepth = 0; - protected $maxDepth = PHP_INT_MAX; - protected $exclude = array(); - protected $names = array(); - protected $notNames = array(); - protected $contains = array(); - protected $notContains = array(); - protected $sizes = array(); - protected $dates = array(); - protected $filters = array(); - protected $sort = false; - protected $paths = array(); - protected $notPaths = array(); - protected $ignoreUnreadableDirs = false; - - private static $areSupported = array(); - - /** - * {@inheritDoc} - */ - public function isSupported() - { - $name = $this->getName(); - - if (!array_key_exists($name, self::$areSupported)) { - self::$areSupported[$name] = $this->canBeUsed(); - } - - return self::$areSupported[$name]; - } - - /** - * {@inheritdoc} - */ - public function setFollowLinks($followLinks) - { - $this->followLinks = $followLinks; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setMode($mode) - { - $this->mode = $mode; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setDepths(array $depths) - { - $this->minDepth = 0; - $this->maxDepth = PHP_INT_MAX; - - foreach ($depths as $comparator) { - switch ($comparator->getOperator()) { - case '>': - $this->minDepth = $comparator->getTarget() + 1; - break; - case '>=': - $this->minDepth = $comparator->getTarget(); - break; - case '<': - $this->maxDepth = $comparator->getTarget() - 1; - break; - case '<=': - $this->maxDepth = $comparator->getTarget(); - break; - default: - $this->minDepth = $this->maxDepth = $comparator->getTarget(); - } - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setExclude(array $exclude) - { - $this->exclude = $exclude; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setNames(array $names) - { - $this->names = $names; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setNotNames(array $notNames) - { - $this->notNames = $notNames; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setContains(array $contains) - { - $this->contains = $contains; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setNotContains(array $notContains) - { - $this->notContains = $notContains; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setSizes(array $sizes) - { - $this->sizes = $sizes; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setDates(array $dates) - { - $this->dates = $dates; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setFilters(array $filters) - { - $this->filters = $filters; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setSort($sort) - { - $this->sort = $sort; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setPath(array $paths) - { - $this->paths = $paths; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setNotPath(array $notPaths) - { - $this->notPaths = $notPaths; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function ignoreUnreadableDirs($ignore = true) - { - $this->ignoreUnreadableDirs = (Boolean) $ignore; - - return $this; - } - - /** - * Returns whether the adapter is supported in the current environment. - * - * This method should be implemented in all adapters. Do not implement - * isSupported in the adapters as the generic implementation provides a cache - * layer. - * - * @see isSupported - * - * @return Boolean Whether the adapter is supported - */ - abstract protected function canBeUsed(); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -use Symfony\Component\Finder\Shell\Shell; -use Symfony\Component\Finder\Shell\Command; -use Symfony\Component\Finder\Iterator\SortableIterator; -use Symfony\Component\Finder\Expression\Expression; - -/** - * Shell engine implementation using GNU find command. - * - * @author Jean-François Simon - */ -class GnuFindAdapter extends AbstractFindAdapter -{ - /** - * {@inheritdoc} - */ - public function getName() - { - return 'gnu_find'; - } - - /** - * {@inheritdoc} - */ - protected function buildFormatSorting(Command $command, $sort) - { - switch ($sort) { - case SortableIterator::SORT_BY_NAME: - $command->ins('sort')->add('| sort'); - - return; - case SortableIterator::SORT_BY_TYPE: - $format = '%y'; - break; - case SortableIterator::SORT_BY_ACCESSED_TIME: - $format = '%A@'; - break; - case SortableIterator::SORT_BY_CHANGED_TIME: - $format = '%C@'; - break; - case SortableIterator::SORT_BY_MODIFIED_TIME: - $format = '%T@'; - break; - default: - throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort)); - } - - $command - ->get('find') - ->add('-printf') - ->arg($format.' %h/%f\\n') - ->add('| sort | cut') - ->arg('-d ') - ->arg('-f2-') - ; - } - - /** - * {@inheritdoc} - */ - protected function canBeUsed() - { - return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed(); - } - - /** - * {@inheritdoc} - */ - protected function buildFindCommand(Command $command, $dir) - { - return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended'); - } - - /** - * {@inheritdoc} - */ - protected function buildContentFiltering(Command $command, array $contains, $not = false) - { - foreach ($contains as $contain) { - $expr = Expression::create($contain); - - // todo: avoid forking process for each $pattern by using multiple -e options - $command - ->add('| xargs -I{} -r grep -I') - ->add($expr->isCaseSensitive() ? null : '-i') - ->add($not ? '-L' : '-l') - ->add('-Ee')->arg($expr->renderPattern()) - ->add('{}') - ; - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -use Symfony\Component\Finder\Shell\Shell; -use Symfony\Component\Finder\Shell\Command; -use Symfony\Component\Finder\Iterator\SortableIterator; -use Symfony\Component\Finder\Expression\Expression; - -/** - * Shell engine implementation using BSD find command. - * - * @author Jean-François Simon - */ -class BsdFindAdapter extends AbstractFindAdapter -{ - /** - * {@inheritdoc} - */ - public function getName() - { - return 'bsd_find'; - } - - /** - * {@inheritdoc} - */ - protected function canBeUsed() - { - return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed(); - } - - /** - * {@inheritdoc} - */ - protected function buildFormatSorting(Command $command, $sort) - { - switch ($sort) { - case SortableIterator::SORT_BY_NAME: - $command->ins('sort')->add('| sort'); - - return; - case SortableIterator::SORT_BY_TYPE: - $format = '%HT'; - break; - case SortableIterator::SORT_BY_ACCESSED_TIME: - $format = '%a'; - break; - case SortableIterator::SORT_BY_CHANGED_TIME: - $format = '%c'; - break; - case SortableIterator::SORT_BY_MODIFIED_TIME: - $format = '%m'; - break; - default: - throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort)); - } - - $command - ->add('-print0 | xargs -0 stat -f') - ->arg($format.'%t%N') - ->add('| sort | cut -f 2'); - } - - /** - * {@inheritdoc} - */ - protected function buildFindCommand(Command $command, $dir) - { - parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1); - - return $command; - } - - /** - * {@inheritdoc} - */ - protected function buildContentFiltering(Command $command, array $contains, $not = false) - { - foreach ($contains as $contain) { - $expr = Expression::create($contain); - - // todo: avoid forking process for each $pattern by using multiple -e options - $command - ->add('| grep -v \'^$\'') - ->add('| xargs -I{} grep -I') - ->add($expr->isCaseSensitive() ? null : '-i') - ->add($not ? '-L' : '-l') - ->add('-Ee')->arg($expr->renderPattern()) - ->add('{}') - ; - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -use Symfony\Component\Finder\Exception\AccessDeniedException; -use Symfony\Component\Finder\Iterator; -use Symfony\Component\Finder\Shell\Shell; -use Symfony\Component\Finder\Expression\Expression; -use Symfony\Component\Finder\Shell\Command; -use Symfony\Component\Finder\Iterator\SortableIterator; -use Symfony\Component\Finder\Comparator\NumberComparator; -use Symfony\Component\Finder\Comparator\DateComparator; - -/** - * Shell engine implementation using GNU find command. - * - * @author Jean-François Simon - */ -abstract class AbstractFindAdapter extends AbstractAdapter -{ - /** - * @var Shell - */ - protected $shell; - - /** - * Constructor. - */ - public function __construct() - { - $this->shell = new Shell(); - } - - /** - * {@inheritdoc} - */ - public function searchInDirectory($dir) - { - // having "/../" in path make find fail - $dir = realpath($dir); - - // searching directories containing or not containing strings leads to no result - if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) { - return new Iterator\FilePathsIterator(array(), $dir); - } - - $command = Command::create(); - $find = $this->buildFindCommand($command, $dir); - - if ($this->followLinks) { - $find->add('-follow'); - } - - $find->add('-mindepth')->add($this->minDepth + 1); - - if (PHP_INT_MAX !== $this->maxDepth) { - $find->add('-maxdepth')->add($this->maxDepth + 1); - } - - if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) { - $find->add('-type d'); - } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) { - $find->add('-type f'); - } - - $this->buildNamesFiltering($find, $this->names); - $this->buildNamesFiltering($find, $this->notNames, true); - $this->buildPathsFiltering($find, $dir, $this->paths); - $this->buildPathsFiltering($find, $dir, $this->notPaths, true); - $this->buildSizesFiltering($find, $this->sizes); - $this->buildDatesFiltering($find, $this->dates); - - $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs'); - $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut'); - - if ($useGrep && ($this->contains || $this->notContains)) { - $grep = $command->ins('grep'); - $this->buildContentFiltering($grep, $this->contains); - $this->buildContentFiltering($grep, $this->notContains, true); - } - - if ($useSort) { - $this->buildSorting($command, $this->sort); - } - - $command->setErrorHandler( - $this->ignoreUnreadableDirs - // If directory is unreadable and finder is set to ignore it, `stderr` is ignored. - ? function ($stderr) { return; } - : function ($stderr) { throw new AccessDeniedException($stderr); } - ); - - $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute()); - $iterator = new Iterator\FilePathsIterator($paths, $dir); - - if ($this->exclude) { - $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude); - } - - if (!$useGrep && ($this->contains || $this->notContains)) { - $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains); - } - - if ($this->filters) { - $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); - } - - if (!$useSort && $this->sort) { - $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort); - $iterator = $iteratorAggregate->getIterator(); - } - - return $iterator; - } - - /** - * {@inheritdoc} - */ - protected function canBeUsed() - { - return $this->shell->testCommand('find'); - } - - /** - * @param Command $command - * @param string $dir - * - * @return Command - */ - protected function buildFindCommand(Command $command, $dir) - { - return $command - ->ins('find') - ->add('find ') - ->arg($dir) - ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions - } - - /** - * @param Command $command - * @param string[] $names - * @param Boolean $not - */ - private function buildNamesFiltering(Command $command, array $names, $not = false) - { - if (0 === count($names)) { - return; - } - - $command->add($not ? '-not' : null)->cmd('('); - - foreach ($names as $i => $name) { - $expr = Expression::create($name); - - // Find does not support expandable globs ("*.{a,b}" syntax). - if ($expr->isGlob() && $expr->getGlob()->isExpandable()) { - $expr = Expression::create($expr->getGlob()->toRegex(false)); - } - - // Fixes 'not search' and 'full path matching' regex problems. - // - Jokers '.' are replaced by [^/]. - // - We add '[^/]*' before and after regex (if no ^|$ flags are present). - if ($expr->isRegex()) { - $regex = $expr->getRegex(); - $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*') - ->setStartFlag(false) - ->setStartJoker(true) - ->replaceJokers('[^/]'); - if (!$regex->hasEndFlag() || $regex->hasEndJoker()) { - $regex->setEndJoker(false)->append('[^/]*'); - } - } - - $command - ->add($i > 0 ? '-or' : null) - ->add($expr->isRegex() - ? ($expr->isCaseSensitive() ? '-regex' : '-iregex') - : ($expr->isCaseSensitive() ? '-name' : '-iname') - ) - ->arg($expr->renderPattern()); - } - - $command->cmd(')'); - } - - /** - * @param Command $command - * @param string $dir - * @param string[] $paths - * @param Boolean $not - */ - private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false) - { - if (0 === count($paths)) { - return; - } - - $command->add($not ? '-not' : null)->cmd('('); - - foreach ($paths as $i => $path) { - $expr = Expression::create($path); - - // Find does not support expandable globs ("*.{a,b}" syntax). - if ($expr->isGlob() && $expr->getGlob()->isExpandable()) { - $expr = Expression::create($expr->getGlob()->toRegex(false)); - } - - // Fixes 'not search' regex problems. - if ($expr->isRegex()) { - $regex = $expr->getRegex(); - $regex->prepend($regex->hasStartFlag() ? $dir.DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag()); - } else { - $expr->prepend('*')->append('*'); - } - - $command - ->add($i > 0 ? '-or' : null) - ->add($expr->isRegex() - ? ($expr->isCaseSensitive() ? '-regex' : '-iregex') - : ($expr->isCaseSensitive() ? '-path' : '-ipath') - ) - ->arg($expr->renderPattern()); - } - - $command->cmd(')'); - } - - /** - * @param Command $command - * @param NumberComparator[] $sizes - */ - private function buildSizesFiltering(Command $command, array $sizes) - { - foreach ($sizes as $i => $size) { - $command->add($i > 0 ? '-and' : null); - - switch ($size->getOperator()) { - case '<=': - $command->add('-size -'.($size->getTarget() + 1).'c'); - break; - case '>=': - $command->add('-size +'. ($size->getTarget() - 1).'c'); - break; - case '>': - $command->add('-size +'.$size->getTarget().'c'); - break; - case '!=': - $command->add('-size -'.$size->getTarget().'c'); - $command->add('-size +'.$size->getTarget().'c'); - case '<': - default: - $command->add('-size -'.$size->getTarget().'c'); - } - } - } - - /** - * @param Command $command - * @param DateComparator[] $dates - */ - private function buildDatesFiltering(Command $command, array $dates) - { - foreach ($dates as $i => $date) { - $command->add($i > 0 ? '-and' : null); - - $mins = (int) round((time()-$date->getTarget()) / 60); - - if (0 > $mins) { - // mtime is in the future - $command->add(' -mmin -0'); - // we will have no result so we don't need to continue - return; - } - - switch ($date->getOperator()) { - case '<=': - $command->add('-mmin +'.($mins - 1)); - break; - case '>=': - $command->add('-mmin -'.($mins + 1)); - break; - case '>': - $command->add('-mmin -'.$mins); - break; - case '!=': - $command->add('-mmin +'.$mins.' -or -mmin -'.$mins); - break; - case '<': - default: - $command->add('-mmin +'.$mins); - } - } - } - - /** - * @param Command $command - * @param string $sort - * - * @throws \InvalidArgumentException - */ - private function buildSorting(Command $command, $sort) - { - $this->buildFormatSorting($command, $sort); - } - - /** - * @param Command $command - * @param string $sort - */ - abstract protected function buildFormatSorting(Command $command, $sort); - - /** - * @param Command $command - * @param array $contains - * @param Boolean $not - */ - abstract protected function buildContentFiltering(Command $command, array $contains, $not = false); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -use Symfony\Component\Finder\Iterator; - -/** - * PHP finder engine implementation. - * - * @author Jean-François Simon - */ -class PhpAdapter extends AbstractAdapter -{ - /** - * {@inheritdoc} - */ - public function searchInDirectory($dir) - { - $flags = \RecursiveDirectoryIterator::SKIP_DOTS; - - if ($this->followLinks) { - $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS; - } - - $iterator = new \RecursiveIteratorIterator( - new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs), - \RecursiveIteratorIterator::SELF_FIRST - ); - - if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) { - $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth); - } - - if ($this->mode) { - $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode); - } - - if ($this->exclude) { - $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude); - } - - if ($this->names || $this->notNames) { - $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames); - } - - if ($this->contains || $this->notContains) { - $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains); - } - - if ($this->sizes) { - $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes); - } - - if ($this->dates) { - $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates); - } - - if ($this->filters) { - $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); - } - - if ($this->sort) { - $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort); - $iterator = $iteratorAggregate->getIterator(); - } - - if ($this->paths || $this->notPaths) { - $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths); - } - - return $iterator; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'php'; - } - - /** - * {@inheritdoc} - */ - protected function canBeUsed() - { - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Adapter; - -/** - * @author Jean-François Simon - */ -interface AdapterInterface -{ - /** - * @param Boolean $followLinks - * - * @return AdapterInterface Current instance - */ - public function setFollowLinks($followLinks); - - /** - * @param integer $mode - * - * @return AdapterInterface Current instance - */ - public function setMode($mode); - - /** - * @param array $exclude - * - * @return AdapterInterface Current instance - */ - public function setExclude(array $exclude); - - /** - * @param array $depths - * - * @return AdapterInterface Current instance - */ - public function setDepths(array $depths); - - /** - * @param array $names - * - * @return AdapterInterface Current instance - */ - public function setNames(array $names); - - /** - * @param array $notNames - * - * @return AdapterInterface Current instance - */ - public function setNotNames(array $notNames); - - /** - * @param array $contains - * - * @return AdapterInterface Current instance - */ - public function setContains(array $contains); - - /** - * @param array $notContains - * - * @return AdapterInterface Current instance - */ - public function setNotContains(array $notContains); - - /** - * @param array $sizes - * - * @return AdapterInterface Current instance - */ - public function setSizes(array $sizes); - - /** - * @param array $dates - * - * @return AdapterInterface Current instance - */ - public function setDates(array $dates); - - /** - * @param array $filters - * - * @return AdapterInterface Current instance - */ - public function setFilters(array $filters); - - /** - * @param \Closure|integer $sort - * - * @return AdapterInterface Current instance - */ - public function setSort($sort); - - /** - * @param array $paths - * - * @return AdapterInterface Current instance - */ - public function setPath(array $paths); - - /** - * @param array $notPaths - * - * @return AdapterInterface Current instance - */ - public function setNotPath(array $notPaths); - - /** - * @param boolean $ignore - * - * @return AdapterInterface Current instance - */ - public function ignoreUnreadableDirs($ignore = true); - - /** - * @param string $dir - * - * @return \Iterator Result iterator - */ - public function searchInDirectory($dir); - - /** - * Tests adapter support for current platform. - * - * @return Boolean - */ - public function isSupported(); - - /** - * Returns adapter name. - * - * @return string - */ - public function getName(); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder; - -/** - * Glob matches globbing patterns against text. - * - * if match_glob("foo.*", "foo.bar") echo "matched\n"; - * - * // prints foo.bar and foo.baz - * $regex = glob_to_regex("foo.*"); - * for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t) - * { - * if (/$regex/) echo "matched: $car\n"; - * } - * - * Glob implements glob(3) style matching that can be used to match - * against text, rather than fetching names from a filesystem. - * - * Based on the Perl Text::Glob module. - * - * @author Fabien Potencier PHP port - * @author Richard Clamp Perl version - * @copyright 2004-2005 Fabien Potencier - * @copyright 2002 Richard Clamp - */ -class Glob -{ - /** - * Returns a regexp which is the equivalent of the glob pattern. - * - * @param string $glob The glob pattern - * @param Boolean $strictLeadingDot - * @param Boolean $strictWildcardSlash - * - * @return string regex The regexp - */ - public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true) - { - $firstByte = true; - $escaping = false; - $inCurlies = 0; - $regex = ''; - $sizeGlob = strlen($glob); - for ($i = 0; $i < $sizeGlob; $i++) { - $car = $glob[$i]; - if ($firstByte) { - if ($strictLeadingDot && '.' !== $car) { - $regex .= '(?=[^\.])'; - } - - $firstByte = false; - } - - if ('/' === $car) { - $firstByte = true; - } - - if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) { - $regex .= "\\$car"; - } elseif ('*' === $car) { - $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*'); - } elseif ('?' === $car) { - $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.'); - } elseif ('{' === $car) { - $regex .= $escaping ? '\\{' : '('; - if (!$escaping) { - ++$inCurlies; - } - } elseif ('}' === $car && $inCurlies) { - $regex .= $escaping ? '}' : ')'; - if (!$escaping) { - --$inCurlies; - } - } elseif (',' === $car && $inCurlies) { - $regex .= $escaping ? ',' : '|'; - } elseif ('\\' === $car) { - if ($escaping) { - $regex .= '\\\\'; - $escaping = false; - } else { - $escaping = true; - } - - continue; - } else { - $regex .= $car; - } - $escaping = false; - } - - return '#^'.$regex.'$#'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\SplFileInfo; - -/** - * Iterate over shell command result. - * - * @author Jean-François Simon - */ -class FilePathsIterator extends \ArrayIterator -{ - /** - * @var string - */ - private $baseDir; - - /** - * @var int - */ - private $baseDirLength; - - /** - * @var string - */ - private $subPath; - - /** - * @var string - */ - private $subPathname; - - /** - * @var SplFileInfo - */ - private $current; - - /** - * @param array $paths List of paths returned by shell command - * @param string $baseDir Base dir for relative path building - */ - public function __construct(array $paths, $baseDir) - { - $this->baseDir = $baseDir; - $this->baseDirLength = strlen($baseDir); - - parent::__construct($paths); - } - - /** - * @param string $name - * @param array $arguments - * - * @return mixed - */ - public function __call($name, array $arguments) - { - return call_user_func_array(array($this->current(), $name), $arguments); - } - - /** - * Return an instance of SplFileInfo with support for relative paths. - * - * @return SplFileInfo File information - */ - public function current() - { - return $this->current; - } - - /** - * @return string - */ - public function key() - { - return $this->current->getPathname(); - } - - public function next() - { - parent::next(); - $this->buildProperties(); - } - - public function rewind() - { - parent::rewind(); - $this->buildProperties(); - } - - /** - * @return string - */ - public function getSubPath() - { - return $this->subPath; - } - - /** - * @return string - */ - public function getSubPathname() - { - return $this->subPathname; - } - - private function buildProperties() - { - $absolutePath = parent::current(); - - if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) { - $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\'); - $dir = dirname($this->subPathname); - $this->subPath = '.' === $dir ? '' : $dir; - } else { - $this->subPath = $this->subPathname = ''; - } - - $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * FileTypeFilterIterator only keeps files, directories, or both. - * - * @author Fabien Potencier - */ -class FileTypeFilterIterator extends FilterIterator -{ - const ONLY_FILES = 1; - const ONLY_DIRECTORIES = 2; - - private $mode; - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param integer $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES) - */ - public function __construct(\Iterator $iterator, $mode) - { - $this->mode = $mode; - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $fileinfo = $this->current(); - if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { - return false; - } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { - return false; - } - - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * SortableIterator applies a sort on a given Iterator. - * - * @author Fabien Potencier - */ -class SortableIterator implements \IteratorAggregate -{ - const SORT_BY_NAME = 1; - const SORT_BY_TYPE = 2; - const SORT_BY_ACCESSED_TIME = 3; - const SORT_BY_CHANGED_TIME = 4; - const SORT_BY_MODIFIED_TIME = 5; - - private $iterator; - private $sort; - - /** - * Constructor. - * - * @param \Traversable $iterator The Iterator to filter - * @param integer|callback $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback) - * - * @throws \InvalidArgumentException - */ - public function __construct(\Traversable $iterator, $sort) - { - $this->iterator = $iterator; - - if (self::SORT_BY_NAME === $sort) { - $this->sort = function ($a, $b) { - return strcmp($a->getRealpath(), $b->getRealpath()); - }; - } elseif (self::SORT_BY_TYPE === $sort) { - $this->sort = function ($a, $b) { - if ($a->isDir() && $b->isFile()) { - return -1; - } elseif ($a->isFile() && $b->isDir()) { - return 1; - } - - return strcmp($a->getRealpath(), $b->getRealpath()); - }; - } elseif (self::SORT_BY_ACCESSED_TIME === $sort) { - $this->sort = function ($a, $b) { - return ($a->getATime() > $b->getATime()); - }; - } elseif (self::SORT_BY_CHANGED_TIME === $sort) { - $this->sort = function ($a, $b) { - return ($a->getCTime() > $b->getCTime()); - }; - } elseif (self::SORT_BY_MODIFIED_TIME === $sort) { - $this->sort = function ($a, $b) { - return ($a->getMTime() > $b->getMTime()); - }; - } elseif (is_callable($sort)) { - $this->sort = $sort; - } else { - throw new \InvalidArgumentException('The SortableIterator takes a PHP callback or a valid built-in sort algorithm as an argument.'); - } - } - - public function getIterator() - { - $array = iterator_to_array($this->iterator, true); - uasort($array, $this->sort); - - return new \ArrayIterator($array); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * This iterator just overrides the rewind method in order to correct a PHP bug. - * - * @see https://bugs.php.net/bug.php?id=49104 - * - * @author Alex Bogomazov - */ -abstract class FilterIterator extends \FilterIterator -{ - /** - * This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after - * rewind in some cases. - * - * @see FilterIterator::rewind() - */ - public function rewind() - { - $iterator = $this; - while ($iterator instanceof \OuterIterator) { - $innerIterator = $iterator->getInnerIterator(); - - if ($innerIterator instanceof RecursiveDirectoryIterator) { - if ($innerIterator->isRewindable()) { - $innerIterator->next(); - $innerIterator->rewind(); - } - } elseif ($iterator->getInnerIterator() instanceof \FilesystemIterator) { - $iterator->getInnerIterator()->next(); - $iterator->getInnerIterator()->rewind(); - } - $iterator = $iterator->getInnerIterator(); - } - - parent::rewind(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). - * - * @author Fabien Potencier - * @author WÅ‚odzimierz Gajda - */ -class FilecontentFilterIterator extends MultiplePcreFilterIterator -{ - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - if (!$this->matchRegexps && !$this->noMatchRegexps) { - return true; - } - - $fileinfo = $this->current(); - - if ($fileinfo->isDir() || !$fileinfo->isReadable()) { - return false; - } - - $content = $fileinfo->getContents(); - if (!$content) { - return false; - } - - // should at least not match one rule to exclude - foreach ($this->noMatchRegexps as $regex) { - if (preg_match($regex, $content)) { - return false; - } - } - - // should at least match one rule - $match = true; - if ($this->matchRegexps) { - $match = false; - foreach ($this->matchRegexps as $regex) { - if (preg_match($regex, $content)) { - return true; - } - } - } - - return $match; - } - - /** - * Converts string to regexp if necessary. - * - * @param string $str Pattern: string or regexp - * - * @return string regexp corresponding to a given string or regexp - */ - protected function toRegex($str) - { - return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\Comparator\NumberComparator; - -/** - * SizeRangeFilterIterator filters out files that are not in the given size range. - * - * @author Fabien Potencier - */ -class SizeRangeFilterIterator extends FilterIterator -{ - private $comparators = array(); - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param NumberComparator[] $comparators An array of NumberComparator instances - */ - public function __construct(\Iterator $iterator, array $comparators) - { - $this->comparators = $comparators; - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $fileinfo = $this->current(); - if (!$fileinfo->isFile()) { - return true; - } - - $filesize = $fileinfo->getSize(); - foreach ($this->comparators as $compare) { - if (!$compare->test($filesize)) { - return false; - } - } - - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * ExcludeDirectoryFilterIterator filters out directories. - * - * @author Fabien Potencier - */ -class ExcludeDirectoryFilterIterator extends FilterIterator -{ - private $patterns = array(); - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param array $directories An array of directories to exclude - */ - public function __construct(\Iterator $iterator, array $directories) - { - foreach ($directories as $directory) { - $this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#'; - } - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); - $path = strtr($path, '\\', '/'); - foreach ($this->patterns as $pattern) { - if (preg_match($pattern, $path)) { - return false; - } - } - - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * DepthRangeFilterIterator limits the directory depth. - * - * @author Fabien Potencier - */ -class DepthRangeFilterIterator extends FilterIterator -{ - private $minDepth = 0; - - /** - * Constructor. - * - * @param \RecursiveIteratorIterator $iterator The Iterator to filter - * @param int $minDepth The min depth - * @param int $maxDepth The max depth - */ - public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX) - { - $this->minDepth = $minDepth; - $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth); - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - return $this->getInnerIterator()->getDepth() >= $this->minDepth; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\Expression\Expression; - -/** - * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). - * - * @author Fabien Potencier - */ -abstract class MultiplePcreFilterIterator extends FilterIterator -{ - protected $matchRegexps = array(); - protected $noMatchRegexps = array(); - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param array $matchPatterns An array of patterns that need to match - * @param array $noMatchPatterns An array of patterns that need to not match - */ - public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) - { - foreach ($matchPatterns as $pattern) { - $this->matchRegexps[] = $this->toRegex($pattern); - } - - foreach ($noMatchPatterns as $pattern) { - $this->noMatchRegexps[] = $this->toRegex($pattern); - } - - parent::__construct($iterator); - } - - /** - * Checks whether the string is a regex. - * - * @param string $str - * - * @return Boolean Whether the given string is a regex - */ - protected function isRegex($str) - { - return Expression::create($str)->isRegex(); - } - - /** - * Converts string into regexp. - * - * @param string $str Pattern - * - * @return string regexp corresponding to a given string - */ - abstract protected function toRegex($str); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\Exception\AccessDeniedException; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Extends the \RecursiveDirectoryIterator to support relative paths - * - * @author Victor Berchet - */ -class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator -{ - /** - * @var boolean - */ - private $ignoreUnreadableDirs; - - /** - * @var Boolean - */ - private $rewindable; - - /** - * Constructor. - * - * @param string $path - * @param int $flags - * @param boolean $ignoreUnreadableDirs - * - * @throws \RuntimeException - */ - public function __construct($path, $flags, $ignoreUnreadableDirs = false) - { - if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) { - throw new \RuntimeException('This iterator only support returning current as fileinfo.'); - } - - parent::__construct($path, $flags); - $this->ignoreUnreadableDirs = $ignoreUnreadableDirs; - } - - /** - * Return an instance of SplFileInfo with support for relative paths - * - * @return SplFileInfo File information - */ - public function current() - { - return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname()); - } - - /** - * @return \RecursiveIterator - * - * @throws AccessDeniedException - */ - public function getChildren() - { - try { - return parent::getChildren(); - } catch (\UnexpectedValueException $e) { - if ($this->ignoreUnreadableDirs) { - // If directory is unreadable and finder is set to ignore it, a fake empty content is returned. - return new \RecursiveArrayIterator(array()); - } else { - throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e); - } - } - } - - /** - * Do nothing for non rewindable stream - */ - public function rewind() - { - if (false === $this->isRewindable()) { - return; - } - - // @see https://bugs.php.net/bug.php?id=49104 - parent::next(); - - parent::rewind(); - } - - /** - * Checks if the stream is rewindable. - * - * @return Boolean true when the stream is rewindable, false otherwise - */ - public function isRewindable() - { - if (null !== $this->rewindable) { - return $this->rewindable; - } - - if (false !== $stream = @opendir($this->getPath())) { - $infos = stream_get_meta_data($stream); - closedir($stream); - - if ($infos['seekable']) { - return $this->rewindable = true; - } - } - - return $this->rewindable = false; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\Expression\Expression; - -/** - * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string). - * - * @author Fabien Potencier - */ -class FilenameFilterIterator extends MultiplePcreFilterIterator -{ - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $filename = $this->current()->getFilename(); - - // should at least not match one rule to exclude - foreach ($this->noMatchRegexps as $regex) { - if (preg_match($regex, $filename)) { - return false; - } - } - - // should at least match one rule - $match = true; - if ($this->matchRegexps) { - $match = false; - foreach ($this->matchRegexps as $regex) { - if (preg_match($regex, $filename)) { - return true; - } - } - } - - return $match; - } - - /** - * Converts glob to regexp. - * - * PCRE patterns are left unchanged. - * Glob strings are transformed with Glob::toRegex(). - * - * @param string $str Pattern: glob or regexp - * - * @return string regexp corresponding to a given glob or regexp - */ - protected function toRegex($str) - { - return Expression::create($str)->getRegex()->render(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * CustomFilterIterator filters files by applying anonymous functions. - * - * The anonymous function receives a \SplFileInfo and must return false - * to remove files. - * - * @author Fabien Potencier - */ -class CustomFilterIterator extends FilterIterator -{ - private $filters = array(); - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param array $filters An array of PHP callbacks - * - * @throws \InvalidArgumentException - */ - public function __construct(\Iterator $iterator, array $filters) - { - foreach ($filters as $filter) { - if (!is_callable($filter)) { - throw new \InvalidArgumentException('Invalid PHP callback.'); - } - } - $this->filters = $filters; - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $fileinfo = $this->current(); - - foreach ($this->filters as $filter) { - if (false === call_user_func($filter, $fileinfo)) { - return false; - } - } - - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * PathFilterIterator filters files by path patterns (e.g. some/special/dir). - * - * @author Fabien Potencier - * @author WÅ‚odzimierz Gajda - */ -class PathFilterIterator extends MultiplePcreFilterIterator -{ - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $filename = $this->current()->getRelativePathname(); - - if (defined('PHP_WINDOWS_VERSION_MAJOR')) { - $filename = strtr($filename, '\\', '/'); - } - - // should at least not match one rule to exclude - foreach ($this->noMatchRegexps as $regex) { - if (preg_match($regex, $filename)) { - return false; - } - } - - // should at least match one rule - $match = true; - if ($this->matchRegexps) { - $match = false; - foreach ($this->matchRegexps as $regex) { - if (preg_match($regex, $filename)) { - return true; - } - } - } - - return $match; - } - - /** - * Converts strings to regexp. - * - * PCRE patterns are left unchanged. - * - * Default conversion: - * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/' - * - * Use only / as directory separator (on Windows also). - * - * @param string $str Pattern: regexp or dirname. - * - * @return string regexp corresponding to a given string or regexp - */ - protected function toRegex($str) - { - return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -use Symfony\Component\Finder\Comparator\DateComparator; - -/** - * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). - * - * @author Fabien Potencier - */ -class DateRangeFilterIterator extends FilterIterator -{ - private $comparators = array(); - - /** - * Constructor. - * - * @param \Iterator $iterator The Iterator to filter - * @param DateComparator[] $comparators An array of DateComparator instances - */ - public function __construct(\Iterator $iterator, array $comparators) - { - $this->comparators = $comparators; - - parent::__construct($iterator); - } - - /** - * Filters the iterator values. - * - * @return Boolean true if the value should be kept, false otherwise - */ - public function accept() - { - $fileinfo = $this->current(); - - if (!$fileinfo->isFile()) { - return true; - } - - $filedate = $fileinfo->getMTime(); - foreach ($this->comparators as $compare) { - if (!$compare->test($filedate)) { - return false; - } - } - - return true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Comparator; - -/** - * NumberComparator compiles a simple comparison to an anonymous - * subroutine, which you can call with a value to be tested again. - * - * Now this would be very pointless, if NumberCompare didn't understand - * magnitudes. - * - * The target value may use magnitudes of kilobytes (k, ki), - * megabytes (m, mi), or gigabytes (g, gi). Those suffixed - * with an i use the appropriate 2**n version in accordance with the - * IEC standard: http://physics.nist.gov/cuu/Units/binary.html - * - * Based on the Perl Number::Compare module. - * - * @author Fabien Potencier PHP port - * @author Richard Clamp Perl version - * - * @copyright 2004-2005 Fabien Potencier - * @copyright 2002 Richard Clamp - * - * @see http://physics.nist.gov/cuu/Units/binary.html - */ -class NumberComparator extends Comparator -{ - /** - * Constructor. - * - * @param string $test A comparison string - * - * @throws \InvalidArgumentException If the test is not understood - */ - public function __construct($test) - { - if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test)); - } - - $target = $matches[2]; - if (!is_numeric($target)) { - throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target)); - } - if (isset($matches[3])) { - // magnitude - switch (strtolower($matches[3])) { - case 'k': - $target *= 1000; - break; - case 'ki': - $target *= 1024; - break; - case 'm': - $target *= 1000000; - break; - case 'mi': - $target *= 1024*1024; - break; - case 'g': - $target *= 1000000000; - break; - case 'gi': - $target *= 1024*1024*1024; - break; - } - } - - $this->setTarget($target); - $this->setOperator(isset($matches[1]) ? $matches[1] : '=='); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Comparator; - -/** - * Comparator. - * - * @author Fabien Potencier - */ -class Comparator -{ - private $target; - private $operator = '=='; - - /** - * Gets the target value. - * - * @return string The target value - */ - public function getTarget() - { - return $this->target; - } - - /** - * Sets the target value. - * - * @param string $target The target value - */ - public function setTarget($target) - { - $this->target = $target; - } - - /** - * Gets the comparison operator. - * - * @return string The operator - */ - public function getOperator() - { - return $this->operator; - } - - /** - * Sets the comparison operator. - * - * @param string $operator A valid operator - * - * @throws \InvalidArgumentException - */ - public function setOperator($operator) - { - if (!$operator) { - $operator = '=='; - } - - if (!in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) { - throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator)); - } - - $this->operator = $operator; - } - - /** - * Tests against the target. - * - * @param mixed $test A test value - * - * @return Boolean - */ - public function test($test) - { - switch ($this->operator) { - case '>': - return $test > $this->target; - case '>=': - return $test >= $this->target; - case '<': - return $test < $this->target; - case '<=': - return $test <= $this->target; - case '!=': - return $test != $this->target; - } - - return $test == $this->target; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Comparator; - -/** - * DateCompare compiles date comparisons. - * - * @author Fabien Potencier - */ -class DateComparator extends Comparator -{ - - /** - * Constructor. - * - * @param string $test A comparison string - * - * @throws \InvalidArgumentException If the test is not understood - */ - public function __construct($test) - { - if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test)); - } - - try { - $date = new \DateTime($matches[2]); - $target = $date->format('U'); - } catch (\Exception $e) { - throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2])); - } - - $operator = isset($matches[1]) ? $matches[1] : '=='; - if ('since' === $operator || 'after' === $operator) { - $operator = '>'; - } - - if ('until' === $operator || 'before' === $operator) { - $operator = '<'; - } - - $this->setOperator($operator); - $this->setTarget($target); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Shell; - -/** - * @author Jean-François Simon - */ -class Command -{ - /** - * @var Command|null - */ - private $parent; - - /** - * @var array - */ - private $bits = array(); - - /** - * @var array - */ - private $labels = array(); - - /** - * @var \Closure|null - */ - private $errorHandler; - - /** - * Constructor. - * - * @param Command|null $parent Parent command - */ - public function __construct(Command $parent = null) - { - $this->parent = $parent; - } - - /** - * Returns command as string. - * - * @return string - */ - public function __toString() - { - return $this->join(); - } - - /** - * Creates a new Command instance. - * - * @param Command|null $parent Parent command - * - * @return Command New Command instance - */ - public static function create(Command $parent = null) - { - return new self($parent); - } - - /** - * Escapes special chars from input. - * - * @param string $input A string to escape - * - * @return string The escaped string - */ - public static function escape($input) - { - return escapeshellcmd($input); - } - - /** - * Quotes input. - * - * @param string $input An argument string - * - * @return string The quoted string - */ - public static function quote($input) - { - return escapeshellarg($input); - } - - /** - * Appends a string or a Command instance. - * - * @param string|Command $bit - * - * @return Command The current Command instance - */ - public function add($bit) - { - $this->bits[] = $bit; - - return $this; - } - - /** - * Prepends a string or a command instance. - * - * @param string|Command $bit - * - * @return Command The current Command instance - */ - public function top($bit) - { - array_unshift($this->bits, $bit); - - foreach ($this->labels as $label => $index) { - $this->labels[$label] += 1; - } - - return $this; - } - - /** - * Appends an argument, will be quoted. - * - * @param string $arg - * - * @return Command The current Command instance - */ - public function arg($arg) - { - $this->bits[] = self::quote($arg); - - return $this; - } - - /** - * Appends escaped special command chars. - * - * @param string $esc - * - * @return Command The current Command instance - */ - public function cmd($esc) - { - $this->bits[] = self::escape($esc); - - return $this; - } - - /** - * Inserts a labeled command to feed later. - * - * @param string $label The unique label - * - * @return Command The current Command instance - * - * @throws \RuntimeException If label already exists - */ - public function ins($label) - { - if (isset($this->labels[$label])) { - throw new \RuntimeException(sprintf('Label "%s" already exists.', $label)); - } - - $this->bits[] = self::create($this); - $this->labels[$label] = count($this->bits)-1; - - return $this->bits[$this->labels[$label]]; - } - - /** - * Retrieves a previously labeled command. - * - * @param string $label - * - * @return Command The labeled command - * - * @throws \RuntimeException - */ - public function get($label) - { - if (!isset($this->labels[$label])) { - throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label)); - } - - return $this->bits[$this->labels[$label]]; - } - - /** - * Returns parent command (if any). - * - * @return Command Parent command - * - * @throws \RuntimeException If command has no parent - */ - public function end() - { - if (null === $this->parent) { - throw new \RuntimeException('Calling end on root command doesn\'t make sense.'); - } - - return $this->parent; - } - - /** - * Counts bits stored in command. - * - * @return int The bits count - */ - public function length() - { - return count($this->bits); - } - - /** - * @param \Closure $errorHandler - * - * @return Command - */ - public function setErrorHandler(\Closure $errorHandler) - { - $this->errorHandler = $errorHandler; - - return $this; - } - - /** - * @return \Closure|null - */ - public function getErrorHandler() - { - return $this->errorHandler; - } - - /** - * Executes current command. - * - * @return array The command result - * - * @throws \RuntimeException - */ - public function execute() - { - if (null === $this->errorHandler) { - exec($this->join(), $output); - } else { - $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes); - $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY); - - if ($error = stream_get_contents($pipes[2])) { - call_user_func($this->errorHandler, $error); - } - - proc_close($process); - } - - return $output ?: array(); - } - - /** - * Joins bits. - * - * @return string - */ - public function join() - { - return implode(' ', array_filter( - array_map(function ($bit) { - return $bit instanceof Command ? $bit->join() : ($bit ?: null); - }, $this->bits), - function ($bit) { return null !== $bit; } - )); - } - - /** - * Insert a string or a Command instance before the bit at given position $index (index starts from 0). - * - * @param string|Command $bit - * @param integer $index - * - * @return Command The current Command instance - */ - public function addAtIndex($bit, $index) - { - array_splice($this->bits, $index, 0, $bit); - - return $this; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Shell; - -/** - * @author Jean-François Simon - */ -class Shell -{ - const TYPE_UNIX = 1; - const TYPE_DARWIN = 2; - const TYPE_CYGWIN = 3; - const TYPE_WINDOWS = 4; - const TYPE_BSD = 5; - - /** - * @var string|null - */ - private $type; - - /** - * Returns guessed OS type. - * - * @return int - */ - public function getType() - { - if (null === $this->type) { - $this->type = $this->guessType(); - } - - return $this->type; - } - - /** - * Tests if a command is available. - * - * @param string $command - * - * @return bool - */ - public function testCommand($command) - { - if (self::TYPE_WINDOWS === $this->type) { - // todo: find a way to test if Windows command exists - return false; - } - - if (!function_exists('exec')) { - return false; - } - - // todo: find a better way (command could not be available) - exec('command -v '.$command, $output, $code); - - return 0 === $code && count($output) > 0; - } - - /** - * Guesses OS type. - * - * @return int - */ - private function guessType() - { - $os = strtolower(PHP_OS); - - if (false !== strpos($os, 'cygwin')) { - return self::TYPE_CYGWIN; - } - - if (false !== strpos($os, 'darwin')) { - return self::TYPE_DARWIN; - } - - if (false !== strpos($os, 'bsd')) { - return self::TYPE_BSD; - } - - if (0 === strpos($os, 'win')) { - return self::TYPE_WINDOWS; - } - - return self::TYPE_UNIX; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Exception; - -/** - * @author Jean-François Simon - */ -class OperationNotPermitedException extends AdapterFailureException -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Exception; - -use Symfony\Component\Finder\Adapter\AdapterInterface; - -/** - * Base exception for all adapter failures. - * - * @author Jean-François Simon - */ -class AdapterFailureException extends \RuntimeException implements ExceptionInterface -{ - /** - * @var \Symfony\Component\Finder\Adapter\AdapterInterface - */ - private $adapter; - - /** - * @param AdapterInterface $adapter - * @param string|null $message - * @param \Exception|null $previous - */ - public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null) - { - $this->adapter = $adapter; - parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous); - } - - /** - * {@inheritdoc} - */ - public function getAdapter() - { - return $this->adapter; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Exception; - -/** - * @author Jean-François Simon - */ -class AccessDeniedException extends \UnexpectedValueException -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Exception; - -/** - * @author Jean-François Simon - */ -interface ExceptionInterface -{ - /** - * @return \Symfony\Component\Finder\Adapter\AdapterInterface - */ - public function getAdapter(); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Exception; - -use Symfony\Component\Finder\Adapter\AdapterInterface; -use Symfony\Component\Finder\Shell\Command; - -/** - * @author Jean-François Simon - */ -class ShellCommandFailureException extends AdapterFailureException -{ - /** - * @var Command - */ - private $command; - - /** - * @param AdapterInterface $adapter - * @param Command $command - * @param \Exception|null $previous - */ - public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null) - { - $this->command = $command; - parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous); - } - - /** - * @return Command - */ - public function getCommand() - { - return $this->command; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder; - -use Symfony\Component\Finder\Adapter\AdapterInterface; -use Symfony\Component\Finder\Adapter\GnuFindAdapter; -use Symfony\Component\Finder\Adapter\BsdFindAdapter; -use Symfony\Component\Finder\Adapter\PhpAdapter; -use Symfony\Component\Finder\Exception\ExceptionInterface; - -/** - * Finder allows to build rules to find files and directories. - * - * It is a thin wrapper around several specialized iterator classes. - * - * All rules may be invoked several times. - * - * All methods return the current Finder object to allow easy chaining: - * - * $finder = Finder::create()->files()->name('*.php')->in(__DIR__); - * - * @author Fabien Potencier - * - * @api - */ -class Finder implements \IteratorAggregate, \Countable -{ - const IGNORE_VCS_FILES = 1; - const IGNORE_DOT_FILES = 2; - - private $mode = 0; - private $names = array(); - private $notNames = array(); - private $exclude = array(); - private $filters = array(); - private $depths = array(); - private $sizes = array(); - private $followLinks = false; - private $sort = false; - private $ignore = 0; - private $dirs = array(); - private $dates = array(); - private $iterators = array(); - private $contains = array(); - private $notContains = array(); - private $adapters = array(); - private $paths = array(); - private $notPaths = array(); - private $ignoreUnreadableDirs = false; - - private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'); - - /** - * Constructor. - */ - public function __construct() - { - $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES; - - $this - ->addAdapter(new GnuFindAdapter()) - ->addAdapter(new BsdFindAdapter()) - ->addAdapter(new PhpAdapter(), -50) - ->setAdapter('php') - ; - } - - /** - * Creates a new Finder. - * - * @return Finder A new Finder instance - * - * @api - */ - public static function create() - { - return new static(); - } - - /** - * Registers a finder engine implementation. - * - * @param AdapterInterface $adapter An adapter instance - * @param integer $priority Highest is selected first - * - * @return Finder The current Finder instance - */ - public function addAdapter(Adapter\AdapterInterface $adapter, $priority = 0) - { - $this->adapters[$adapter->getName()] = array( - 'adapter' => $adapter, - 'priority' => $priority, - 'selected' => false, - ); - - return $this->sortAdapters(); - } - - /** - * Sets the selected adapter to the best one according to the current platform the code is run on. - * - * @return Finder The current Finder instance - */ - public function useBestAdapter() - { - $this->resetAdapterSelection(); - - return $this->sortAdapters(); - } - - /** - * Selects the adapter to use. - * - * @param string $name - * - * @throws \InvalidArgumentException - * - * @return Finder The current Finder instance - */ - public function setAdapter($name) - { - if (!isset($this->adapters[$name])) { - throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name)); - } - - $this->resetAdapterSelection(); - $this->adapters[$name]['selected'] = true; - - return $this->sortAdapters(); - } - - /** - * Removes all adapters registered in the finder. - * - * @return Finder The current Finder instance - */ - public function removeAdapters() - { - $this->adapters = array(); - - return $this; - } - - /** - * Returns registered adapters ordered by priority without extra information. - * - * @return AdapterInterface[] - */ - public function getAdapters() - { - return array_values(array_map(function (array $adapter) { - return $adapter['adapter']; - }, $this->adapters)); - } - - /** - * Restricts the matching to directories only. - * - * @return Finder The current Finder instance - * - * @api - */ - public function directories() - { - $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES; - - return $this; - } - - /** - * Restricts the matching to files only. - * - * @return Finder The current Finder instance - * - * @api - */ - public function files() - { - $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES; - - return $this; - } - - /** - * Adds tests for the directory depth. - * - * Usage: - * - * $finder->depth('> 1') // the Finder will start matching at level 1. - * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point. - * - * @param int $level The depth level expression - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\DepthRangeFilterIterator - * @see Symfony\Component\Finder\Comparator\NumberComparator - * - * @api - */ - public function depth($level) - { - $this->depths[] = new Comparator\NumberComparator($level); - - return $this; - } - - /** - * Adds tests for file dates (last modified). - * - * The date must be something that strtotime() is able to parse: - * - * $finder->date('since yesterday'); - * $finder->date('until 2 days ago'); - * $finder->date('> now - 2 hours'); - * $finder->date('>= 2005-10-15'); - * - * @param string $date A date rage string - * - * @return Finder The current Finder instance - * - * @see strtotime - * @see Symfony\Component\Finder\Iterator\DateRangeFilterIterator - * @see Symfony\Component\Finder\Comparator\DateComparator - * - * @api - */ - public function date($date) - { - $this->dates[] = new Comparator\DateComparator($date); - - return $this; - } - - /** - * Adds rules that files must match. - * - * You can use patterns (delimited with / sign), globs or simple strings. - * - * $finder->name('*.php') - * $finder->name('/\.php$/') // same as above - * $finder->name('test.php') - * - * @param string $pattern A pattern (a regexp, a glob, or a string) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator - * - * @api - */ - public function name($pattern) - { - $this->names[] = $pattern; - - return $this; - } - - /** - * Adds rules that files must not match. - * - * @param string $pattern A pattern (a regexp, a glob, or a string) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator - * - * @api - */ - public function notName($pattern) - { - $this->notNames[] = $pattern; - - return $this; - } - - /** - * Adds tests that file contents must match. - * - * Strings or PCRE patterns can be used: - * - * $finder->contains('Lorem ipsum') - * $finder->contains('/Lorem ipsum/i') - * - * @param string $pattern A pattern (string or regexp) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilecontentFilterIterator - */ - public function contains($pattern) - { - $this->contains[] = $pattern; - - return $this; - } - - /** - * Adds tests that file contents must not match. - * - * Strings or PCRE patterns can be used: - * - * $finder->notContains('Lorem ipsum') - * $finder->notContains('/Lorem ipsum/i') - * - * @param string $pattern A pattern (string or regexp) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilecontentFilterIterator - */ - public function notContains($pattern) - { - $this->notContains[] = $pattern; - - return $this; - } - - /** - * Adds rules that filenames must match. - * - * You can use patterns (delimited with / sign) or simple strings. - * - * $finder->path('some/special/dir') - * $finder->path('/some\/special\/dir/') // same as above - * - * Use only / as dirname separator. - * - * @param string $pattern A pattern (a regexp or a string) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator - */ - public function path($pattern) - { - $this->paths[] = $pattern; - - return $this; - } - - /** - * Adds rules that filenames must not match. - * - * You can use patterns (delimited with / sign) or simple strings. - * - * $finder->notPath('some/special/dir') - * $finder->notPath('/some\/special\/dir/') // same as above - * - * Use only / as dirname separator. - * - * @param string $pattern A pattern (a regexp or a string) - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator - */ - public function notPath($pattern) - { - $this->notPaths[] = $pattern; - - return $this; - } - - /** - * Adds tests for file sizes. - * - * $finder->size('> 10K'); - * $finder->size('<= 1Ki'); - * $finder->size(4); - * - * @param string $size A size range string - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SizeRangeFilterIterator - * @see Symfony\Component\Finder\Comparator\NumberComparator - * - * @api - */ - public function size($size) - { - $this->sizes[] = new Comparator\NumberComparator($size); - - return $this; - } - - /** - * Excludes directories. - * - * @param string|array $dirs A directory path or an array of directories - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator - * - * @api - */ - public function exclude($dirs) - { - $this->exclude = array_merge($this->exclude, (array) $dirs); - - return $this; - } - - /** - * Excludes "hidden" directories and files (starting with a dot). - * - * @param Boolean $ignoreDotFiles Whether to exclude "hidden" files or not - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator - * - * @api - */ - public function ignoreDotFiles($ignoreDotFiles) - { - if ($ignoreDotFiles) { - $this->ignore = $this->ignore | static::IGNORE_DOT_FILES; - } else { - $this->ignore = $this->ignore & ~static::IGNORE_DOT_FILES; - } - - return $this; - } - - /** - * Forces the finder to ignore version control directories. - * - * @param Boolean $ignoreVCS Whether to exclude VCS files or not - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator - * - * @api - */ - public function ignoreVCS($ignoreVCS) - { - if ($ignoreVCS) { - $this->ignore = $this->ignore | static::IGNORE_VCS_FILES; - } else { - $this->ignore = $this->ignore & ~static::IGNORE_VCS_FILES; - } - - return $this; - } - - /** - * Adds VCS patterns. - * - * @see ignoreVCS - * - * @param string|string[] $pattern VCS patterns to ignore - */ - public static function addVCSPattern($pattern) - { - foreach ((array) $pattern as $p) { - self::$vcsPatterns[] = $p; - } - - self::$vcsPatterns = array_unique(self::$vcsPatterns); - } - - /** - * Sorts files and directories by an anonymous function. - * - * The anonymous function receives two \SplFileInfo instances to compare. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @param \Closure $closure An anonymous function - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sort(\Closure $closure) - { - $this->sort = $closure; - - return $this; - } - - /** - * Sorts files and directories by name. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sortByName() - { - $this->sort = Iterator\SortableIterator::SORT_BY_NAME; - - return $this; - } - - /** - * Sorts files and directories by type (directories before files), then by name. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sortByType() - { - $this->sort = Iterator\SortableIterator::SORT_BY_TYPE; - - return $this; - } - - /** - * Sorts files and directories by the last accessed time. - * - * This is the time that the file was last accessed, read or written to. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sortByAccessedTime() - { - $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME; - - return $this; - } - - /** - * Sorts files and directories by the last inode changed time. - * - * This is the time that the inode information was last modified (permissions, owner, group or other metadata). - * - * On Windows, since inode is not available, changed time is actually the file creation time. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sortByChangedTime() - { - $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME; - - return $this; - } - - /** - * Sorts files and directories by the last modified time. - * - * This is the last time the actual contents of the file were last modified. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\SortableIterator - * - * @api - */ - public function sortByModifiedTime() - { - $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME; - - return $this; - } - - /** - * Filters the iterator with an anonymous function. - * - * The anonymous function receives a \SplFileInfo and must return false - * to remove files. - * - * @param \Closure $closure An anonymous function - * - * @return Finder The current Finder instance - * - * @see Symfony\Component\Finder\Iterator\CustomFilterIterator - * - * @api - */ - public function filter(\Closure $closure) - { - $this->filters[] = $closure; - - return $this; - } - - /** - * Forces the following of symlinks. - * - * @return Finder The current Finder instance - * - * @api - */ - public function followLinks() - { - $this->followLinks = true; - - return $this; - } - - /** - * Tells finder to ignore unreadable directories. - * - * By default, scanning unreadable directories content throws an AccessDeniedException. - * - * @param boolean $ignore - * - * @return Finder The current Finder instance - */ - public function ignoreUnreadableDirs($ignore = true) - { - $this->ignoreUnreadableDirs = (Boolean) $ignore; - - return $this; - } - - /** - * Searches files and directories which match defined rules. - * - * @param string|array $dirs A directory path or an array of directories - * - * @return Finder The current Finder instance - * - * @throws \InvalidArgumentException if one of the directories does not exist - * - * @api - */ - public function in($dirs) - { - $resolvedDirs = array(); - - foreach ((array) $dirs as $dir) { - if (is_dir($dir)) { - $resolvedDirs[] = $dir; - } elseif ($glob = glob($dir, GLOB_ONLYDIR)) { - $resolvedDirs = array_merge($resolvedDirs, $glob); - } else { - throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir)); - } - } - - $this->dirs = array_merge($this->dirs, $resolvedDirs); - - return $this; - } - - /** - * Returns an Iterator for the current Finder configuration. - * - * This method implements the IteratorAggregate interface. - * - * @return \Iterator An iterator - * - * @throws \LogicException if the in() method has not been called - */ - public function getIterator() - { - if (0 === count($this->dirs) && 0 === count($this->iterators)) { - throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.'); - } - - if (1 === count($this->dirs) && 0 === count($this->iterators)) { - return $this->searchInDirectory($this->dirs[0]); - } - - $iterator = new \AppendIterator(); - foreach ($this->dirs as $dir) { - $iterator->append($this->searchInDirectory($dir)); - } - - foreach ($this->iterators as $it) { - $iterator->append($it); - } - - return $iterator; - } - - /** - * Appends an existing set of files/directories to the finder. - * - * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array. - * - * @param mixed $iterator - * - * @return Finder The finder - * - * @throws \InvalidArgumentException When the given argument is not iterable. - */ - public function append($iterator) - { - if ($iterator instanceof \IteratorAggregate) { - $this->iterators[] = $iterator->getIterator(); - } elseif ($iterator instanceof \Iterator) { - $this->iterators[] = $iterator; - } elseif ($iterator instanceof \Traversable || is_array($iterator)) { - $it = new \ArrayIterator(); - foreach ($iterator as $file) { - $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file)); - } - $this->iterators[] = $it; - } else { - throw new \InvalidArgumentException('Finder::append() method wrong argument type.'); - } - - return $this; - } - - /** - * Counts all the results collected by the iterators. - * - * @return int - */ - public function count() - { - return iterator_count($this->getIterator()); - } - - /** - * @return Finder The current Finder instance - */ - private function sortAdapters() - { - uasort($this->adapters, function (array $a, array $b) { - if ($a['selected'] || $b['selected']) { - return $a['selected'] ? -1 : 1; - } - - return $a['priority'] > $b['priority'] ? -1 : 1; - }); - - return $this; - } - - /** - * @param $dir - * - * @return \Iterator - * - * @throws \RuntimeException When none of the adapters are supported - */ - private function searchInDirectory($dir) - { - if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) { - $this->exclude = array_merge($this->exclude, self::$vcsPatterns); - } - - if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) { - $this->notPaths[] = '#(^|/)\..+(/|$)#'; - } - - foreach ($this->adapters as $adapter) { - if ($adapter['adapter']->isSupported()) { - try { - return $this - ->buildAdapter($adapter['adapter']) - ->searchInDirectory($dir); - } catch (ExceptionInterface $e) {} - } - } - - throw new \RuntimeException('No supported adapter found.'); - } - - /** - * @param AdapterInterface $adapter - * - * @return AdapterInterface - */ - private function buildAdapter(AdapterInterface $adapter) - { - return $adapter - ->setFollowLinks($this->followLinks) - ->setDepths($this->depths) - ->setMode($this->mode) - ->setExclude($this->exclude) - ->setNames($this->names) - ->setNotNames($this->notNames) - ->setContains($this->contains) - ->setNotContains($this->notContains) - ->setSizes($this->sizes) - ->setDates($this->dates) - ->setFilters($this->filters) - ->setSort($this->sort) - ->setPath($this->paths) - ->setNotPath($this->notPaths) - ->ignoreUnreadableDirs($this->ignoreUnreadableDirs); - } - - /** - * Unselects all adapters. - */ - private function resetAdapterSelection() - { - $this->adapters = array_map(function (array $properties) { - $properties['selected'] = false; - - return $properties; - }, $this->adapters); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder; - -/** - * Extends \SplFileInfo to support relative paths - * - * @author Fabien Potencier - */ -class SplFileInfo extends \SplFileInfo -{ - private $relativePath; - private $relativePathname; - - /** - * Constructor - * - * @param string $file The file name - * @param string $relativePath The relative path - * @param string $relativePathname The relative path name - */ - public function __construct($file, $relativePath, $relativePathname) - { - parent::__construct($file); - $this->relativePath = $relativePath; - $this->relativePathname = $relativePathname; - } - - /** - * Returns the relative path - * - * @return string the relative path - */ - public function getRelativePath() - { - return $this->relativePath; - } - - /** - * Returns the relative path name - * - * @return string the relative path name - */ - public function getRelativePathname() - { - return $this->relativePathname; - } - - /** - * Returns the contents of the file - * - * @return string the contents of the file - * - * @throws \RuntimeException - */ - public function getContents() - { - $level = error_reporting(0); - $content = file_get_contents($this->getPathname()); - error_reporting($level); - if (false === $content) { - $error = error_get_last(); - throw new \RuntimeException($error['message']); - } - - return $content; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Expression; - -/** - * @author Jean-François Simon - */ -interface ValueInterface -{ - /** - * Renders string representation of expression. - * - * @return string - */ - public function render(); - - /** - * Renders string representation of pattern. - * - * @return string - */ - public function renderPattern(); - - /** - * Returns value case sensitivity. - * - * @return bool - */ - public function isCaseSensitive(); - - /** - * Returns expression type. - * - * @return int - */ - public function getType(); - - /** - * @param string $expr - * - * @return ValueInterface - */ - public function prepend($expr); - - /** - * @param string $expr - * - * @return ValueInterface - */ - public function append($expr); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Expression; - -/** - * @author Jean-François Simon - */ -class Glob implements ValueInterface -{ - /** - * @var string - */ - private $pattern; - - /** - * @param string $pattern - */ - public function __construct($pattern) - { - $this->pattern = $pattern; - } - - /** - * {@inheritdoc} - */ - public function render() - { - return $this->pattern; - } - - /** - * {@inheritdoc} - */ - public function renderPattern() - { - return $this->pattern; - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return Expression::TYPE_GLOB; - } - - /** - * {@inheritdoc} - */ - public function isCaseSensitive() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function prepend($expr) - { - $this->pattern = $expr.$this->pattern; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function append($expr) - { - $this->pattern .= $expr; - - return $this; - } - - /** - * Tests if glob is expandable ("*.{a,b}" syntax). - * - * @return bool - */ - public function isExpandable() - { - return false !== strpos($this->pattern, '{') - && false !== strpos($this->pattern, '}'); - } - - /** - * @param bool $strictLeadingDot - * @param bool $strictWildcardSlash - * - * @return Regex - */ - public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true) - { - $firstByte = true; - $escaping = false; - $inCurlies = 0; - $regex = ''; - $sizeGlob = strlen($this->pattern); - for ($i = 0; $i < $sizeGlob; $i++) { - $car = $this->pattern[$i]; - if ($firstByte) { - if ($strictLeadingDot && '.' !== $car) { - $regex .= '(?=[^\.])'; - } - - $firstByte = false; - } - - if ('/' === $car) { - $firstByte = true; - } - - if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) { - $regex .= "\\$car"; - } elseif ('*' === $car) { - $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*'); - } elseif ('?' === $car) { - $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.'); - } elseif ('{' === $car) { - $regex .= $escaping ? '\\{' : '('; - if (!$escaping) { - ++$inCurlies; - } - } elseif ('}' === $car && $inCurlies) { - $regex .= $escaping ? '}' : ')'; - if (!$escaping) { - --$inCurlies; - } - } elseif (',' === $car && $inCurlies) { - $regex .= $escaping ? ',' : '|'; - } elseif ('\\' === $car) { - if ($escaping) { - $regex .= '\\\\'; - $escaping = false; - } else { - $escaping = true; - } - - continue; - } else { - $regex .= $car; - } - $escaping = false; - } - - return new Regex('^'.$regex.'$'); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Expression; - -/** - * @author Jean-François Simon - */ -class Expression implements ValueInterface -{ - const TYPE_REGEX = 1; - const TYPE_GLOB = 2; - - /** - * @var ValueInterface - */ - private $value; - - /** - * @param string $expr - * - * @return Expression - */ - public static function create($expr) - { - return new self($expr); - } - - /** - * @param string $expr - */ - public function __construct($expr) - { - try { - $this->value = Regex::create($expr); - } catch (\InvalidArgumentException $e) { - $this->value = new Glob($expr); - } - } - - /** - * @return string - */ - public function __toString() - { - return $this->render(); - } - - /** - * {@inheritdoc} - */ - public function render() - { - return $this->value->render(); - } - - /** - * {@inheritdoc} - */ - public function renderPattern() - { - return $this->value->renderPattern(); - } - - /** - * @return bool - */ - public function isCaseSensitive() - { - return $this->value->isCaseSensitive(); - } - - /** - * @return int - */ - public function getType() - { - return $this->value->getType(); - } - - /** - * {@inheritdoc} - */ - public function prepend($expr) - { - $this->value->prepend($expr); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function append($expr) - { - $this->value->append($expr); - - return $this; - } - - /** - * @return bool - */ - public function isRegex() - { - return self::TYPE_REGEX === $this->value->getType(); - } - - /** - * @return bool - */ - public function isGlob() - { - return self::TYPE_GLOB === $this->value->getType(); - } - - /** - * @throws \LogicException - * - * @return Glob - */ - public function getGlob() - { - if (self::TYPE_GLOB !== $this->value->getType()) { - throw new \LogicException('Regex can\'t be transformed to glob.'); - } - - return $this->value; - } - - /** - * @return Regex - */ - public function getRegex() - { - return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Expression; - -/** - * @author Jean-François Simon - */ -class Regex implements ValueInterface -{ - const START_FLAG = '^'; - const END_FLAG = '$'; - const BOUNDARY = '~'; - const JOKER = '.*'; - const ESCAPING = '\\'; - - /** - * @var string - */ - private $pattern; - - /** - * @var array - */ - private $options; - - /** - * @var bool - */ - private $startFlag; - - /** - * @var bool - */ - private $endFlag; - - /** - * @var bool - */ - private $startJoker; - - /** - * @var bool - */ - private $endJoker; - - /** - * @param string $expr - * - * @return Regex - * - * @throws \InvalidArgumentException - */ - public static function create($expr) - { - if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) { - $start = substr($m[1], 0, 1); - $end = substr($m[1], -1); - - if ( - ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start)) - || ($start === '{' && $end === '}') - || ($start === '(' && $end === ')') - ) { - return new self(substr($m[1], 1, -1), $m[2], $end); - } - } - - throw new \InvalidArgumentException('Given expression is not a regex.'); - } - - /** - * @param string $pattern - * @param string $options - * @param string $delimiter - */ - public function __construct($pattern, $options = '', $delimiter = null) - { - if (null !== $delimiter) { - // removes delimiter escaping - $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern); - } - - $this->parsePattern($pattern); - $this->options = $options; - } - - /** - * @return string - */ - public function __toString() - { - return $this->render(); - } - - /** - * {@inheritdoc} - */ - public function render() - { - return self::BOUNDARY - .$this->renderPattern() - .self::BOUNDARY - .$this->options; - } - - /** - * {@inheritdoc} - */ - public function renderPattern() - { - return ($this->startFlag ? self::START_FLAG : '') - .($this->startJoker ? self::JOKER : '') - .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern) - .($this->endJoker ? self::JOKER : '') - .($this->endFlag ? self::END_FLAG : ''); - } - - /** - * {@inheritdoc} - */ - public function isCaseSensitive() - { - return !$this->hasOption('i'); - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return Expression::TYPE_REGEX; - } - - /** - * {@inheritdoc} - */ - public function prepend($expr) - { - $this->pattern = $expr.$this->pattern; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function append($expr) - { - $this->pattern .= $expr; - - return $this; - } - - /** - * @param string $option - * - * @return bool - */ - public function hasOption($option) - { - return false !== strpos($this->options, $option); - } - - /** - * @param string $option - * - * @return Regex - */ - public function addOption($option) - { - if (!$this->hasOption($option)) { - $this->options.= $option; - } - - return $this; - } - - /** - * @param string $option - * - * @return Regex - */ - public function removeOption($option) - { - $this->options = str_replace($option, '', $this->options); - - return $this; - } - - /** - * @param bool $startFlag - * - * @return Regex - */ - public function setStartFlag($startFlag) - { - $this->startFlag = $startFlag; - - return $this; - } - - /** - * @return bool - */ - public function hasStartFlag() - { - return $this->startFlag; - } - - /** - * @param bool $endFlag - * - * @return Regex - */ - public function setEndFlag($endFlag) - { - $this->endFlag = (bool) $endFlag; - - return $this; - } - - /** - * @return bool - */ - public function hasEndFlag() - { - return $this->endFlag; - } - - /** - * @param bool $startJoker - * - * @return Regex - */ - public function setStartJoker($startJoker) - { - $this->startJoker = $startJoker; - - return $this; - } - - /** - * @return bool - */ - public function hasStartJoker() - { - return $this->startJoker; - } - - /** - * @param bool $endJoker - * - * @return Regex - */ - public function setEndJoker($endJoker) - { - $this->endJoker = (bool) $endJoker; - - return $this; - } - - /** - * @return bool - */ - public function hasEndJoker() - { - return $this->endJoker; - } - - /** - * @param array $replacement - * - * @return Regex - */ - public function replaceJokers($replacement) - { - $replace = function ($subject) use ($replacement) { - $subject = $subject[0]; - $replace = 0 === substr_count($subject, '\\') % 2; - - return $replace ? str_replace('.', $replacement, $subject) : $subject; - }; - - $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern); - - return $this; - } - - /** - * @param string $pattern - */ - private function parsePattern($pattern) - { - if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) { - $pattern = substr($pattern, 1); - } - - if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) { - $pattern = substr($pattern, 2); - } - - if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) { - $pattern = substr($pattern, 0, -1); - } - - if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) { - $pattern = substr($pattern, 0, -2); - } - - $this->pattern = $pattern; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; - -/** - * Yaml offers convenience methods to load and dump YAML. - * - * @author Fabien Potencier - * - * @api - */ -class Yaml -{ - /** - * Parses YAML into a PHP array. - * - * The parse method, when supplied with a YAML stream (string or file), - * will do its best to convert YAML in a file into a PHP array. - * - * Usage: - * - * $array = Yaml::parse('config.yml'); - * print_r($array); - * - * - * As this method accepts both plain strings and file names as an input, - * you must validate the input before calling this method. Passing a file - * as an input is a deprecated feature and will be removed in 3.0. - * - * @param string $input Path to a YAML file or a string containing YAML - * @param Boolean $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise - * @param Boolean $objectSupport True if object support is enabled, false otherwise - * - * @return array The YAML converted to a PHP array - * - * @throws ParseException If the YAML is not valid - * - * @api - */ - public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false) - { - // if input is a file, process it - $file = ''; - if (strpos($input, "\n") === false && is_file($input)) { - if (false === is_readable($input)) { - throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input)); - } - - $file = $input; - $input = file_get_contents($file); - } - - $yaml = new Parser(); - - try { - return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport); - } catch (ParseException $e) { - if ($file) { - $e->setParsedFile($file); - } - - throw $e; - } - } - - /** - * Dumps a PHP array to a YAML string. - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. - * - * @param array $array PHP array - * @param integer $inline The level where you switch to inline YAML - * @param integer $indent The amount of spaces to use for indentation of nested nodes. - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return string A YAML string representing the original PHP array - * - * @api - */ - public static function dump($array, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false) - { - $yaml = new Dumper(); - $yaml->setIndentation($indent); - - return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -/** - * Escaper encapsulates escaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - */ -class Escaper -{ - // Characters that would cause a dumped string to require double quoting. - const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; - - // Mapping arrays for escaping a double quoted string. The backslash is - // first to ensure proper escaping because str_replace operates iteratively - // on the input arrays. This ordering of the characters avoids the use of strtr, - // which performs more slowly. - private static $escapees = array('\\\\', '\\"', '"', - "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", - "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", - "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", - "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9"); - private static $escaped = array('\\"', '\\\\', '\\"', - "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a", - "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f", - "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17", - "\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f", - "\\N", "\\_", "\\L", "\\P"); - - /** - * Determines if a PHP value would require double quoting in YAML. - * - * @param string $value A PHP value - * - * @return Boolean True if the value would require double quotes. - */ - public static function requiresDoubleQuoting($value) - { - return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); - } - - /** - * Escapes and surrounds a PHP value with double quotes. - * - * @param string $value A PHP value - * - * @return string The quoted, escaped string - */ - public static function escapeWithDoubleQuotes($value) - { - return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value)); - } - - /** - * Determines if a PHP value would require single quoting in YAML. - * - * @param string $value A PHP value - * - * @return Boolean True if the value would require single quotes. - */ - public static function requiresSingleQuoting($value) - { - return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); - } - - /** - * Escapes and surrounds a PHP value with single quotes. - * - * @param string $value A PHP value - * - * @return string The quoted, escaped string - */ - public static function escapeWithSingleQuotes($value) - { - return sprintf("'%s'", str_replace('\'', '\'\'', $value)); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; - -/** - * Parser parses YAML strings to convert them to PHP arrays. - * - * @author Fabien Potencier - */ -class Parser -{ - const FOLDED_SCALAR_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; - - private $offset = 0; - private $lines = array(); - private $currentLineNb = -1; - private $currentLine = ''; - private $refs = array(); - - /** - * Constructor - * - * @param integer $offset The offset of YAML document (used for line numbers in error messages) - */ - public function __construct($offset = 0) - { - $this->offset = $offset; - } - - /** - * Parses a YAML string to a PHP value. - * - * @param string $value A YAML string - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return mixed A PHP value - * - * @throws ParseException If the YAML is not valid - */ - public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) - { - $this->currentLineNb = -1; - $this->currentLine = ''; - $this->lines = explode("\n", $this->cleanup($value)); - - if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) { - throw new ParseException('The YAML value does not appear to be valid UTF-8.'); - } - - if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - - $data = array(); - $context = null; - while ($this->moveToNextLine()) { - if ($this->isCurrentLineEmpty()) { - continue; - } - - // tab? - if ("\t" === $this->currentLine[0]) { - throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - $isRef = $isInPlace = $isProcessed = false; - if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) { - if ($context && 'mapping' == $context) { - throw new ParseException('You cannot define a sequence item when in a mapping'); - } - $context = 'sequence'; - - if (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - // array - if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - $c = $this->getRealCurrentLineNb() + 1; - $parser = new Parser($c); - $parser->refs =& $this->refs; - $data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); - } else { - if (isset($values['leadspaces']) - && ' ' == $values['leadspaces'] - && preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $values['value'], $matches) - ) { - // this is a compact notation element, add to next block and parse - $c = $this->getRealCurrentLineNb(); - $parser = new Parser($c); - $parser->refs =& $this->refs; - - $block = $values['value']; - if ($this->isNextLineIndented()) { - $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2); - } - - $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport); - } else { - $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); - } - } - } elseif (preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values) && false === strpos($values['key'],' #')) { - if ($context && 'sequence' == $context) { - throw new ParseException('You cannot define a mapping item when in a sequence'); - } - $context = 'mapping'; - - // force correct settings - Inline::parse(null, $exceptionOnInvalidType, $objectSupport); - try { - $key = Inline::parseScalar($values['key']); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - if ('<<' === $key) { - if (isset($values['value']) && 0 === strpos($values['value'], '*')) { - $isInPlace = substr($values['value'], 1); - if (!array_key_exists($isInPlace, $this->refs)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $isInPlace), $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } else { - if (isset($values['value']) && $values['value'] !== '') { - $value = $values['value']; - } else { - $value = $this->getNextEmbedBlock(); - } - $c = $this->getRealCurrentLineNb() + 1; - $parser = new Parser($c); - $parser->refs =& $this->refs; - $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport); - - $merged = array(); - if (!is_array($parsed)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } elseif (isset($parsed[0])) { - // Numeric array, merge individual elements - foreach (array_reverse($parsed) as $parsedItem) { - if (!is_array($parsedItem)) { - throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem); - } - $merged = array_merge($parsedItem, $merged); - } - } else { - // Associative array, merge - $merged = array_merge($merged, $parsed); - } - - $isProcessed = $merged; - } - } elseif (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - if ($isProcessed) { - // Merge keys - $data = $isProcessed; - // hash - } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - // if next line is less indented or equal, then it means that the current value is null - if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { - $data[$key] = null; - } else { - $c = $this->getRealCurrentLineNb() + 1; - $parser = new Parser($c); - $parser->refs =& $this->refs; - $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); - } - } else { - if ($isInPlace) { - $data = $this->refs[$isInPlace]; - } else { - $data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); - } - } - } else { - // 1-liner optionally followed by newline - $lineCount = count($this->lines); - if (1 === $lineCount || (2 === $lineCount && empty($this->lines[1]))) { - try { - $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - if (is_array($value)) { - $first = reset($value); - if (is_string($first) && 0 === strpos($first, '*')) { - $data = array(); - foreach ($value as $alias) { - $data[] = $this->refs[substr($alias, 1)]; - } - $value = $data; - } - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - return $value; - } - - switch (preg_last_error()) { - case PREG_INTERNAL_ERROR: - $error = 'Internal PCRE error.'; - break; - case PREG_BACKTRACK_LIMIT_ERROR: - $error = 'pcre.backtrack_limit reached.'; - break; - case PREG_RECURSION_LIMIT_ERROR: - $error = 'pcre.recursion_limit reached.'; - break; - case PREG_BAD_UTF8_ERROR: - $error = 'Malformed UTF-8 data.'; - break; - case PREG_BAD_UTF8_OFFSET_ERROR: - $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; - break; - default: - $error = 'Unable to parse.'; - } - - throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - if ($isRef) { - $this->refs[$isRef] = end($data); - } - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - return empty($data) ? null : $data; - } - - /** - * Returns the current line number (takes the offset into account). - * - * @return integer The current line number - */ - private function getRealCurrentLineNb() - { - return $this->currentLineNb + $this->offset; - } - - /** - * Returns the current line indentation. - * - * @return integer The current line indentation - */ - private function getCurrentLineIndentation() - { - return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' ')); - } - - /** - * Returns the next embed block of YAML. - * - * @param integer $indentation The indent level at which the block is to be read, or null for default - * - * @return string A YAML string - * - * @throws ParseException When indentation problem are detected - */ - private function getNextEmbedBlock($indentation = null) - { - $this->moveToNextLine(); - - if (null === $indentation) { - $newIndent = $this->getCurrentLineIndentation(); - - $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem($this->currentLine); - - if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } else { - $newIndent = $indentation; - } - - $data = array(substr($this->currentLine, $newIndent)); - - $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine); - - // Comments must not be removed inside a string block (ie. after a line ending with "|") - $removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~'; - $removeComments = !preg_match($removeCommentsPattern, $this->currentLine); - - while ($this->moveToNextLine()) { - $indent = $this->getCurrentLineIndentation(); - - if ($indent === $newIndent) { - $removeComments = !preg_match($removeCommentsPattern, $this->currentLine); - } - - if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine)) { - $this->moveToPreviousLine(); - break; - } - - if ($this->isCurrentLineBlank()) { - $data[] = substr($this->currentLine, $newIndent); - continue; - } - - if ($removeComments && $this->isCurrentLineComment()) { - continue; - } - - if ($indent >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } elseif (0 == $indent) { - $this->moveToPreviousLine(); - - break; - } else { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } - - return implode("\n", $data); - } - - /** - * Moves the parser to the next line. - * - * @return Boolean - */ - private function moveToNextLine() - { - if ($this->currentLineNb >= count($this->lines) - 1) { - return false; - } - - $this->currentLine = $this->lines[++$this->currentLineNb]; - - return true; - } - - /** - * Moves the parser to the previous line. - */ - private function moveToPreviousLine() - { - $this->currentLine = $this->lines[--$this->currentLineNb]; - } - - /** - * Parses a YAML value. - * - * @param string $value A YAML value - * @param Boolean $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise - * @param Boolean $objectSupport True if object support is enabled, false otherwise - * - * @return mixed A PHP value - * - * @throws ParseException When reference does not exist - */ - private function parseValue($value, $exceptionOnInvalidType, $objectSupport) - { - if (0 === strpos($value, '*')) { - if (false !== $pos = strpos($value, '#')) { - $value = substr($value, 1, $pos - 2); - } else { - $value = substr($value, 1); - } - - if (!array_key_exists($value, $this->refs)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine); - } - - return $this->refs[$value]; - } - - if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) { - $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - - return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers))); - } - - try { - return Inline::parse($value, $exceptionOnInvalidType, $objectSupport); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } - - /** - * Parses a folded scalar. - * - * @param string $separator The separator that was used to begin this folded scalar (| or >) - * @param string $indicator The indicator that was used to begin this folded scalar (+ or -) - * @param integer $indentation The indentation that was used to begin this folded scalar - * - * @return string The text value - */ - private function parseFoldedScalar($separator, $indicator = '', $indentation = 0) - { - $notEOF = $this->moveToNextLine(); - if (!$notEOF) { - return ''; - } - - $isCurrentLineBlank = $this->isCurrentLineBlank(); - $text = ''; - - // leading blank lines are consumed before determining indentation - while ($notEOF && $isCurrentLineBlank) { - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $text .= "\n"; - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - - // determine indentation if not specified - if (0 === $indentation) { - if (preg_match('/^ +/', $this->currentLine, $matches)) { - $indentation = strlen($matches[0]); - } - } - - if ($indentation > 0) { - $pattern = sprintf('/^ {%d}(.*)$/', $indentation); - - while ( - $notEOF && ( - $isCurrentLineBlank || - preg_match($pattern, $this->currentLine, $matches) - ) - ) { - if ($isCurrentLineBlank) { - $text .= substr($this->currentLine, $indentation); - } else { - $text .= $matches[1]; - } - - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $text .= "\n"; - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - } elseif ($notEOF) { - $text .= "\n"; - } - - if ($notEOF) { - $this->moveToPreviousLine(); - } - - // replace all non-trailing single newlines with spaces in folded blocks - if ('>' === $separator) { - preg_match('/(\n*)$/', $text, $matches); - $text = preg_replace('/(?getCurrentLineIndentation(); - $EOF = !$this->moveToNextLine(); - - while (!$EOF && $this->isCurrentLineEmpty()) { - $EOF = !$this->moveToNextLine(); - } - - if ($EOF) { - return false; - } - - $ret = false; - if ($this->getCurrentLineIndentation() > $currentIndentation) { - $ret = true; - } - - $this->moveToPreviousLine(); - - return $ret; - } - - /** - * Returns true if the current line is blank or if it is a comment line. - * - * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise - */ - private function isCurrentLineEmpty() - { - return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); - } - - /** - * Returns true if the current line is blank. - * - * @return Boolean Returns true if the current line is blank, false otherwise - */ - private function isCurrentLineBlank() - { - return '' == trim($this->currentLine, ' '); - } - - /** - * Returns true if the current line is a comment line. - * - * @return Boolean Returns true if the current line is a comment line, false otherwise - */ - private function isCurrentLineComment() - { - //checking explicitly the first char of the trim is faster than loops or strpos - $ltrimmedLine = ltrim($this->currentLine, ' '); - - return $ltrimmedLine[0] === '#'; - } - - /** - * Cleanups a YAML string to be parsed. - * - * @param string $value The input YAML string - * - * @return string A cleaned up YAML string - */ - private function cleanup($value) - { - $value = str_replace(array("\r\n", "\r"), "\n", $value); - - // strip YAML header - $count = 0; - $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count); - $this->offset += $count; - - // remove leading comments - $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); - if ($count == 1) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - } - - // remove start of the document marker (---) - $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); - if ($count == 1) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - - // remove end of the document marker (...) - $value = preg_replace('#\.\.\.\s*$#s', '', $value); - } - - return $value; - } - - /** - * Returns true if the next line starts unindented collection - * - * @return Boolean Returns true if the next line starts unindented collection, false otherwise - */ - private function isNextLineUnIndentedCollection() - { - $currentIndentation = $this->getCurrentLineIndentation(); - $notEOF = $this->moveToNextLine(); - - while ($notEOF && $this->isCurrentLineEmpty()) { - $notEOF = $this->moveToNextLine(); - } - - if (false === $notEOF) { - return false; - } - - $ret = false; - if ( - $this->getCurrentLineIndentation() == $currentIndentation - && - $this->isStringUnIndentedCollectionItem($this->currentLine) - ) { - $ret = true; - } - - $this->moveToPreviousLine(); - - return $ret; - } - - /** - * Returns true if the string is un-indented collection item - * - * @return Boolean Returns true if the string is un-indented collection item, false otherwise - */ - private function isStringUnIndentedCollectionItem() - { - return (0 === strpos($this->currentLine, '- ')); - } - -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -/** - * Dumper dumps PHP variables to YAML strings. - * - * @author Fabien Potencier - */ -class Dumper -{ - /** - * The amount of spaces to use for indentation of nested nodes. - * - * @var integer - */ - protected $indentation = 4; - - /** - * Sets the indentation. - * - * @param integer $num The amount of spaces to use for indentation of nested nodes. - */ - public function setIndentation($num) - { - $this->indentation = (int) $num; - } - - /** - * Dumps a PHP value to YAML. - * - * @param mixed $input The PHP value - * @param integer $inline The level where you switch to inline YAML - * @param integer $indent The level of indentation (used internally) - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return string The YAML representation of the PHP value - */ - public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false) - { - $output = ''; - $prefix = $indent ? str_repeat(' ', $indent) : ''; - - if ($inline <= 0 || !is_array($input) || empty($input)) { - $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport); - } else { - $isAHash = array_keys($input) !== range(0, count($input) - 1); - - foreach ($input as $key => $value) { - $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); - - $output .= sprintf('%s%s%s%s', - $prefix, - $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-', - $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport) - ).($willBeInlined ? "\n" : ''); - } - } - - return $output; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -/** - * Unescaper encapsulates unescaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - */ -class Unescaper -{ - // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters - // must be converted to that encoding. - const ENCODING = 'UTF-8'; - - // Regex fragment that matches an escaped character in a double quoted - // string. - const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})"; - - /** - * Unescapes a single quoted string. - * - * @param string $value A single quoted string. - * - * @return string The unescaped string. - */ - public function unescapeSingleQuotedString($value) - { - return str_replace('\'\'', '\'', $value); - } - - /** - * Unescapes a double quoted string. - * - * @param string $value A double quoted string. - * - * @return string The unescaped string. - */ - public function unescapeDoubleQuotedString($value) - { - $self = $this; - $callback = function ($match) use ($self) { - return $self->unescapeCharacter($match[0]); - }; - - // evaluate the string - return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); - } - - /** - * Unescapes a character that was found in a double-quoted string - * - * @param string $value An escaped character - * - * @return string The unescaped character - */ - public function unescapeCharacter($value) - { - switch ($value{1}) { - case '0': - return "\x0"; - case 'a': - return "\x7"; - case 'b': - return "\x8"; - case 't': - return "\t"; - case "\t": - return "\t"; - case 'n': - return "\n"; - case 'v': - return "\xb"; - case 'f': - return "\xc"; - case 'r': - return "\xd"; - case 'e': - return "\x1b"; - case ' ': - return ' '; - case '"': - return '"'; - case '/': - return '/'; - case '\\': - return '\\'; - case 'N': - // U+0085 NEXT LINE - return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE'); - case '_': - // U+00A0 NO-BREAK SPACE - return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE'); - case 'L': - // U+2028 LINE SEPARATOR - return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE'); - case 'P': - // U+2029 PARAGRAPH SEPARATOR - return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE'); - case 'x': - $char = pack('n', hexdec(substr($value, 2, 2))); - - return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE'); - case 'u': - $char = pack('n', hexdec(substr($value, 2, 4))); - - return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE'); - case 'U': - $char = pack('N', hexdec(substr($value, 2, 8))); - - return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE'); - } - } - - /** - * Convert a string from one encoding to another. - * - * @param string $value The string to convert - * @param string $to The input encoding - * @param string $from The output encoding - * - * @return string The string with the new encoding - * - * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring) - */ - private function convertEncoding($value, $to, $from) - { - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($value, $to, $from); - } elseif (function_exists('iconv')) { - return iconv($from, $to, $value); - } - - throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).'); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during dumping. - * - * @author Fabien Potencier - * - * @api - */ -class DumpException extends RuntimeException -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception interface for all exceptions thrown by the component. - * - * @author Fabien Potencier - * - * @api - */ -interface ExceptionInterface -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -if (!defined('JSON_UNESCAPED_UNICODE')) { - define('JSON_UNESCAPED_SLASHES', 64); - define('JSON_UNESCAPED_UNICODE', 256); -} - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Fabien Potencier - * - * @api - */ -class ParseException extends RuntimeException -{ - private $parsedFile; - private $parsedLine; - private $snippet; - private $rawMessage; - - /** - * Constructor. - * - * @param string $message The error message - * @param integer $parsedLine The line where the error occurred - * @param integer $snippet The snippet of code near the problem - * @param string $parsedFile The file name where the error occurred - * @param \Exception $previous The previous exception - */ - public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) - { - $this->parsedFile = $parsedFile; - $this->parsedLine = $parsedLine; - $this->snippet = $snippet; - $this->rawMessage = $message; - - $this->updateRepr(); - - parent::__construct($this->message, 0, $previous); - } - - /** - * Gets the snippet of code near the error. - * - * @return string The snippet of code - */ - public function getSnippet() - { - return $this->snippet; - } - - /** - * Sets the snippet of code near the error. - * - * @param string $snippet The code snippet - */ - public function setSnippet($snippet) - { - $this->snippet = $snippet; - - $this->updateRepr(); - } - - /** - * Gets the filename where the error occurred. - * - * This method returns null if a string is parsed. - * - * @return string The filename - */ - public function getParsedFile() - { - return $this->parsedFile; - } - - /** - * Sets the filename where the error occurred. - * - * @param string $parsedFile The filename - */ - public function setParsedFile($parsedFile) - { - $this->parsedFile = $parsedFile; - - $this->updateRepr(); - } - - /** - * Gets the line where the error occurred. - * - * @return integer The file line - */ - public function getParsedLine() - { - return $this->parsedLine; - } - - /** - * Sets the line where the error occurred. - * - * @param integer $parsedLine The file line - */ - public function setParsedLine($parsedLine) - { - $this->parsedLine = $parsedLine; - - $this->updateRepr(); - } - - private function updateRepr() - { - $this->message = $this->rawMessage; - - $dot = false; - if ('.' === substr($this->message, -1)) { - $this->message = substr($this->message, 0, -1); - $dot = true; - } - - if (null !== $this->parsedFile) { - $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); - } - - if ($this->parsedLine >= 0) { - $this->message .= sprintf(' at line %d', $this->parsedLine); - } - - if ($this->snippet) { - $this->message .= sprintf(' (near "%s")', $this->snippet); - } - - if ($dot) { - $this->message .= '.'; - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Romain Neutron - * - * @api - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Exception\DumpException; - -/** - * Inline implements a YAML parser/dumper for the YAML inline syntax. - * - * @author Fabien Potencier - */ -class Inline -{ - const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; - - private static $exceptionOnInvalidType = false; - private static $objectSupport = false; - - /** - * Converts a YAML string to a PHP array. - * - * @param string $value A YAML string - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return array A PHP array representing the YAML string - * - * @throws ParseException - */ - public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) - { - self::$exceptionOnInvalidType = $exceptionOnInvalidType; - self::$objectSupport = $objectSupport; - - $value = trim($value); - - if (0 == strlen($value)) { - return ''; - } - - if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('ASCII'); - } - - $i = 0; - switch ($value[0]) { - case '[': - $result = self::parseSequence($value, $i); - ++$i; - break; - case '{': - $result = self::parseMapping($value, $i); - ++$i; - break; - default: - $result = self::parseScalar($value, null, array('"', "'"), $i); - } - - // some comments are allowed at the end - if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - return $result; - } - - /** - * Dumps a given PHP variable to a YAML string. - * - * @param mixed $value The PHP variable to convert - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return string The YAML string representing the PHP array - * - * @throws DumpException When trying to dump PHP resource - */ - public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false) - { - switch (true) { - case is_resource($value): - if ($exceptionOnInvalidType) { - throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); - } - - return 'null'; - case is_object($value): - if ($objectSupport) { - return '!!php/object:'.serialize($value); - } - - if ($exceptionOnInvalidType) { - throw new DumpException('Object support when dumping a YAML file has been disabled.'); - } - - return 'null'; - case is_array($value): - return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport); - case null === $value: - return 'null'; - case true === $value: - return 'true'; - case false === $value: - return 'false'; - case ctype_digit($value): - return is_string($value) ? "'$value'" : (int) $value; - case is_numeric($value): - $locale = setlocale(LC_NUMERIC, 0); - if (false !== $locale) { - setlocale(LC_NUMERIC, 'C'); - } - $repr = is_string($value) ? "'$value'" : (is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : strval($value)); - - if (false !== $locale) { - setlocale(LC_NUMERIC, $locale); - } - - return $repr; - case Escaper::requiresDoubleQuoting($value): - return Escaper::escapeWithDoubleQuotes($value); - case Escaper::requiresSingleQuoting($value): - return Escaper::escapeWithSingleQuotes($value); - case '' == $value: - return "''"; - case preg_match(self::getTimestampRegex(), $value): - case in_array(strtolower($value), array('null', '~', 'true', 'false')): - return "'$value'"; - default: - return $value; - } - } - - /** - * Dumps a PHP array to a YAML string. - * - * @param array $value The PHP array to dump - * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param Boolean $objectSupport true if object support is enabled, false otherwise - * - * @return string The YAML string representing the PHP array - */ - private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport) - { - // array - $keys = array_keys($value); - if ((1 == count($keys) && '0' == $keys[0]) - || (count($keys) > 1 && array_reduce($keys, function ($v, $w) { return (integer) $v + $w; }, 0) == count($keys) * (count($keys) - 1) / 2) - ) { - $output = array(); - foreach ($value as $val) { - $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport); - } - - return sprintf('[%s]', implode(', ', $output)); - } - - // mapping - $output = array(); - foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport)); - } - - return sprintf('{ %s }', implode(', ', $output)); - } - - /** - * Parses a scalar to a YAML string. - * - * @param scalar $scalar - * @param string $delimiters - * @param array $stringDelimiters - * @param integer &$i - * @param Boolean $evaluate - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true) - { - if (in_array($scalar[$i], $stringDelimiters)) { - // quoted scalar - $output = self::parseQuotedScalar($scalar, $i); - - if (null !== $delimiters) { - $tmp = ltrim(substr($scalar, $i), ' '); - if (!in_array($tmp[0], $delimiters)) { - throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); - } - } - } else { - // "normal" string - if (!$delimiters) { - $output = substr($scalar, $i); - $i += strlen($output); - - // remove comments - if (false !== $strpos = strpos($output, ' #')) { - $output = rtrim(substr($output, 0, $strpos)); - } - } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { - $output = $match[1]; - $i += strlen($output); - } else { - throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar)); - } - - if ($evaluate) { - $output = self::evaluateScalar($output); - } - } - - return $output; - } - - /** - * Parses a quoted scalar to YAML. - * - * @param string $scalar - * @param integer &$i - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseQuotedScalar($scalar, &$i) - { - if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { - throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i))); - } - - $output = substr($match[0], 1, strlen($match[0]) - 2); - - $unescaper = new Unescaper(); - if ('"' == $scalar[$i]) { - $output = $unescaper->unescapeDoubleQuotedString($output); - } else { - $output = $unescaper->unescapeSingleQuotedString($output); - } - - $i += strlen($match[0]); - - return $output; - } - - /** - * Parses a sequence to a YAML string. - * - * @param string $sequence - * @param integer &$i - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseSequence($sequence, &$i = 0) - { - $output = array(); - $len = strlen($sequence); - $i += 1; - - // [foo, bar, ...] - while ($i < $len) { - switch ($sequence[$i]) { - case '[': - // nested sequence - $output[] = self::parseSequence($sequence, $i); - break; - case '{': - // nested mapping - $output[] = self::parseMapping($sequence, $i); - break; - case ']': - return $output; - case ',': - case ' ': - break; - default: - $isQuoted = in_array($sequence[$i], array('"', "'")); - $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i); - - if (!$isQuoted && false !== strpos($value, ': ')) { - // embedded mapping? - try { - $value = self::parseMapping('{'.$value.'}'); - } catch (\InvalidArgumentException $e) { - // no, it's not - } - } - - $output[] = $value; - - --$i; - } - - ++$i; - } - - throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence)); - } - - /** - * Parses a mapping to a YAML string. - * - * @param string $mapping - * @param integer &$i - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseMapping($mapping, &$i = 0) - { - $output = array(); - $len = strlen($mapping); - $i += 1; - - // {foo: bar, bar:foo, ...} - while ($i < $len) { - switch ($mapping[$i]) { - case ' ': - case ',': - ++$i; - continue 2; - case '}': - return $output; - } - - // key - $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); - - // value - $done = false; - while ($i < $len) { - switch ($mapping[$i]) { - case '[': - // nested sequence - $output[$key] = self::parseSequence($mapping, $i); - $done = true; - break; - case '{': - // nested mapping - $output[$key] = self::parseMapping($mapping, $i); - $done = true; - break; - case ':': - case ' ': - break; - default: - $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i); - $done = true; - --$i; - } - - ++$i; - - if ($done) { - continue 2; - } - } - } - - throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping)); - } - - /** - * Evaluates scalars and replaces magic values. - * - * @param string $scalar - * - * @return string A YAML string - */ - private static function evaluateScalar($scalar) - { - $scalar = trim($scalar); - $scalarLower = strtolower($scalar); - switch (true) { - case 'null' === $scalarLower: - case '' === $scalar: - case '~' === $scalar: - return null; - case 'true' === $scalarLower: - return true; - case 'false' === $scalarLower: - return false; - // Optimise for returning strings. - case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]): - switch (true) { - case 0 === strpos($scalar, '!str'): - return (string) substr($scalar, 5); - case 0 === strpos($scalar, '! '): - return intval(self::parseScalar(substr($scalar, 2))); - case 0 === strpos($scalar, '!!php/object:'): - if (self::$objectSupport) { - return unserialize(substr($scalar, 13)); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); - } - - return null; - case ctype_digit($scalar): - $raw = $scalar; - $cast = intval($scalar); - - return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); - case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): - $raw = $scalar; - $cast = intval($scalar); - - return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); - case is_numeric($scalar): - return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar); - case '.inf' === $scalarLower: - case '.nan' === $scalarLower: - return -log(0); - case '-.inf' === $scalarLower: - return log(0); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): - return floatval(str_replace(',', '', $scalar)); - case preg_match(self::getTimestampRegex(), $scalar): - return strtotime($scalar); - } - default: - return (string) $scalar; - } - } - - /** - * Gets a regex that matches a YAML date. - * - * @return string The regular expression - * - * @see http://www.yaml.org/spec/1.2/spec.html#id2761573 - */ - private static function getTimestampRegex() - { - return <<[0-9][0-9][0-9][0-9]) - -(?P[0-9][0-9]?) - -(?P[0-9][0-9]?) - (?:(?:[Tt]|[ \t]+) - (?P[0-9][0-9]?) - :(?P[0-9][0-9]) - :(?P[0-9][0-9]) - (?:\.(?P[0-9]*))? - (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) - (?::(?P[0-9][0-9]))?))?)? - $~x -EOF; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -/** - * Contains all events dispatched by an Application. - * - * @author Francesco Levorato - */ -final class ConsoleEvents -{ - /** - * The COMMAND event allows you to attach listeners before any command is - * executed by the console. It also allows you to modify the command, input and output - * before they are handled to the command. - * - * The event listener method receives a Symfony\Component\Console\Event\ConsoleCommandEvent - * instance. - * - * @var string - */ - const COMMAND = 'console.command'; - - /** - * The TERMINATE event allows you to attach listeners after a command is - * executed by the console. - * - * The event listener method receives a Symfony\Component\Console\Event\ConsoleTerminateEvent - * instance. - * - * @var string - */ - const TERMINATE = 'console.terminate'; - - /** - * The EXCEPTION event occurs when an uncaught exception appears. - * - * This event allows you to deal with the exception or - * to modify the thrown exception. The event listener method receives - * a Symfony\Component\Console\Event\ConsoleExceptionEvent - * instance. - * - * @var string - */ - const EXCEPTION = 'console.exception'; -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter class for console output. - * - * @author Konstantin Kudryashov - * - * @api - */ -class OutputFormatter implements OutputFormatterInterface -{ - private $decorated; - private $styles = array(); - private $styleStack; - - /** - * Escapes "<" special char in given text. - * - * @param string $text Text to escape - * - * @return string Escaped text - */ - public static function escape($text) - { - return preg_replace('/([^\\\\]?) FormatterStyle" instances - * - * @api - */ - public function __construct($decorated = false, array $styles = array()) - { - $this->decorated = (Boolean) $decorated; - - $this->setStyle('error', new OutputFormatterStyle('white', 'red')); - $this->setStyle('info', new OutputFormatterStyle('green')); - $this->setStyle('comment', new OutputFormatterStyle('yellow')); - $this->setStyle('question', new OutputFormatterStyle('black', 'cyan')); - - foreach ($styles as $name => $style) { - $this->setStyle($name, $style); - } - - $this->styleStack = new OutputFormatterStyleStack(); - } - - /** - * Sets the decorated flag. - * - * @param Boolean $decorated Whether to decorate the messages or not - * - * @api - */ - public function setDecorated($decorated) - { - $this->decorated = (Boolean) $decorated; - } - - /** - * Gets the decorated flag. - * - * @return Boolean true if the output will decorate messages, false otherwise - * - * @api - */ - public function isDecorated() - { - return $this->decorated; - } - - /** - * Sets a new style. - * - * @param string $name The style name - * @param OutputFormatterStyleInterface $style The style instance - * - * @api - */ - public function setStyle($name, OutputFormatterStyleInterface $style) - { - $this->styles[strtolower($name)] = $style; - } - - /** - * Checks if output formatter has style with specified name. - * - * @param string $name - * - * @return Boolean - * - * @api - */ - public function hasStyle($name) - { - return isset($this->styles[strtolower($name)]); - } - - /** - * Gets style options from style with specified name. - * - * @param string $name - * - * @return OutputFormatterStyleInterface - * - * @throws \InvalidArgumentException When style isn't defined - * - * @api - */ - public function getStyle($name) - { - if (!$this->hasStyle($name)) { - throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name)); - } - - return $this->styles[strtolower($name)]; - } - - /** - * Formats a message according to the given styles. - * - * @param string $message The message to style - * - * @return string The styled message - * - * @api - */ - public function format($message) - { - $offset = 0; - $output = ''; - $tagRegex = '[a-z][a-z0-9_=;-]*'; - preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE); - foreach ($matches[0] as $i => $match) { - $pos = $match[1]; - $text = $match[0]; - - // add the text up to the next tag - $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset)); - $offset = $pos + strlen($text); - - // opening tag? - if ($open = '/' != $text[1]) { - $tag = $matches[1][$i][0]; - } else { - $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : ''; - } - - if (!$open && !$tag) { - // - $this->styleStack->pop(); - } elseif ($pos && '\\' == $message[$pos - 1]) { - // escaped tag - $output .= $this->applyCurrentStyle($text); - } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) { - $output .= $this->applyCurrentStyle($text); - } elseif ($open) { - $this->styleStack->push($style); - } else { - $this->styleStack->pop($style); - } - } - - $output .= $this->applyCurrentStyle(substr($message, $offset)); - - return str_replace('\\<', '<', $output); - } - - /** - * @return OutputFormatterStyleStack - */ - public function getStyleStack() - { - return $this->styleStack; - } - - /** - * Tries to create new style instance from string. - * - * @param string $string - * - * @return OutputFormatterStyle|Boolean false if string is not format string - */ - private function createStyleFromString($string) - { - if (isset($this->styles[$string])) { - return $this->styles[$string]; - } - - if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) { - return false; - } - - $style = new OutputFormatterStyle(); - foreach ($matches as $match) { - array_shift($match); - - if ('fg' == $match[0]) { - $style->setForeground($match[1]); - } elseif ('bg' == $match[0]) { - $style->setBackground($match[1]); - } else { - $style->setOption($match[1]); - } - } - - return $style; - } - - /** - * Applies current style from stack to text, if must be applied. - * - * @param string $text Input text - * - * @return string Styled text - */ - private function applyCurrentStyle($text) - { - return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter interface for console output. - * - * @author Konstantin Kudryashov - * - * @api - */ -interface OutputFormatterInterface -{ - /** - * Sets the decorated flag. - * - * @param Boolean $decorated Whether to decorate the messages or not - * - * @api - */ - public function setDecorated($decorated); - - /** - * Gets the decorated flag. - * - * @return Boolean true if the output will decorate messages, false otherwise - * - * @api - */ - public function isDecorated(); - - /** - * Sets a new style. - * - * @param string $name The style name - * @param OutputFormatterStyleInterface $style The style instance - * - * @api - */ - public function setStyle($name, OutputFormatterStyleInterface $style); - - /** - * Checks if output formatter has style with specified name. - * - * @param string $name - * - * @return Boolean - * - * @api - */ - public function hasStyle($name); - - /** - * Gets style options from style with specified name. - * - * @param string $name - * - * @return OutputFormatterStyleInterface - * - * @api - */ - public function getStyle($name); - - /** - * Formats a message according to the given styles. - * - * @param string $message The message to style - * - * @return string The styled message - * - * @api - */ - public function format($message); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter style class for defining styles. - * - * @author Konstantin Kudryashov - * - * @api - */ -class OutputFormatterStyle implements OutputFormatterStyleInterface -{ - private static $availableForegroundColors = array( - 'black' => 30, - 'red' => 31, - 'green' => 32, - 'yellow' => 33, - 'blue' => 34, - 'magenta' => 35, - 'cyan' => 36, - 'white' => 37 - ); - private static $availableBackgroundColors = array( - 'black' => 40, - 'red' => 41, - 'green' => 42, - 'yellow' => 43, - 'blue' => 44, - 'magenta' => 45, - 'cyan' => 46, - 'white' => 47 - ); - private static $availableOptions = array( - 'bold' => 1, - 'underscore' => 4, - 'blink' => 5, - 'reverse' => 7, - 'conceal' => 8 - ); - - private $foreground; - private $background; - private $options = array(); - - /** - * Initializes output formatter style. - * - * @param string|null $foreground The style foreground color name - * @param string|null $background The style background color name - * @param array $options The style options - * - * @api - */ - public function __construct($foreground = null, $background = null, array $options = array()) - { - if (null !== $foreground) { - $this->setForeground($foreground); - } - if (null !== $background) { - $this->setBackground($background); - } - if (count($options)) { - $this->setOptions($options); - } - } - - /** - * Sets style foreground color. - * - * @param string|null $color The color name - * - * @throws \InvalidArgumentException When the color name isn't defined - * - * @api - */ - public function setForeground($color = null) - { - if (null === $color) { - $this->foreground = null; - - return; - } - - if (!isset(static::$availableForegroundColors[$color])) { - throw new \InvalidArgumentException(sprintf( - 'Invalid foreground color specified: "%s". Expected one of (%s)', - $color, - implode(', ', array_keys(static::$availableForegroundColors)) - )); - } - - $this->foreground = static::$availableForegroundColors[$color]; - } - - /** - * Sets style background color. - * - * @param string|null $color The color name - * - * @throws \InvalidArgumentException When the color name isn't defined - * - * @api - */ - public function setBackground($color = null) - { - if (null === $color) { - $this->background = null; - - return; - } - - if (!isset(static::$availableBackgroundColors[$color])) { - throw new \InvalidArgumentException(sprintf( - 'Invalid background color specified: "%s". Expected one of (%s)', - $color, - implode(', ', array_keys(static::$availableBackgroundColors)) - )); - } - - $this->background = static::$availableBackgroundColors[$color]; - } - - /** - * Sets some specific style option. - * - * @param string $option The option name - * - * @throws \InvalidArgumentException When the option name isn't defined - * - * @api - */ - public function setOption($option) - { - if (!isset(static::$availableOptions[$option])) { - throw new \InvalidArgumentException(sprintf( - 'Invalid option specified: "%s". Expected one of (%s)', - $option, - implode(', ', array_keys(static::$availableOptions)) - )); - } - - if (false === array_search(static::$availableOptions[$option], $this->options)) { - $this->options[] = static::$availableOptions[$option]; - } - } - - /** - * Unsets some specific style option. - * - * @param string $option The option name - * - * @throws \InvalidArgumentException When the option name isn't defined - * - */ - public function unsetOption($option) - { - if (!isset(static::$availableOptions[$option])) { - throw new \InvalidArgumentException(sprintf( - 'Invalid option specified: "%s". Expected one of (%s)', - $option, - implode(', ', array_keys(static::$availableOptions)) - )); - } - - $pos = array_search(static::$availableOptions[$option], $this->options); - if (false !== $pos) { - unset($this->options[$pos]); - } - } - - /** - * Sets multiple style options at once. - * - * @param array $options - */ - public function setOptions(array $options) - { - $this->options = array(); - - foreach ($options as $option) { - $this->setOption($option); - } - } - - /** - * Applies the style to a given text. - * - * @param string $text The text to style - * - * @return string - */ - public function apply($text) - { - $codes = array(); - - if (null !== $this->foreground) { - $codes[] = $this->foreground; - } - if (null !== $this->background) { - $codes[] = $this->background; - } - if (count($this->options)) { - $codes = array_merge($codes, $this->options); - } - - if (0 === count($codes)) { - return $text; - } - - return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter style interface for defining styles. - * - * @author Konstantin Kudryashov - * - * @api - */ -interface OutputFormatterStyleInterface -{ - /** - * Sets style foreground color. - * - * @param string $color The color name - * - * @api - */ - public function setForeground($color = null); - - /** - * Sets style background color. - * - * @param string $color The color name - * - * @api - */ - public function setBackground($color = null); - - /** - * Sets some specific style option. - * - * @param string $option The option name - * - * @api - */ - public function setOption($option); - - /** - * Unsets some specific style option. - * - * @param string $option The option name - */ - public function unsetOption($option); - - /** - * Sets multiple style options at once. - * - * @param array $options - */ - public function setOptions(array $options); - - /** - * Applies the style to a given text. - * - * @param string $text The text to style - * - * @return string - */ - public function apply($text); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * @author Jean-François Simon - */ -class OutputFormatterStyleStack -{ - /** - * @var OutputFormatterStyleInterface[] - */ - private $styles; - - /** - * @var OutputFormatterStyleInterface - */ - private $emptyStyle; - - /** - * Constructor. - * - * @param OutputFormatterStyleInterface|null $emptyStyle - */ - public function __construct(OutputFormatterStyleInterface $emptyStyle = null) - { - $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle(); - $this->reset(); - } - - /** - * Resets stack (ie. empty internal arrays). - */ - public function reset() - { - $this->styles = array(); - } - - /** - * Pushes a style in the stack. - * - * @param OutputFormatterStyleInterface $style - */ - public function push(OutputFormatterStyleInterface $style) - { - $this->styles[] = $style; - } - - /** - * Pops a style from the stack. - * - * @param OutputFormatterStyleInterface|null $style - * - * @return OutputFormatterStyleInterface - * - * @throws \InvalidArgumentException When style tags incorrectly nested - */ - public function pop(OutputFormatterStyleInterface $style = null) - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - if (null === $style) { - return array_pop($this->styles); - } - - foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { - if ($style->apply('') === $stackedStyle->apply('')) { - $this->styles = array_slice($this->styles, 0, $index); - - return $stackedStyle; - } - } - - throw new \InvalidArgumentException('Incorrectly nested style tag found.'); - } - - /** - * Computes current style with stacks top codes. - * - * @return OutputFormatterStyle - */ - public function getCurrent() - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - return $this->styles[count($this->styles)-1]; - } - - /** - * @param OutputFormatterStyleInterface $emptyStyle - * - * @return OutputFormatterStyleStack - */ - public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle) - { - $this->emptyStyle = $emptyStyle; - - return $this; - } - - /** - * @return OutputFormatterStyleInterface - */ - public function getEmptyStyle() - { - return $this->emptyStyle; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * HelperInterface is the interface all helpers must implement. - * - * @author Fabien Potencier - * - * @api - */ -interface HelperInterface -{ - /** - * Sets the helper set associated with this helper. - * - * @param HelperSet $helperSet A HelperSet instance - * - * @api - */ - public function setHelperSet(HelperSet $helperSet = null); - - /** - * Gets the helper set associated with this helper. - * - * @return HelperSet A HelperSet instance - * - * @api - */ - public function getHelperSet(); - - /** - * Returns the canonical name of this helper. - * - * @return string The canonical name - * - * @api - */ - public function getName(); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Formatter\OutputFormatter; - -/** - * The Formatter class provides helpers to format messages. - * - * @author Fabien Potencier - */ -class FormatterHelper extends Helper -{ - /** - * Formats a message within a section. - * - * @param string $section The section name - * @param string $message The message - * @param string $style The style to apply to the section - * - * @return string The format section - */ - public function formatSection($section, $message, $style = 'info') - { - return sprintf('<%s>[%s] %s', $style, $section, $style, $message); - } - - /** - * Formats a message as a block of text. - * - * @param string|array $messages The message to write in the block - * @param string $style The style to apply to the whole block - * @param Boolean $large Whether to return a large block - * - * @return string The formatter message - */ - public function formatBlock($messages, $style, $large = false) - { - $messages = (array) $messages; - - $len = 0; - $lines = array(); - foreach ($messages as $message) { - $message = OutputFormatter::escape($message); - $lines[] = sprintf($large ? ' %s ' : ' %s ', $message); - $len = max($this->strlen($message) + ($large ? 4 : 2), $len); - } - - $messages = $large ? array(str_repeat(' ', $len)) : array(); - foreach ($lines as $line) { - $messages[] = $line.str_repeat(' ', $len - $this->strlen($line)); - } - if ($large) { - $messages[] = str_repeat(' ', $len); - } - - foreach ($messages as &$message) { - $message = sprintf('<%s>%s', $style, $message, $style); - } - - return implode("\n", $messages); - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return 'formatter'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\OutputInterface; -use InvalidArgumentException; - -/** - * Provides helpers to display table output. - * - * @author Саша Стаменковић - */ -class TableHelper extends Helper -{ - const LAYOUT_DEFAULT = 0; - const LAYOUT_BORDERLESS = 1; - const LAYOUT_COMPACT = 2; - - /** - * Table headers. - * - * @var array - */ - private $headers = array(); - - /** - * Table rows. - * - * @var array - */ - private $rows = array(); - - // Rendering options - private $paddingChar; - private $horizontalBorderChar; - private $verticalBorderChar; - private $crossingChar; - private $cellHeaderFormat; - private $cellRowFormat; - private $cellRowContentFormat; - private $borderFormat; - private $padType; - - /** - * Column widths cache. - * - * @var array - */ - private $columnWidths = array(); - - /** - * Number of columns cache. - * - * @var array - */ - private $numberOfColumns; - - /** - * @var OutputInterface - */ - private $output; - - public function __construct() - { - $this->setLayout(self::LAYOUT_DEFAULT); - } - - /** - * Sets table layout type. - * - * @param int $layout self::LAYOUT_* - * - * @return TableHelper - */ - public function setLayout($layout) - { - switch ($layout) { - case self::LAYOUT_BORDERLESS: - $this - ->setPaddingChar(' ') - ->setHorizontalBorderChar('=') - ->setVerticalBorderChar(' ') - ->setCrossingChar(' ') - ->setCellHeaderFormat('%s') - ->setCellRowFormat('%s') - ->setCellRowContentFormat(' %s ') - ->setBorderFormat('%s') - ->setPadType(STR_PAD_RIGHT) - ; - break; - - case self::LAYOUT_COMPACT: - $this - ->setPaddingChar(' ') - ->setHorizontalBorderChar('') - ->setVerticalBorderChar(' ') - ->setCrossingChar('') - ->setCellHeaderFormat('%s') - ->setCellRowFormat('%s') - ->setCellRowContentFormat('%s') - ->setBorderFormat('%s') - ->setPadType(STR_PAD_RIGHT) - ; - break; - - case self::LAYOUT_DEFAULT: - $this - ->setPaddingChar(' ') - ->setHorizontalBorderChar('-') - ->setVerticalBorderChar('|') - ->setCrossingChar('+') - ->setCellHeaderFormat('%s') - ->setCellRowFormat('%s') - ->setCellRowContentFormat(' %s ') - ->setBorderFormat('%s') - ->setPadType(STR_PAD_RIGHT) - ; - break; - - default: - throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout)); - break; - }; - - return $this; - } - - public function setHeaders(array $headers) - { - $this->headers = array_values($headers); - - return $this; - } - - public function setRows(array $rows) - { - $this->rows = array(); - - return $this->addRows($rows); - } - - public function addRows(array $rows) - { - foreach ($rows as $row) { - $this->addRow($row); - } - - return $this; - } - - public function addRow(array $row) - { - $this->rows[] = array_values($row); - - $keys = array_keys($this->rows); - $rowKey = array_pop($keys); - - foreach ($row as $key => $cellValue) { - if (!strstr($cellValue, "\n")) { - continue; - } - - $lines = explode("\n", $cellValue); - $this->rows[$rowKey][$key] = $lines[0]; - unset($lines[0]); - - foreach ($lines as $lineKey => $line) { - $nextRowKey = $rowKey + $lineKey + 1; - - if (isset($this->rows[$nextRowKey])) { - $this->rows[$nextRowKey][$key] = $line; - } else { - $this->rows[$nextRowKey] = array($key => $line); - } - } - } - - return $this; - } - - public function setRow($column, array $row) - { - $this->rows[$column] = $row; - - return $this; - } - - /** - * Sets padding character, used for cell padding. - * - * @param string $paddingChar - * - * @return TableHelper - */ - public function setPaddingChar($paddingChar) - { - if (!$paddingChar) { - throw new \LogicException('The padding char must not be empty'); - } - - $this->paddingChar = $paddingChar; - - return $this; - } - - /** - * Sets horizontal border character. - * - * @param string $horizontalBorderChar - * - * @return TableHelper - */ - public function setHorizontalBorderChar($horizontalBorderChar) - { - $this->horizontalBorderChar = $horizontalBorderChar; - - return $this; - } - - /** - * Sets vertical border character. - * - * @param string $verticalBorderChar - * - * @return TableHelper - */ - public function setVerticalBorderChar($verticalBorderChar) - { - $this->verticalBorderChar = $verticalBorderChar; - - return $this; - } - - /** - * Sets crossing character. - * - * @param string $crossingChar - * - * @return TableHelper - */ - public function setCrossingChar($crossingChar) - { - $this->crossingChar = $crossingChar; - - return $this; - } - - /** - * Sets header cell format. - * - * @param string $cellHeaderFormat - * - * @return TableHelper - */ - public function setCellHeaderFormat($cellHeaderFormat) - { - $this->cellHeaderFormat = $cellHeaderFormat; - - return $this; - } - - /** - * Sets row cell format. - * - * @param string $cellRowFormat - * - * @return TableHelper - */ - public function setCellRowFormat($cellRowFormat) - { - $this->cellRowFormat = $cellRowFormat; - - return $this; - } - - /** - * Sets row cell content format. - * - * @param string $cellRowContentFormat - * - * @return TableHelper - */ - public function setCellRowContentFormat($cellRowContentFormat) - { - $this->cellRowContentFormat = $cellRowContentFormat; - - return $this; - } - - /** - * Sets table border format. - * - * @param string $borderFormat - * - * @return TableHelper - */ - public function setBorderFormat($borderFormat) - { - $this->borderFormat = $borderFormat; - - return $this; - } - - /** - * Sets cell padding type. - * - * @param integer $padType STR_PAD_* - * - * @return TableHelper - */ - public function setPadType($padType) - { - $this->padType = $padType; - - return $this; - } - - /** - * Renders table to output. - * - * Example: - * +---------------+-----------------------+------------------+ - * | ISBN | Title | Author | - * +---------------+-----------------------+------------------+ - * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | - * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | - * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | - * +---------------+-----------------------+------------------+ - * - * @param OutputInterface $output - */ - public function render(OutputInterface $output) - { - $this->output = $output; - - $this->renderRowSeparator(); - $this->renderRow($this->headers, $this->cellHeaderFormat); - if (!empty($this->headers)) { - $this->renderRowSeparator(); - } - foreach ($this->rows as $row) { - $this->renderRow($row, $this->cellRowFormat); - } - if (!empty($this->rows)) { - $this->renderRowSeparator(); - } - - $this->cleanup(); - } - - /** - * Renders horizontal header separator. - * - * Example: +-----+-----------+-------+ - */ - private function renderRowSeparator() - { - if (0 === $count = $this->getNumberOfColumns()) { - return; - } - - if (!$this->horizontalBorderChar && !$this->crossingChar) { - return; - } - - $markup = $this->crossingChar; - for ($column = 0; $column < $count; $column++) { - $markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column)).$this->crossingChar; - } - - $this->output->writeln(sprintf($this->borderFormat, $markup)); - } - - /** - * Renders vertical column separator. - */ - private function renderColumnSeparator() - { - $this->output->write(sprintf($this->borderFormat, $this->verticalBorderChar)); - } - - /** - * Renders table row. - * - * Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | - * - * @param array $row - * @param string $cellFormat - */ - private function renderRow(array $row, $cellFormat) - { - if (empty($row)) { - return; - } - - $this->renderColumnSeparator(); - for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) { - $this->renderCell($row, $column, $cellFormat); - $this->renderColumnSeparator(); - } - $this->output->writeln(''); - } - - /** - * Renders table cell with padding. - * - * @param array $row - * @param integer $column - * @param string $cellFormat - */ - private function renderCell(array $row, $column, $cellFormat) - { - $cell = isset($row[$column]) ? $row[$column] : ''; - $width = $this->getColumnWidth($column); - - // str_pad won't work properly with multi-byte strings, we need to fix the padding - if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($cell)) { - $width += strlen($cell) - mb_strlen($cell, $encoding); - } - - $width += $this->strlen($cell) - $this->computeLengthWithoutDecoration($cell); - - $content = sprintf($this->cellRowContentFormat, $cell); - - $this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->paddingChar, $this->padType))); - } - - /** - * Gets number of columns for this table. - * - * @return int - */ - private function getNumberOfColumns() - { - if (null !== $this->numberOfColumns) { - return $this->numberOfColumns; - } - - $columns = array(0); - $columns[] = count($this->headers); - foreach ($this->rows as $row) { - $columns[] = count($row); - } - - return $this->numberOfColumns = max($columns); - } - - /** - * Gets column width. - * - * @param integer $column - * - * @return int - */ - private function getColumnWidth($column) - { - if (isset($this->columnWidths[$column])) { - return $this->columnWidths[$column]; - } - - $lengths = array(0); - $lengths[] = $this->getCellWidth($this->headers, $column); - foreach ($this->rows as $row) { - $lengths[] = $this->getCellWidth($row, $column); - } - - return $this->columnWidths[$column] = max($lengths) + strlen($this->cellRowContentFormat) - 2; - } - - /** - * Gets cell width. - * - * @param array $row - * @param integer $column - * - * @return int - */ - private function getCellWidth(array $row, $column) - { - return isset($row[$column]) ? $this->computeLengthWithoutDecoration($row[$column]) : 0; - } - - /** - * Called after rendering to cleanup cache data. - */ - private function cleanup() - { - $this->columnWidths = array(); - $this->numberOfColumns = null; - } - - private function computeLengthWithoutDecoration($string) - { - $formatter = $this->output->getFormatter(); - $isDecorated = $formatter->isDecorated(); - $formatter->setDecorated(false); - - $string = $formatter->format($string); - $formatter->setDecorated($isDecorated); - - return $this->strlen($string); - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return 'table'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Descriptor\DescriptorInterface; -use Symfony\Component\Console\Descriptor\JsonDescriptor; -use Symfony\Component\Console\Descriptor\MarkdownDescriptor; -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * This class adds helper method to describe objects in various formats. - * - * @author Jean-François Simon - */ -class DescriptorHelper extends Helper -{ - /** - * @var DescriptorInterface[] - */ - private $descriptors = array(); - - /** - * Constructor. - */ - public function __construct() - { - $this - ->register('txt', new TextDescriptor()) - ->register('xml', new XmlDescriptor()) - ->register('json', new JsonDescriptor()) - ->register('md', new MarkdownDescriptor()) - ; - } - - /** - * Describes an object if supported. - * - * Available options are: - * * format: string, the output format name - * * raw_text: boolean, sets output type as raw - * - * @param OutputInterface $output - * @param object $object - * @param array $options - * - * @throws \InvalidArgumentException - */ - public function describe(OutputInterface $output, $object, array $options = array()) - { - $options = array_merge(array( - 'raw_text' => false, - 'format' => 'txt', - ), $options); - - if (!isset($this->descriptors[$options['format']])) { - throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); - } - - $descriptor = $this->descriptors[$options['format']]; - $descriptor->describe($output, $object, $options); - } - - /** - * Registers a descriptor. - * - * @param string $format - * @param DescriptorInterface $descriptor - * - * @return DescriptorHelper - */ - public function register($format, DescriptorInterface $descriptor) - { - $this->descriptors[$format] = $descriptor; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'descriptor'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputAwareInterface; - -/** - * An implementation of InputAwareInterface for Helpers. - * - * @author Wouter J - */ -abstract class InputAwareHelper extends Helper implements InputAwareInterface -{ - protected $input; - - /** - * {@inheritDoc} - */ - public function setInput(InputInterface $input) - { - $this->input = $input; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * The Progress class provides helpers to display progress output. - * - * @author Chris Jones - * @author Fabien Potencier - */ -class ProgressHelper extends Helper -{ - const FORMAT_QUIET = ' %percent%%'; - const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%'; - const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%'; - const FORMAT_QUIET_NOMAX = ' %current%'; - const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]'; - const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%'; - - // options - private $barWidth = 28; - private $barChar = '='; - private $emptyBarChar = '-'; - private $progressChar = '>'; - private $format = null; - private $redrawFreq = 1; - - private $lastMessagesLength; - private $barCharOriginal; - - /** - * @var OutputInterface - */ - private $output; - - /** - * Current step - * - * @var integer - */ - private $current; - - /** - * Maximum number of steps - * - * @var integer - */ - private $max; - - /** - * Start time of the progress bar - * - * @var integer - */ - private $startTime; - - /** - * List of formatting variables - * - * @var array - */ - private $defaultFormatVars = array( - 'current', - 'max', - 'bar', - 'percent', - 'elapsed', - ); - - /** - * Available formatting variables - * - * @var array - */ - private $formatVars; - - /** - * Stored format part widths (used for padding) - * - * @var array - */ - private $widths = array( - 'current' => 4, - 'max' => 4, - 'percent' => 3, - 'elapsed' => 6, - ); - - /** - * Various time formats - * - * @var array - */ - private $timeFormats = array( - array(0, '???'), - array(2, '1 sec'), - array(59, 'secs', 1), - array(60, '1 min'), - array(3600, 'mins', 60), - array(5400, '1 hr'), - array(86400, 'hrs', 3600), - array(129600, '1 day'), - array(604800, 'days', 86400), - ); - - /** - * Sets the progress bar width. - * - * @param int $size The progress bar size - */ - public function setBarWidth($size) - { - $this->barWidth = (int) $size; - } - - /** - * Sets the bar character. - * - * @param string $char A character - */ - public function setBarCharacter($char) - { - $this->barChar = $char; - } - - /** - * Sets the empty bar character. - * - * @param string $char A character - */ - public function setEmptyBarCharacter($char) - { - $this->emptyBarChar = $char; - } - - /** - * Sets the progress bar character. - * - * @param string $char A character - */ - public function setProgressCharacter($char) - { - $this->progressChar = $char; - } - - /** - * Sets the progress bar format. - * - * @param string $format The format - */ - public function setFormat($format) - { - $this->format = $format; - } - - /** - * Sets the redraw frequency. - * - * @param int $freq The frequency in steps - */ - public function setRedrawFrequency($freq) - { - $this->redrawFreq = (int) $freq; - } - - /** - * Starts the progress output. - * - * @param OutputInterface $output An Output instance - * @param integer|null $max Maximum steps - */ - public function start(OutputInterface $output, $max = null) - { - $this->startTime = time(); - $this->current = 0; - $this->max = (int) $max; - $this->output = $output; - $this->lastMessagesLength = 0; - $this->barCharOriginal = ''; - - if (null === $this->format) { - switch ($output->getVerbosity()) { - case OutputInterface::VERBOSITY_QUIET: - $this->format = self::FORMAT_QUIET_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_QUIET; - } - break; - case OutputInterface::VERBOSITY_VERBOSE: - case OutputInterface::VERBOSITY_VERY_VERBOSE: - case OutputInterface::VERBOSITY_DEBUG: - $this->format = self::FORMAT_VERBOSE_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_VERBOSE; - } - break; - default: - $this->format = self::FORMAT_NORMAL_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_NORMAL; - } - break; - } - } - - $this->initialize(); - } - - /** - * Advances the progress output X steps. - * - * @param integer $step Number of steps to advance - * @param Boolean $redraw Whether to redraw or not - * - * @throws \LogicException - */ - public function advance($step = 1, $redraw = false) - { - $this->setCurrent($this->current + $step, $redraw); - } - - /** - * Sets the current progress. - * - * @param integer $current The current progress - * @param Boolean $redraw Whether to redraw or not - * - * @throws \LogicException - */ - public function setCurrent($current, $redraw = false) - { - if (null === $this->startTime) { - throw new \LogicException('You must start the progress bar before calling setCurrent().'); - } - - $current = (int) $current; - - if ($current < $this->current) { - throw new \LogicException('You can\'t regress the progress bar'); - } - - if (0 === $this->current) { - $redraw = true; - } - - $prevPeriod = intval($this->current / $this->redrawFreq); - - $this->current = $current; - - $currPeriod = intval($this->current / $this->redrawFreq); - if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) { - $this->display(); - } - } - - /** - * Outputs the current progress string. - * - * @param Boolean $finish Forces the end result - * - * @throws \LogicException - */ - public function display($finish = false) - { - if (null === $this->startTime) { - throw new \LogicException('You must start the progress bar before calling display().'); - } - - $message = $this->format; - foreach ($this->generate($finish) as $name => $value) { - $message = str_replace("%{$name}%", $value, $message); - } - $this->overwrite($this->output, $message); - } - - /** - * Removes the progress bar from the current line. - * - * This is useful if you wish to write some output - * while a progress bar is running. - * Call display() to show the progress bar again. - */ - public function clear() - { - $this->overwrite($this->output, ''); - } - - /** - * Finishes the progress output. - */ - public function finish() - { - if (null === $this->startTime) { - throw new \LogicException('You must start the progress bar before calling finish().'); - } - - if (null !== $this->startTime) { - if (!$this->max) { - $this->barChar = $this->barCharOriginal; - $this->display(true); - } - $this->startTime = null; - $this->output->writeln(''); - $this->output = null; - } - } - - /** - * Initializes the progress helper. - */ - private function initialize() - { - $this->formatVars = array(); - foreach ($this->defaultFormatVars as $var) { - if (false !== strpos($this->format, "%{$var}%")) { - $this->formatVars[$var] = true; - } - } - - if ($this->max > 0) { - $this->widths['max'] = $this->strlen($this->max); - $this->widths['current'] = $this->widths['max']; - } else { - $this->barCharOriginal = $this->barChar; - $this->barChar = $this->emptyBarChar; - } - } - - /** - * Generates the array map of format variables to values. - * - * @param Boolean $finish Forces the end result - * - * @return array Array of format vars and values - */ - private function generate($finish = false) - { - $vars = array(); - $percent = 0; - if ($this->max > 0) { - $percent = (float) $this->current / $this->max; - } - - if (isset($this->formatVars['bar'])) { - $completeBars = 0; - - if ($this->max > 0) { - $completeBars = floor($percent * $this->barWidth); - } else { - if (!$finish) { - $completeBars = floor($this->current % $this->barWidth); - } else { - $completeBars = $this->barWidth; - } - } - - $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar); - $bar = str_repeat($this->barChar, $completeBars); - if ($completeBars < $this->barWidth) { - $bar .= $this->progressChar; - $bar .= str_repeat($this->emptyBarChar, $emptyBars); - } - - $vars['bar'] = $bar; - } - - if (isset($this->formatVars['elapsed'])) { - $elapsed = time() - $this->startTime; - $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT); - } - - if (isset($this->formatVars['current'])) { - $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT); - } - - if (isset($this->formatVars['max'])) { - $vars['max'] = $this->max; - } - - if (isset($this->formatVars['percent'])) { - $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT); - } - - return $vars; - } - - /** - * Converts seconds into human-readable format. - * - * @param integer $secs Number of seconds - * - * @return string Time in readable format - */ - private function humaneTime($secs) - { - $text = ''; - foreach ($this->timeFormats as $format) { - if ($secs < $format[0]) { - if (count($format) == 2) { - $text = $format[1]; - break; - } else { - $text = ceil($secs / $format[2]).' '.$format[1]; - break; - } - } - } - - return $text; - } - - /** - * Overwrites a previous message to the output. - * - * @param OutputInterface $output An Output instance - * @param string $message The message - */ - private function overwrite(OutputInterface $output, $message) - { - $length = $this->strlen($message); - - // append whitespace to match the last line's length - if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) { - $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT); - } - - // carriage return - $output->write("\x0D"); - $output->write($message); - - $this->lastMessagesLength = $this->strlen($message); - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return 'progress'; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; - -/** - * The Dialog class provides helpers to interact with the user. - * - * @author Fabien Potencier - */ -class DialogHelper extends InputAwareHelper -{ - private $inputStream; - private static $shell; - private static $stty; - - /** - * Asks the user to select a value. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param array $choices List of choices to pick from - * @param Boolean|string $default The default answer if the user enters nothing - * @param Boolean|integer $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param string $errorMessage Message which will be shown if invalid value from choice list would be picked - * @param Boolean $multiselect Select more than one value separated by comma - * - * @return integer|string|array The selected value or values (the key of the choices array) - * - * @throws \InvalidArgumentException - */ - public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false) - { - $width = max(array_map('strlen', array_keys($choices))); - - $messages = (array) $question; - foreach ($choices as $key => $value) { - $messages[] = sprintf(" [%-${width}s] %s", $key, $value); - } - - $output->writeln($messages); - - $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) { - // Collapse all spaces. - $selectedChoices = str_replace(" ", "", $picked); - - if ($multiselect) { - // Check for a separated comma values - if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { - throw new \InvalidArgumentException(sprintf($errorMessage, $picked)); - } - $selectedChoices = explode(",", $selectedChoices); - } else { - $selectedChoices = array($picked); - } - - $multiselectChoices = array(); - - foreach ($selectedChoices as $value) { - if (empty($choices[$value])) { - throw new \InvalidArgumentException(sprintf($errorMessage, $value)); - } - array_push($multiselectChoices, $value); - } - - if ($multiselect) { - return $multiselectChoices; - } - - return $picked; - }, $attempts, $default); - - return $result; - } - - /** - * Asks a question to the user. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param string $default The default answer if none is given by the user - * @param array $autocomplete List of values to autocomplete - * - * @return string The user answer - * - * @throws \RuntimeException If there is no data to read in the input stream - */ - public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) - { - if ($this->input && !$this->input->isInteractive()) { - return $default; - } - - $output->write($question); - - $inputStream = $this->inputStream ?: STDIN; - - if (null === $autocomplete || !$this->hasSttyAvailable()) { - $ret = fgets($inputStream, 4096); - if (false === $ret) { - throw new \RuntimeException('Aborted'); - } - $ret = trim($ret); - } else { - $ret = ''; - - $i = 0; - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - - $sttyMode = shell_exec('stty -g'); - - // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) - shell_exec('stty -icanon -echo'); - - // Add highlighted text style - $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); - - // Read a keypress - while (!feof($inputStream)) { - $c = fread($inputStream, 1); - - // Backspace Character - if ("\177" === $c) { - if (0 === $numMatches && 0 !== $i) { - $i--; - // Move cursor backwards - $output->write("\033[1D"); - } - - if ($i === 0) { - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - } else { - $numMatches = 0; - } - - // Pop the last character off the end of our string - $ret = substr($ret, 0, $i); - } elseif ("\033" === $c) { // Did we read an escape sequence? - $c .= fread($inputStream, 2); - - // A = Up Arrow. B = Down Arrow - if ('A' === $c[2] || 'B' === $c[2]) { - if ('A' === $c[2] && -1 === $ofs) { - $ofs = 0; - } - - if (0 === $numMatches) { - continue; - } - - $ofs += ('A' === $c[2]) ? -1 : 1; - $ofs = ($numMatches + $ofs) % $numMatches; - } - } elseif (ord($c) < 32) { - if ("\t" === $c || "\n" === $c) { - if ($numMatches > 0 && -1 !== $ofs) { - $ret = $matches[$ofs]; - // Echo out remaining chars for current match - $output->write(substr($ret, $i)); - $i = strlen($ret); - } - - if ("\n" === $c) { - $output->write($c); - break; - } - - $numMatches = 0; - } - - continue; - } else { - $output->write($c); - $ret .= $c; - $i++; - - $numMatches = 0; - $ofs = 0; - - foreach ($autocomplete as $value) { - // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (0 === strpos($value, $ret) && $i !== strlen($value)) { - $matches[$numMatches++] = $value; - } - } - } - - // Erase characters from cursor to end of line - $output->write("\033[K"); - - if ($numMatches > 0 && -1 !== $ofs) { - // Save cursor position - $output->write("\0337"); - // Write highlighted text - $output->write(''.substr($matches[$ofs], $i).''); - // Restore cursor position - $output->write("\0338"); - } - } - - // Reset stty so it behaves normally again - shell_exec(sprintf('stty %s', $sttyMode)); - } - - return strlen($ret) > 0 ? $ret : $default; - } - - /** - * Asks a confirmation to the user. - * - * The question will be asked until the user answers by nothing, yes, or no. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param Boolean $default The default answer if the user enters nothing - * - * @return Boolean true if the user has confirmed, false otherwise - */ - public function askConfirmation(OutputInterface $output, $question, $default = true) - { - $answer = 'z'; - while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) { - $answer = $this->ask($output, $question); - } - - if (false === $default) { - return $answer && 'y' == strtolower($answer[0]); - } - - return !$answer || 'y' == strtolower($answer[0]); - } - - /** - * Asks a question to the user, the response is hidden - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question - * @param Boolean $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not - * - * @return string The answer - * - * @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden - */ - public function askHiddenResponse(OutputInterface $output, $question, $fallback = true) - { - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; - - // handle code running from a phar - if ('phar:' === substr(__FILE__, 0, 5)) { - $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; - copy($exe, $tmpExe); - $exe = $tmpExe; - } - - $output->write($question); - $value = rtrim(shell_exec($exe)); - $output->writeln(''); - - if (isset($tmpExe)) { - unlink($tmpExe); - } - - return $value; - } - - if ($this->hasSttyAvailable()) { - $output->write($question); - - $sttyMode = shell_exec('stty -g'); - - shell_exec('stty -echo'); - $value = fgets($this->inputStream ?: STDIN, 4096); - shell_exec(sprintf('stty %s', $sttyMode)); - - if (false === $value) { - throw new \RuntimeException('Aborted'); - } - - $value = trim($value); - $output->writeln(''); - - return $value; - } - - if (false !== $shell = $this->getShell()) { - $output->write($question); - $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword'; - $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); - $value = rtrim(shell_exec($command)); - $output->writeln(''); - - return $value; - } - - if ($fallback) { - return $this->ask($output, $question); - } - - throw new \RuntimeException('Unable to hide the response'); - } - - /** - * Asks for a value and validates the response. - * - * The validator receives the data to validate. It must return the - * validated data when the data is valid and throw an exception - * otherwise. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param callable $validator A PHP callback - * @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param string $default The default answer if none is given by the user - * @param array $autocomplete List of values to autocomplete - * - * @return mixed - * - * @throws \Exception When any of the validators return an error - */ - public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null) - { - $that = $this; - - $interviewer = function () use ($output, $question, $default, $autocomplete, $that) { - return $that->ask($output, $question, $default, $autocomplete); - }; - - return $this->validateAttempts($interviewer, $output, $validator, $attempts); - } - - /** - * Asks for a value, hide and validates the response. - * - * The validator receives the data to validate. It must return the - * validated data when the data is valid and throw an exception - * otherwise. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param callable $validator A PHP callback - * @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param Boolean $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not - * - * @return string The response - * - * @throws \Exception When any of the validators return an error - * @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden - * - */ - public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true) - { - $that = $this; - - $interviewer = function () use ($output, $question, $fallback, $that) { - return $that->askHiddenResponse($output, $question, $fallback); - }; - - return $this->validateAttempts($interviewer, $output, $validator, $attempts); - } - - /** - * Sets the input stream to read from when interacting with the user. - * - * This is mainly useful for testing purpose. - * - * @param resource $stream The input stream - */ - public function setInputStream($stream) - { - $this->inputStream = $stream; - } - - /** - * Returns the helper's input stream - * - * @return string - */ - public function getInputStream() - { - return $this->inputStream; - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return 'dialog'; - } - - /** - * Return a valid Unix shell - * - * @return string|Boolean The valid shell name, false in case no valid shell is found - */ - private function getShell() - { - if (null !== self::$shell) { - return self::$shell; - } - - self::$shell = false; - - if (file_exists('/usr/bin/env')) { - // handle other OSs with bash/zsh/ksh/csh if available to hide the answer - $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; - foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) { - if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { - self::$shell = $sh; - break; - } - } - } - - return self::$shell; - } - - private function hasSttyAvailable() - { - if (null !== self::$stty) { - return self::$stty; - } - - exec('stty 2>&1', $output, $exitcode); - - return self::$stty = $exitcode === 0; - } - - /** - * Validate an attempt - * - * @param callable $interviewer A callable that will ask for a question and return the result - * @param OutputInterface $output An Output instance - * @param callable $validator A PHP callback - * @param integer $attempts Max number of times to ask before giving up ; false will ask infinitely - * - * @return string The validated response - * - * @throws \Exception In case the max number of attempts has been reached and no valid response has been given - */ - private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts) - { - $error = null; - while (false === $attempts || $attempts--) { - if (null !== $error) { - $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error')); - } - - try { - return call_user_func($validator, $interviewer()); - } catch (\Exception $error) { - } - } - - throw $error; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * Helper is the base class for all helper classes. - * - * @author Fabien Potencier - */ -abstract class Helper implements HelperInterface -{ - protected $helperSet = null; - - /** - * Sets the helper set associated with this helper. - * - * @param HelperSet $helperSet A HelperSet instance - */ - public function setHelperSet(HelperSet $helperSet = null) - { - $this->helperSet = $helperSet; - } - - /** - * Gets the helper set associated with this helper. - * - * @return HelperSet A HelperSet instance - */ - public function getHelperSet() - { - return $this->helperSet; - } - - /** - * Returns the length of a string, using mb_strlen if it is available. - * - * @param string $string The string to check its length - * - * @return integer The length of the string - */ - protected function strlen($string) - { - if (!function_exists('mb_strlen')) { - return strlen($string); - } - - if (false === $encoding = mb_detect_encoding($string)) { - return strlen($string); - } - - return mb_strlen($string, $encoding); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Command\Command; - -/** - * HelperSet represents a set of helpers to be used with a command. - * - * @author Fabien Potencier - */ -class HelperSet implements \IteratorAggregate -{ - private $helpers = array(); - private $command; - - /** - * Constructor. - * - * @param Helper[] $helpers An array of helper. - */ - public function __construct(array $helpers = array()) - { - foreach ($helpers as $alias => $helper) { - $this->set($helper, is_int($alias) ? null : $alias); - } - } - - /** - * Sets a helper. - * - * @param HelperInterface $helper The helper instance - * @param string $alias An alias - */ - public function set(HelperInterface $helper, $alias = null) - { - $this->helpers[$helper->getName()] = $helper; - if (null !== $alias) { - $this->helpers[$alias] = $helper; - } - - $helper->setHelperSet($this); - } - - /** - * Returns true if the helper if defined. - * - * @param string $name The helper name - * - * @return Boolean true if the helper is defined, false otherwise - */ - public function has($name) - { - return isset($this->helpers[$name]); - } - - /** - * Gets a helper value. - * - * @param string $name The helper name - * - * @return HelperInterface The helper instance - * - * @throws \InvalidArgumentException if the helper is not defined - */ - public function get($name) - { - if (!$this->has($name)) { - throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); - } - - return $this->helpers[$name]; - } - - /** - * Sets the command associated with this helper set. - * - * @param Command $command A Command instance - */ - public function setCommand(Command $command = null) - { - $this->command = $command; - } - - /** - * Gets the command associated with this helper set. - * - * @return Command A Command instance - */ - public function getCommand() - { - return $this->command; - } - - public function getIterator() - { - return new \ArrayIterator($this->helpers); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\StreamOutput; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Eases the testing of console commands. - * - * @author Fabien Potencier - */ -class CommandTester -{ - private $command; - private $input; - private $output; - private $statusCode; - - /** - * Constructor. - * - * @param Command $command A Command instance to test. - */ - public function __construct(Command $command) - { - $this->command = $command; - } - - /** - * Executes the command. - * - * Available options: - * - * * interactive: Sets the input interactive flag - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag - * - * @param array $input An array of arguments and options - * @param array $options An array of options - * - * @return integer The command exit code - */ - public function execute(array $input, array $options = array()) - { - // set the command name automatically if the application requires - // this argument and no command name was passed - if (!isset($input['command']) - && (null !== $application = $this->command->getApplication()) - && $application->getDefinition()->hasArgument('command') - ) { - $input['command'] = $this->command->getName(); - } - - $this->input = new ArrayInput($input); - if (isset($options['interactive'])) { - $this->input->setInteractive($options['interactive']); - } - - $this->output = new StreamOutput(fopen('php://memory', 'w', false)); - if (isset($options['decorated'])) { - $this->output->setDecorated($options['decorated']); - } - if (isset($options['verbosity'])) { - $this->output->setVerbosity($options['verbosity']); - } - - return $this->statusCode = $this->command->run($this->input, $this->output); - } - - /** - * Gets the display returned by the last execution of the command. - * - * @param Boolean $normalize Whether to normalize end of lines to \n or not - * - * @return string The display - */ - public function getDisplay($normalize = false) - { - rewind($this->output->getStream()); - - $display = stream_get_contents($this->output->getStream()); - - if ($normalize) { - $display = str_replace(PHP_EOL, "\n", $display); - } - - return $display; - } - - /** - * Gets the input instance used by the last execution of the command. - * - * @return InputInterface The current input instance - */ - public function getInput() - { - return $this->input; - } - - /** - * Gets the output instance used by the last execution of the command. - * - * @return OutputInterface The current output instance - */ - public function getOutput() - { - return $this->output; - } - - /** - * Gets the status code returned by the last execution of the application. - * - * @return integer The status code - */ - public function getStatusCode() - { - return $this->statusCode; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\StreamOutput; - -/** - * Eases the testing of console applications. - * - * When testing an application, don't forget to disable the auto exit flag: - * - * $application = new Application(); - * $application->setAutoExit(false); - * - * @author Fabien Potencier - */ -class ApplicationTester -{ - private $application; - private $input; - private $output; - private $statusCode; - - /** - * Constructor. - * - * @param Application $application An Application instance to test. - */ - public function __construct(Application $application) - { - $this->application = $application; - } - - /** - * Executes the application. - * - * Available options: - * - * * interactive: Sets the input interactive flag - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag - * - * @param array $input An array of arguments and options - * @param array $options An array of options - * - * @return integer The command exit code - */ - public function run(array $input, $options = array()) - { - $this->input = new ArrayInput($input); - if (isset($options['interactive'])) { - $this->input->setInteractive($options['interactive']); - } - - $this->output = new StreamOutput(fopen('php://memory', 'w', false)); - if (isset($options['decorated'])) { - $this->output->setDecorated($options['decorated']); - } - if (isset($options['verbosity'])) { - $this->output->setVerbosity($options['verbosity']); - } - - return $this->statusCode = $this->application->run($this->input, $this->output); - } - - /** - * Gets the display returned by the last execution of the application. - * - * @param Boolean $normalize Whether to normalize end of lines to \n or not - * - * @return string The display - */ - public function getDisplay($normalize = false) - { - rewind($this->output->getStream()); - - $display = stream_get_contents($this->output->getStream()); - - if ($normalize) { - $display = str_replace(PHP_EOL, "\n", $display); - } - - return $display; - } - - /** - * Gets the input instance used by the last execution of the application. - * - * @return InputInterface The current input instance - */ - public function getInput() - { - return $this->input; - } - - /** - * Gets the output instance used by the last execution of the application. - * - * @return OutputInterface The current output instance - */ - public function getOutput() - { - return $this->output; - } - - /** - * Gets the status code returned by the last execution of the application. - * - * @return integer The status code - */ - public function getStatusCode() - { - return $this->statusCode; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -/** - * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. - * This adds information about stderr output stream. - * - * @author Dariusz Górecki - */ -interface ConsoleOutputInterface extends OutputInterface -{ - /** - * Gets the OutputInterface for errors. - * - * @return OutputInterface - */ - public function getErrorOutput(); - - /** - * Sets the OutputInterface used for errors. - * - * @param OutputInterface $error - */ - public function setErrorOutput(OutputInterface $error); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; -use Symfony\Component\Console\Formatter\OutputFormatter; - -/** - * Base class for output classes. - * - * There are five levels of verbosity: - * - * * normal: no option passed (normal output) - * * verbose: -v (more output) - * * very verbose: -vv (highly extended output) - * * debug: -vvv (all debug output) - * * quiet: -q (no output) - * - * @author Fabien Potencier - * - * @api - */ -abstract class Output implements OutputInterface -{ - private $verbosity; - private $formatter; - - /** - * Constructor. - * - * @param integer $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param Boolean $decorated Whether to decorate messages - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - * - * @api - */ - public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null) - { - $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity; - $this->formatter = $formatter ?: new OutputFormatter(); - $this->formatter->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - $this->formatter = $formatter; - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - return $this->formatter; - } - - /** - * {@inheritdoc} - */ - public function setDecorated($decorated) - { - $this->formatter->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return $this->formatter->isDecorated(); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity($level) - { - $this->verbosity = (int) $level; - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return $this->verbosity; - } - - public function isQuiet() - { - return self::VERBOSITY_QUIET === $this->verbosity; - } - - public function isVerbose() - { - return self::VERBOSITY_VERBOSE <= $this->verbosity; - } - - public function isVeryVerbose() - { - return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; - } - - public function isDebug() - { - return self::VERBOSITY_DEBUG <= $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, $type = self::OUTPUT_NORMAL) - { - $this->write($messages, true, $type); - } - - /** - * {@inheritdoc} - */ - public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) - { - if (self::VERBOSITY_QUIET === $this->verbosity) { - return; - } - - $messages = (array) $messages; - - foreach ($messages as $message) { - switch ($type) { - case OutputInterface::OUTPUT_NORMAL: - $message = $this->formatter->format($message); - break; - case OutputInterface::OUTPUT_RAW: - break; - case OutputInterface::OUTPUT_PLAIN: - $message = strip_tags($this->formatter->format($message)); - break; - default: - throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type)); - } - - $this->doWrite($message, $newline); - } - } - - /** - * Writes a message to the output. - * - * @param string $message A message to write to the output - * @param Boolean $newline Whether to add a newline or not - */ - abstract protected function doWrite($message, $newline); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * StreamOutput writes the output to a given stream. - * - * Usage: - * - * $output = new StreamOutput(fopen('php://stdout', 'w')); - * - * As `StreamOutput` can use any stream, you can also use a file: - * - * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false)); - * - * @author Fabien Potencier - * - * @api - */ -class StreamOutput extends Output -{ - private $stream; - - /** - * Constructor. - * - * @param mixed $stream A stream resource - * @param integer $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param Boolean|null $decorated Whether to decorate messages (null for auto-guessing) - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - * - * @throws \InvalidArgumentException When first argument is not a real stream - * - * @api - */ - public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null) - { - if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) { - throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); - } - - $this->stream = $stream; - - if (null === $decorated) { - $decorated = $this->hasColorSupport(); - } - - parent::__construct($verbosity, $decorated, $formatter); - } - - /** - * Gets the stream attached to this StreamOutput instance. - * - * @return resource A stream resource - */ - public function getStream() - { - return $this->stream; - } - - /** - * {@inheritdoc} - */ - protected function doWrite($message, $newline) - { - if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) { - // @codeCoverageIgnoreStart - // should never happen - throw new \RuntimeException('Unable to write output.'); - // @codeCoverageIgnoreEnd - } - - fflush($this->stream); - } - - /** - * Returns true if the stream supports colorization. - * - * Colorization is disabled if not supported by the stream: - * - * - Windows without Ansicon and ConEmu - * - non tty consoles - * - * @return Boolean true if the stream supports colorization, false otherwise - */ - protected function hasColorSupport() - { - // @codeCoverageIgnoreStart - if (DIRECTORY_SEPARATOR == '\\') { - return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); - } - - return function_exists('posix_isatty') && @posix_isatty($this->stream); - // @codeCoverageIgnoreEnd - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * ConsoleOutput is the default class for all CLI output. It uses STDOUT. - * - * This class is a convenient wrapper around `StreamOutput`. - * - * $output = new ConsoleOutput(); - * - * This is equivalent to: - * - * $output = new StreamOutput(fopen('php://stdout', 'w')); - * - * @author Fabien Potencier - * - * @api - */ -class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface -{ - private $stderr; - - /** - * Constructor. - * - * @param integer $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param Boolean|null $decorated Whether to decorate messages (null for auto-guessing) - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - * - * @api - */ - public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null) - { - $outputStream = 'php://stdout'; - if (!$this->hasStdoutSupport()) { - $outputStream = 'php://output'; - } - - parent::__construct(fopen($outputStream, 'w'), $verbosity, $decorated, $formatter); - - $this->stderr = new StreamOutput(fopen('php://stderr', 'w'), $verbosity, $decorated, $formatter); - } - - /** - * {@inheritdoc} - */ - public function setDecorated($decorated) - { - parent::setDecorated($decorated); - $this->stderr->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - parent::setFormatter($formatter); - $this->stderr->setFormatter($formatter); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity($level) - { - parent::setVerbosity($level); - $this->stderr->setVerbosity($level); - } - - /** - * {@inheritdoc} - */ - public function getErrorOutput() - { - return $this->stderr; - } - - /** - * {@inheritdoc} - */ - public function setErrorOutput(OutputInterface $error) - { - $this->stderr = $error; - } - - /** - * Returns true if current environment supports writing console output to - * STDOUT. - * - * IBM iSeries (OS400) exhibits character-encoding issues when writing to - * STDOUT and doesn't properly convert ASCII to EBCDIC, resulting in garbage - * output. - * - * @return boolean - */ - protected function hasStdoutSupport() - { - return ('OS400' != php_uname('s')); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * NullOutput suppresses all output. - * - * $output = new NullOutput(); - * - * @author Fabien Potencier - * @author Tobias Schultze - * - * @api - */ -class NullOutput implements OutputInterface -{ - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - // to comply with the interface we must return a OutputFormatterInterface - return new OutputFormatter(); - } - - /** - * {@inheritdoc} - */ - public function setDecorated($decorated) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function setVerbosity($level) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return self::VERBOSITY_QUIET; - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, $type = self::OUTPUT_NORMAL) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) - { - // do nothing - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -/** - * @author Jean-François Simon - */ -class BufferedOutput extends Output -{ - /** - * @var string - */ - private $buffer = ''; - - /** - * Empties buffer and returns its content. - * - * @return string - */ - public function fetch() - { - $content = $this->buffer; - $this->buffer = ''; - - return $content; - } - - /** - * {@inheritdoc} - */ - protected function doWrite($message, $newline) - { - $this->buffer .= $message; - - if ($newline) { - $this->buffer .= "\n"; - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * OutputInterface is the interface implemented by all Output classes. - * - * @author Fabien Potencier - * - * @api - */ -interface OutputInterface -{ - const VERBOSITY_QUIET = 0; - const VERBOSITY_NORMAL = 1; - const VERBOSITY_VERBOSE = 2; - const VERBOSITY_VERY_VERBOSE = 3; - const VERBOSITY_DEBUG = 4; - - const OUTPUT_NORMAL = 0; - const OUTPUT_RAW = 1; - const OUTPUT_PLAIN = 2; - - /** - * Writes a message to the output. - * - * @param string|array $messages The message as an array of lines or a single string - * @param Boolean $newline Whether to add a newline - * @param integer $type The type of output (one of the OUTPUT constants) - * - * @throws \InvalidArgumentException When unknown output type is given - * - * @api - */ - public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL); - - /** - * Writes a message to the output and adds a newline at the end. - * - * @param string|array $messages The message as an array of lines of a single string - * @param integer $type The type of output (one of the OUTPUT constants) - * - * @throws \InvalidArgumentException When unknown output type is given - * - * @api - */ - public function writeln($messages, $type = self::OUTPUT_NORMAL); - - /** - * Sets the verbosity of the output. - * - * @param integer $level The level of verbosity (one of the VERBOSITY constants) - * - * @api - */ - public function setVerbosity($level); - - /** - * Gets the current verbosity of the output. - * - * @return integer The current level of verbosity (one of the VERBOSITY constants) - * - * @api - */ - public function getVerbosity(); - - /** - * Sets the decorated flag. - * - * @param Boolean $decorated Whether to decorate the messages - * - * @api - */ - public function setDecorated($decorated); - - /** - * Gets the decorated flag. - * - * @return Boolean true if the output will decorate messages, false otherwise - * - * @api - */ - public function isDecorated(); - - /** - * Sets output formatter. - * - * @param OutputFormatterInterface $formatter - * - * @api - */ - public function setFormatter(OutputFormatterInterface $formatter); - - /** - * Returns current output formatter instance. - * - * @return OutputFormatterInterface - * - * @api - */ - public function getFormatter(); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Jean-François Simon - */ -abstract class Descriptor implements DescriptorInterface -{ - /** - * @var OutputInterface - */ - private $output; - - /** - * {@inheritdoc} - */ - public function describe(OutputInterface $output, $object, array $options = array()) - { - $this->output = $output; - - switch (true) { - case $object instanceof InputArgument: - $this->describeInputArgument($object, $options); - break; - case $object instanceof InputOption: - $this->describeInputOption($object, $options); - break; - case $object instanceof InputDefinition: - $this->describeInputDefinition($object, $options); - break; - case $object instanceof Command: - $this->describeCommand($object, $options); - break; - case $object instanceof Application: - $this->describeApplication($object, $options); - break; - default: - throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object))); - } - } - - /** - * Writes content to output. - * - * @param string $content - * @param boolean $decorated - */ - protected function write($content, $decorated = false) - { - $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW); - } - - /** - * Describes an InputArgument instance. - * - * @param InputArgument $argument - * @param array $options - * - * @return string|mixed - */ - abstract protected function describeInputArgument(InputArgument $argument, array $options = array()); - - /** - * Describes an InputOption instance. - * - * @param InputOption $option - * @param array $options - * - * @return string|mixed - */ - abstract protected function describeInputOption(InputOption $option, array $options = array()); - - /** - * Describes an InputDefinition instance. - * - * @param InputDefinition $definition - * @param array $options - * - * @return string|mixed - */ - abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array()); - - /** - * Describes a Command instance. - * - * @param Command $command - * @param array $options - * - * @return string|mixed - */ - abstract protected function describeCommand(Command $command, array $options = array()); - - /** - * Describes an Application instance. - * - * @param Application $application - * @param array $options - * - * @return string|mixed - */ - abstract protected function describeApplication(Application $application, array $options = array()); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * XML descriptor. - * - * @author Jean-François Simon - */ -class XmlDescriptor extends Descriptor -{ - /** - * @param InputDefinition $definition - * - * @return \DOMDocument - */ - public function getInputDefinitionDocument(InputDefinition $definition) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($definitionXML = $dom->createElement('definition')); - - $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); - foreach ($definition->getArguments() as $argument) { - $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument)); - } - - $definitionXML->appendChild($optionsXML = $dom->createElement('options')); - foreach ($definition->getOptions() as $option) { - $this->appendDocument($optionsXML, $this->getInputOptionDocument($option)); - } - - return $dom; - } - - /** - * @param Command $command - * - * @return \DOMDocument - */ - public function getCommandDocument(Command $command) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($commandXML = $dom->createElement('command')); - - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - $commandXML->setAttribute('id', $command->getName()); - $commandXML->setAttribute('name', $command->getName()); - - $commandXML->appendChild($usageXML = $dom->createElement('usage')); - $usageXML->appendChild($dom->createTextNode(sprintf($command->getSynopsis(), ''))); - - $commandXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription()))); - - $commandXML->appendChild($helpXML = $dom->createElement('help')); - $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp()))); - - $commandXML->appendChild($aliasesXML = $dom->createElement('aliases')); - foreach ($command->getAliases() as $alias) { - $aliasesXML->appendChild($aliasXML = $dom->createElement('alias')); - $aliasXML->appendChild($dom->createTextNode($alias)); - } - - $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition()); - $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); - - return $dom; - } - - /** - * @param Application $application - * @param string|null $namespace - * - * @return \DOMDocument - */ - public function getApplicationDocument(Application $application, $namespace = null) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($rootXml = $dom->createElement('symfony')); - - if ($application->getName() !== 'UNKNOWN') { - $rootXml->setAttribute('name', $application->getName()); - if ($application->getVersion() !== 'UNKNOWN') { - $rootXml->setAttribute('version', $application->getVersion()); - } - } - - $rootXml->appendChild($commandsXML = $dom->createElement('commands')); - - $description = new ApplicationDescription($application, $namespace); - - if ($namespace) { - $commandsXML->setAttribute('namespace', $namespace); - } - - foreach ($description->getCommands() as $command) { - $this->appendDocument($commandsXML, $this->getCommandDocument($command)); - } - - if (!$namespace) { - $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); - - foreach ($description->getNamespaces() as $namespaceDescription) { - $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); - $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']); - - foreach ($namespaceDescription['commands'] as $name) { - $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); - $commandXML->appendChild($dom->createTextNode($name)); - } - } - } - - return $dom; - } - - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = array()) - { - $this->writeDocument($this->getInputArgumentDocument($argument)); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = array()) - { - $this->writeDocument($this->getInputOptionDocument($option)); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) - { - $this->writeDocument($this->getInputDefinitionDocument($definition)); - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = array()) - { - $this->writeDocument($this->getCommandDocument($command)); - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = array()) - { - $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null)); - } - - /** - * Appends document children to parent node. - * - * @param \DOMNode $parentNode - * @param \DOMNode $importedParent - */ - private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) - { - foreach ($importedParent->childNodes as $childNode) { - $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true)); - } - } - - /** - * Writes DOM document. - * - * @param \DOMDocument $dom - * - * @return \DOMDocument|string - */ - private function writeDocument(\DOMDocument $dom) - { - $dom->formatOutput = true; - $this->write($dom->saveXML()); - } - - /** - * @param InputArgument $argument - * - * @return \DOMDocument - */ - private function getInputArgumentDocument(InputArgument $argument) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - - $dom->appendChild($objectXML = $dom->createElement('argument')); - $objectXML->setAttribute('name', $argument->getName()); - $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0); - $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0); - $objectXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode($argument->getDescription())); - - $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); - $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array())); - foreach ($defaults as $default) { - $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); - $defaultXML->appendChild($dom->createTextNode($default)); - } - - return $dom; - } - - /** - * @param InputOption $option - * - * @return \DOMDocument - */ - private function getInputOptionDocument(InputOption $option) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - - $dom->appendChild($objectXML = $dom->createElement('option')); - $objectXML->setAttribute('name', '--'.$option->getName()); - $pos = strpos($option->getShortcut(), '|'); - if (false !== $pos) { - $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); - $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut()))); - } else { - $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); - } - $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); - $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); - $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); - $objectXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode($option->getDescription())); - - if ($option->acceptValue()) { - $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array())); - $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); - - if (!empty($defaults)) { - foreach ($defaults as $default) { - $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); - $defaultXML->appendChild($dom->createTextNode($default)); - } - } - } - - return $dom; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * Text descriptor. - * - * @author Jean-François Simon - */ -class TextDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = array()) - { - if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) { - $default = sprintf(' (default: %s)', $this->formatDefaultValue($argument->getDefault())); - } else { - $default = ''; - } - - $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($argument->getName()); - - $this->writeText(sprintf(" %-${nameWidth}s %s%s", - $argument->getName(), - str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $argument->getDescription()), - $default - ), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = array()) - { - if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) { - $default = sprintf(' (default: %s)', $this->formatDefaultValue($option->getDefault())); - } else { - $default = ''; - } - - $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($option->getName()); - $nameWithShortcutWidth = $nameWidth - strlen($option->getName()) - 2; - - $this->writeText(sprintf(" %s %-${nameWithShortcutWidth}s%s%s%s", - '--'.$option->getName(), - $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '', - str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $option->getDescription()), - $default, - $option->isArray() ? ' (multiple values allowed)' : '' - ), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) - { - $nameWidth = 0; - foreach ($definition->getOptions() as $option) { - $nameLength = strlen($option->getName()) + 2; - if ($option->getShortcut()) { - $nameLength += strlen($option->getShortcut()) + 3; - } - $nameWidth = max($nameWidth, $nameLength); - } - foreach ($definition->getArguments() as $argument) { - $nameWidth = max($nameWidth, strlen($argument->getName())); - } - ++$nameWidth; - - if ($definition->getArguments()) { - $this->writeText('Arguments:', $options); - $this->writeText("\n"); - foreach ($definition->getArguments() as $argument) { - $this->describeInputArgument($argument, array_merge($options, array('name_width' => $nameWidth))); - $this->writeText("\n"); - } - } - - if ($definition->getArguments() && $definition->getOptions()) { - $this->writeText("\n"); - } - - if ($definition->getOptions()) { - $this->writeText('Options:', $options); - $this->writeText("\n"); - foreach ($definition->getOptions() as $option) { - $this->describeInputOption($option, array_merge($options, array('name_width' => $nameWidth))); - $this->writeText("\n"); - } - } - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = array()) - { - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - $this->writeText('Usage:', $options); - $this->writeText("\n"); - $this->writeText(' '.$command->getSynopsis(), $options); - $this->writeText("\n"); - - if (count($command->getAliases()) > 0) { - $this->writeText("\n"); - $this->writeText('Aliases: '.implode(', ', $command->getAliases()).'', $options); - } - - if ($definition = $command->getNativeDefinition()) { - $this->writeText("\n"); - $this->describeInputDefinition($definition, $options); - } - - $this->writeText("\n"); - - if ($help = $command->getProcessedHelp()) { - $this->writeText('Help:', $options); - $this->writeText("\n"); - $this->writeText(' '.str_replace("\n", "\n ", $help), $options); - $this->writeText("\n"); - } - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = array()) - { - $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; - $description = new ApplicationDescription($application, $describedNamespace); - - if (isset($options['raw_text']) && $options['raw_text']) { - $width = $this->getColumnWidth($description->getCommands()); - - foreach ($description->getCommands() as $command) { - $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options); - $this->writeText("\n"); - } - } else { - $width = $this->getColumnWidth($description->getCommands()); - - $this->writeText($application->getHelp(), $options); - $this->writeText("\n\n"); - - if ($describedNamespace) { - $this->writeText(sprintf("Available commands for the \"%s\" namespace:", $describedNamespace), $options); - } else { - $this->writeText('Available commands:', $options); - } - - // add commands by namespace - foreach ($description->getNamespaces() as $namespace) { - if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $this->writeText("\n"); - $this->writeText(''.$namespace['id'].'', $options); - } - - foreach ($namespace['commands'] as $name) { - $this->writeText("\n"); - $this->writeText(sprintf(" %-${width}s %s", $name, $description->getCommand($name)->getDescription()), $options); - } - } - - $this->writeText("\n"); - } - } - - /** - * {@inheritdoc} - */ - private function writeText($content, array $options = array()) - { - $this->write( - isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, - isset($options['raw_output']) ? !$options['raw_output'] : true - ); - } - - /** - * Formats input option/argument default value. - * - * @param mixed $default - * - * @return string - */ - private function formatDefaultValue($default) - { - if (version_compare(PHP_VERSION, '5.4', '<')) { - return str_replace('\/', '/', json_encode($default)); - } - - return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - /** - * @param Command[] $commands - * - * @return int - */ - private function getColumnWidth(array $commands) - { - $width = 0; - foreach ($commands as $command) { - $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width; - } - - return $width + 2; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * Markdown descriptor. - * - * @author Jean-François Simon - */ -class MarkdownDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = array()) - { - $this->write( - '**'.$argument->getName().':**'."\n\n" - .'* Name: '.($argument->getName() ?: '')."\n" - .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" - .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" - .'* Description: '.($argument->getDescription() ?: '')."\n" - .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`' - ); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = array()) - { - $this->write( - '**'.$option->getName().':**'."\n\n" - .'* Name: `--'.$option->getName().'`'."\n" - .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '')."\n" - .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" - .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" - .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" - .'* Description: '.($option->getDescription() ?: '')."\n" - .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`' - ); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) - { - if ($showArguments = count($definition->getArguments()) > 0) { - $this->write('### Arguments:'); - foreach ($definition->getArguments() as $argument) { - $this->write("\n\n"); - $this->write($this->describeInputArgument($argument)); - } - } - - if (count($definition->getOptions()) > 0) { - if ($showArguments) { - $this->write("\n\n"); - } - - $this->write('### Options:'); - foreach ($definition->getOptions() as $option) { - $this->write("\n\n"); - $this->write($this->describeInputOption($option)); - } - } - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = array()) - { - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - $this->write( - $command->getName()."\n" - .str_repeat('-', strlen($command->getName()))."\n\n" - .'* Description: '.($command->getDescription() ?: '')."\n" - .'* Usage: `'.$command->getSynopsis().'`'."\n" - .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : '') - ); - - if ($help = $command->getProcessedHelp()) { - $this->write("\n\n"); - $this->write($help); - } - - if ($definition = $command->getNativeDefinition()) { - $this->write("\n\n"); - $this->describeInputDefinition($command->getNativeDefinition()); - } - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = array()) - { - $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; - $description = new ApplicationDescription($application, $describedNamespace); - - $this->write($application->getName()."\n".str_repeat('=', strlen($application->getName()))); - - foreach ($description->getNamespaces() as $namespace) { - if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $this->write("\n\n"); - $this->write('**'.$namespace['id'].':**'); - } - - $this->write("\n\n"); - $this->write(implode("\n", array_map(function ($commandName) { - return '* '.$commandName; - } , $namespace['commands']))); - } - - foreach ($description->getCommands() as $command) { - $this->write("\n\n"); - $this->write($this->describeCommand($command)); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; - -/** - * @author Jean-François Simon - */ -class ApplicationDescription -{ - const GLOBAL_NAMESPACE = '_global'; - - /** - * @var Application - */ - private $application; - - /** - * @var null|string - */ - private $namespace; - - /** - * @var array - */ - private $namespaces; - - /** - * @var Command[] - */ - private $commands; - - /** - * @var Command[] - */ - private $aliases; - - /** - * Constructor. - * - * @param Application $application - * @param string|null $namespace - */ - public function __construct(Application $application, $namespace = null) - { - $this->application = $application; - $this->namespace = $namespace; - } - - /** - * @return array - */ - public function getNamespaces() - { - if (null === $this->namespaces) { - $this->inspectApplication(); - } - - return $this->namespaces; - } - - /** - * @return Command[] - */ - public function getCommands() - { - if (null === $this->commands) { - $this->inspectApplication(); - } - - return $this->commands; - } - - /** - * @param string $name - * - * @return Command - * - * @throws \InvalidArgumentException - */ - public function getCommand($name) - { - if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { - throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name)); - } - - return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name]; - } - - private function inspectApplication() - { - $this->commands = array(); - $this->namespaces = array(); - - $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null); - foreach ($this->sortCommands($all) as $namespace => $commands) { - $names = array(); - - /** @var Command $command */ - foreach ($commands as $name => $command) { - if (!$command->getName()) { - continue; - } - - if ($command->getName() === $name) { - $this->commands[$name] = $command; - } else { - $this->aliases[$name] = $command; - } - - $names[] = $name; - } - - $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names); - } - } - - /** - * @param array $commands - * - * @return array - */ - private function sortCommands(array $commands) - { - $namespacedCommands = array(); - foreach ($commands as $name => $command) { - $key = $this->application->extractNamespace($name, 1); - if (!$key) { - $key = '_global'; - } - - $namespacedCommands[$key][$name] = $command; - } - ksort($namespacedCommands); - - foreach ($namespacedCommands as &$commands) { - ksort($commands); - } - - return $namespacedCommands; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * JSON descriptor. - * - * @author Jean-François Simon - */ -class JsonDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = array()) - { - $this->writeData($this->getInputArgumentData($argument), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = array()) - { - $this->writeData($this->getInputOptionData($option), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) - { - $this->writeData($this->getInputDefinitionData($definition), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = array()) - { - $this->writeData($this->getCommandData($command), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = array()) - { - $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; - $description = new ApplicationDescription($application, $describedNamespace); - $commands = array(); - - foreach ($description->getCommands() as $command) { - $commands[] = $this->getCommandData($command); - } - - $data = $describedNamespace - ? array('commands' => $commands, 'namespace' => $describedNamespace) - : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces())); - - $this->writeData($data, $options); - } - - /** - * Writes data as json. - * - * @param array $data - * @param array $options - * - * @return array|string - */ - private function writeData(array $data, array $options) - { - $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0)); - } - - /** - * @param InputArgument $argument - * - * @return array - */ - private function getInputArgumentData(InputArgument $argument) - { - return array( - 'name' => $argument->getName(), - 'is_required' => $argument->isRequired(), - 'is_array' => $argument->isArray(), - 'description' => $argument->getDescription(), - 'default' => $argument->getDefault(), - ); - } - - /** - * @param InputOption $option - * - * @return array - */ - private function getInputOptionData(InputOption $option) - { - return array( - 'name' => '--'.$option->getName(), - 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '', - 'accept_value' => $option->acceptValue(), - 'is_value_required' => $option->isValueRequired(), - 'is_multiple' => $option->isArray(), - 'description' => $option->getDescription(), - 'default' => $option->getDefault(), - ); - } - - /** - * @param InputDefinition $definition - * - * @return array - */ - private function getInputDefinitionData(InputDefinition $definition) - { - $inputArguments = array(); - foreach ($definition->getArguments() as $name => $argument) { - $inputArguments[$name] = $this->getInputArgumentData($argument); - } - - $inputOptions = array(); - foreach ($definition->getOptions() as $name => $option) { - $inputOptions[$name] = $this->getInputOptionData($option); - } - - return array('arguments' => $inputArguments, 'options' => $inputOptions); - } - - /** - * @param Command $command - * - * @return array - */ - private function getCommandData(Command $command) - { - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - return array( - 'name' => $command->getName(), - 'usage' => $command->getSynopsis(), - 'description' => $command->getDescription(), - 'help' => $command->getProcessedHelp(), - 'aliases' => $command->getAliases(), - 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()), - ); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Descriptor interface. - * - * @author Jean-François Simon - */ -interface DescriptorInterface -{ - /** - * Describes an InputArgument instance. - * - * @param OutputInterface $output - * @param object $object - * @param array $options - */ - public function describe(OutputInterface $output, $object, array $options = array()); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Allows to manipulate the exit code of a command after its execution. - * - * @author Francesco Levorato - */ -class ConsoleTerminateEvent extends ConsoleEvent -{ - /** - * The exit code of the command. - * - * @var integer - */ - private $exitCode; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode) - { - parent::__construct($command, $input, $output); - - $this->setExitCode($exitCode); - } - - /** - * Sets the exit code. - * - * @param integer $exitCode The command exit code - */ - public function setExitCode($exitCode) - { - $this->exitCode = (int) $exitCode; - } - - /** - * Gets the exit code. - * - * @return integer The command exit code - */ - public function getExitCode() - { - return $this->exitCode; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\EventDispatcher\Event; - -/** - * Allows to inspect input and output of a command. - * - * @author Francesco Levorato - */ -class ConsoleEvent extends Event -{ - protected $command; - - private $input; - private $output; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output) - { - $this->command = $command; - $this->input = $input; - $this->output = $output; - } - - /** - * Gets the command that is executed. - * - * @return Command A Command instance - */ - public function getCommand() - { - return $this->command; - } - - /** - * Gets the input instance. - * - * @return InputInterface An InputInterface instance - */ - public function getInput() - { - return $this->input; - } - - /** - * Gets the output instance. - * - * @return OutputInterface An OutputInterface instance - */ - public function getOutput() - { - return $this->output; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -/** - * Allows to do things before the command is executed. - * - * @author Fabien Potencier - */ -class ConsoleCommandEvent extends ConsoleEvent -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Allows to handle exception thrown in a command. - * - * @author Fabien Potencier - */ -class ConsoleExceptionEvent extends ConsoleEvent -{ - private $exception; - private $exitCode; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode) - { - parent::__construct($command, $input, $output); - - $this->setException($exception); - $this->exitCode = (int) $exitCode; - } - - /** - * Returns the thrown exception. - * - * @return \Exception The thrown exception - */ - public function getException() - { - return $this->exception; - } - - /** - * Replaces the thrown exception. - * - * This exception will be thrown if no response is set in the event. - * - * @param \Exception $exception The thrown exception - */ - public function setException(\Exception $exception) - { - $this->exception = $exception; - } - - /** - * Gets the exit code. - * - * @return integer The command exit code - */ - public function getExitCode() - { - return $this->exitCode; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * ArrayInput represents an input provided as an array. - * - * Usage: - * - * $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar')); - * - * @author Fabien Potencier - * - * @api - */ -class ArrayInput extends Input -{ - private $parameters; - - /** - * Constructor. - * - * @param array $parameters An array of parameters - * @param InputDefinition $definition A InputDefinition instance - * - * @api - */ - public function __construct(array $parameters, InputDefinition $definition = null) - { - $this->parameters = $parameters; - - parent::__construct($definition); - } - - /** - * Returns the first argument from the raw parameters (not parsed). - * - * @return string The value of the first argument or null otherwise - */ - public function getFirstArgument() - { - foreach ($this->parameters as $key => $value) { - if ($key && '-' === $key[0]) { - continue; - } - - return $value; - } - } - - /** - * Returns true if the raw parameters (not parsed) contain a value. - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The values to look for in the raw parameters (can be an array) - * - * @return Boolean true if the value is contained in the raw parameters - */ - public function hasParameterOption($values) - { - $values = (array) $values; - - foreach ($this->parameters as $k => $v) { - if (!is_int($k)) { - $v = $k; - } - - if (in_array($v, $values)) { - return true; - } - } - - return false; - } - - /** - * Returns the value of a raw option (not parsed). - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param mixed $default The default value to return if no result is found - * - * @return mixed The option value - */ - public function getParameterOption($values, $default = false) - { - $values = (array) $values; - - foreach ($this->parameters as $k => $v) { - if (is_int($k) && in_array($v, $values)) { - return true; - } elseif (in_array($k, $values)) { - return $v; - } - } - - return $default; - } - - /** - * Returns a stringified representation of the args passed to the command - * - * @return string - */ - public function __toString() - { - $params = array(); - foreach ($this->parameters as $param => $val) { - if ($param && '-' === $param[0]) { - $params[] = $param . ('' != $val ? '='.$this->escapeToken($val) : ''); - } else { - $params[] = $this->escapeToken($val); - } - } - - return implode(' ', $params); - } - - /** - * Processes command line arguments. - */ - protected function parse() - { - foreach ($this->parameters as $key => $value) { - if (0 === strpos($key, '--')) { - $this->addLongOption(substr($key, 2), $value); - } elseif ('-' === $key[0]) { - $this->addShortOption(substr($key, 1), $value); - } else { - $this->addArgument($key, $value); - } - } - } - - /** - * Adds a short option value. - * - * @param string $shortcut The short option key - * @param mixed $value The value for the option - * - * @throws \InvalidArgumentException When option given doesn't exist - */ - private function addShortOption($shortcut, $value) - { - if (!$this->definition->hasShortcut($shortcut)) { - throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); - } - - /** - * Adds a long option value. - * - * @param string $name The long option key - * @param mixed $value The value for the option - * - * @throws \InvalidArgumentException When option given doesn't exist - * @throws \InvalidArgumentException When a required value is missing - */ - private function addLongOption($name, $value) - { - if (!$this->definition->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); - } - - $option = $this->definition->getOption($name); - - if (null === $value) { - if ($option->isValueRequired()) { - throw new \InvalidArgumentException(sprintf('The "--%s" option requires a value.', $name)); - } - - $value = $option->isValueOptional() ? $option->getDefault() : true; - } - - $this->options[$name] = $value; - } - - /** - * Adds an argument value. - * - * @param string $name The argument name - * @param mixed $value The value for the argument - * - * @throws \InvalidArgumentException When argument given doesn't exist - */ - private function addArgument($name, $value) - { - if (!$this->definition->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $this->arguments[$name] = $value; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * StringInput represents an input provided as a string. - * - * Usage: - * - * $input = new StringInput('foo --bar="foobar"'); - * - * @author Fabien Potencier - * - * @api - */ -class StringInput extends ArgvInput -{ - const REGEX_STRING = '([^\s]+?)(?:\s|(?setTokens($this->tokenize($input)); - - if (null !== $definition) { - $this->bind($definition); - } - } - - /** - * Tokenizes a string. - * - * @param string $input The input to tokenize - * - * @return array An array of tokens - * - * @throws \InvalidArgumentException When unable to parse input (should never happen) - */ - private function tokenize($input) - { - $tokens = array(); - $length = strlen($input); - $cursor = 0; - while ($cursor < $length) { - if (preg_match('/\s+/A', $input, $match, null, $cursor)) { - } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) { - $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2))); - } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) { - $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2)); - } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) { - $tokens[] = stripcslashes($match[1]); - } else { - // should never happen - // @codeCoverageIgnoreStart - throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10))); - // @codeCoverageIgnoreEnd - } - - $cursor += strlen($match[0]); - } - - return $tokens; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -if (!defined('JSON_UNESCAPED_UNICODE')) { - define('JSON_UNESCAPED_SLASHES', 64); - define('JSON_UNESCAPED_UNICODE', 256); -} - -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Output\BufferedOutput; - -/** - * A InputDefinition represents a set of valid command line arguments and options. - * - * Usage: - * - * $definition = new InputDefinition(array( - * new InputArgument('name', InputArgument::REQUIRED), - * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED), - * )); - * - * @author Fabien Potencier - * - * @api - */ -class InputDefinition -{ - private $arguments; - private $requiredCount; - private $hasAnArrayArgument = false; - private $hasOptional; - private $options; - private $shortcuts; - - /** - * Constructor. - * - * @param array $definition An array of InputArgument and InputOption instance - * - * @api - */ - public function __construct(array $definition = array()) - { - $this->setDefinition($definition); - } - - /** - * Sets the definition of the input. - * - * @param array $definition The definition array - * - * @api - */ - public function setDefinition(array $definition) - { - $arguments = array(); - $options = array(); - foreach ($definition as $item) { - if ($item instanceof InputOption) { - $options[] = $item; - } else { - $arguments[] = $item; - } - } - - $this->setArguments($arguments); - $this->setOptions($options); - } - - /** - * Sets the InputArgument objects. - * - * @param InputArgument[] $arguments An array of InputArgument objects - * - * @api - */ - public function setArguments($arguments = array()) - { - $this->arguments = array(); - $this->requiredCount = 0; - $this->hasOptional = false; - $this->hasAnArrayArgument = false; - $this->addArguments($arguments); - } - - /** - * Adds an array of InputArgument objects. - * - * @param InputArgument[] $arguments An array of InputArgument objects - * - * @api - */ - public function addArguments($arguments = array()) - { - if (null !== $arguments) { - foreach ($arguments as $argument) { - $this->addArgument($argument); - } - } - } - - /** - * Adds an InputArgument object. - * - * @param InputArgument $argument An InputArgument object - * - * @throws \LogicException When incorrect argument is given - * - * @api - */ - public function addArgument(InputArgument $argument) - { - if (isset($this->arguments[$argument->getName()])) { - throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); - } - - if ($this->hasAnArrayArgument) { - throw new \LogicException('Cannot add an argument after an array argument.'); - } - - if ($argument->isRequired() && $this->hasOptional) { - throw new \LogicException('Cannot add a required argument after an optional one.'); - } - - if ($argument->isArray()) { - $this->hasAnArrayArgument = true; - } - - if ($argument->isRequired()) { - ++$this->requiredCount; - } else { - $this->hasOptional = true; - } - - $this->arguments[$argument->getName()] = $argument; - } - - /** - * Returns an InputArgument by name or by position. - * - * @param string|integer $name The InputArgument name or position - * - * @return InputArgument An InputArgument object - * - * @throws \InvalidArgumentException When argument given doesn't exist - * - * @api - */ - public function getArgument($name) - { - if (!$this->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; - - return $arguments[$name]; - } - - /** - * Returns true if an InputArgument object exists by name or position. - * - * @param string|integer $name The InputArgument name or position - * - * @return Boolean true if the InputArgument object exists, false otherwise - * - * @api - */ - public function hasArgument($name) - { - $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; - - return isset($arguments[$name]); - } - - /** - * Gets the array of InputArgument objects. - * - * @return InputArgument[] An array of InputArgument objects - * - * @api - */ - public function getArguments() - { - return $this->arguments; - } - - /** - * Returns the number of InputArguments. - * - * @return integer The number of InputArguments - */ - public function getArgumentCount() - { - return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments); - } - - /** - * Returns the number of required InputArguments. - * - * @return integer The number of required InputArguments - */ - public function getArgumentRequiredCount() - { - return $this->requiredCount; - } - - /** - * Gets the default values. - * - * @return array An array of default values - */ - public function getArgumentDefaults() - { - $values = array(); - foreach ($this->arguments as $argument) { - $values[$argument->getName()] = $argument->getDefault(); - } - - return $values; - } - - /** - * Sets the InputOption objects. - * - * @param InputOption[] $options An array of InputOption objects - * - * @api - */ - public function setOptions($options = array()) - { - $this->options = array(); - $this->shortcuts = array(); - $this->addOptions($options); - } - - /** - * Adds an array of InputOption objects. - * - * @param InputOption[] $options An array of InputOption objects - * - * @api - */ - public function addOptions($options = array()) - { - foreach ($options as $option) { - $this->addOption($option); - } - } - - /** - * Adds an InputOption object. - * - * @param InputOption $option An InputOption object - * - * @throws \LogicException When option given already exist - * - * @api - */ - public function addOption(InputOption $option) - { - if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { - throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName())); - } - - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { - throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); - } - } - } - - $this->options[$option->getName()] = $option; - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - $this->shortcuts[$shortcut] = $option->getName(); - } - } - } - - /** - * Returns an InputOption by name. - * - * @param string $name The InputOption name - * - * @return InputOption A InputOption object - * - * @throws \InvalidArgumentException When option given doesn't exist - * - * @api - */ - public function getOption($name) - { - if (!$this->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); - } - - return $this->options[$name]; - } - - /** - * Returns true if an InputOption object exists by name. - * - * @param string $name The InputOption name - * - * @return Boolean true if the InputOption object exists, false otherwise - * - * @api - */ - public function hasOption($name) - { - return isset($this->options[$name]); - } - - /** - * Gets the array of InputOption objects. - * - * @return InputOption[] An array of InputOption objects - * - * @api - */ - public function getOptions() - { - return $this->options; - } - - /** - * Returns true if an InputOption object exists by shortcut. - * - * @param string $name The InputOption shortcut - * - * @return Boolean true if the InputOption object exists, false otherwise - */ - public function hasShortcut($name) - { - return isset($this->shortcuts[$name]); - } - - /** - * Gets an InputOption by shortcut. - * - * @param string $shortcut the Shortcut name - * - * @return InputOption An InputOption object - */ - public function getOptionForShortcut($shortcut) - { - return $this->getOption($this->shortcutToName($shortcut)); - } - - /** - * Gets an array of default values. - * - * @return array An array of all default values - */ - public function getOptionDefaults() - { - $values = array(); - foreach ($this->options as $option) { - $values[$option->getName()] = $option->getDefault(); - } - - return $values; - } - - /** - * Returns the InputOption name given a shortcut. - * - * @param string $shortcut The shortcut - * - * @return string The InputOption name - * - * @throws \InvalidArgumentException When option given does not exist - */ - private function shortcutToName($shortcut) - { - if (!isset($this->shortcuts[$shortcut])) { - throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - return $this->shortcuts[$shortcut]; - } - - /** - * Gets the synopsis. - * - * @return string The synopsis - */ - public function getSynopsis() - { - $elements = array(); - foreach ($this->getOptions() as $option) { - $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; - $elements[] = sprintf('['.($option->isValueRequired() ? '%s--%s="..."' : ($option->isValueOptional() ? '%s--%s[="..."]' : '%s--%s')).']', $shortcut, $option->getName()); - } - - foreach ($this->getArguments() as $argument) { - $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : '')); - - if ($argument->isArray()) { - $elements[] = sprintf('... [%sN]', $argument->getName()); - } - } - - return implode(' ', $elements); - } - - /** - * Returns a textual representation of the InputDefinition. - * - * @return string A string representing the InputDefinition - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asText() - { - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); - $descriptor->describe($output, $this, array('raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the InputDefinition. - * - * @param Boolean $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the InputDefinition - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($asDom = false) - { - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getInputDefinitionDocument($this); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this); - - return $output->fetch(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * InputInterface is the interface implemented by all input classes. - * - * @author Fabien Potencier - */ -interface InputInterface -{ - /** - * Returns the first argument from the raw parameters (not parsed). - * - * @return string The value of the first argument or null otherwise - */ - public function getFirstArgument(); - - /** - * Returns true if the raw parameters (not parsed) contain a value. - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The values to look for in the raw parameters (can be an array) - * - * @return Boolean true if the value is contained in the raw parameters - */ - public function hasParameterOption($values); - - /** - * Returns the value of a raw option (not parsed). - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param mixed $default The default value to return if no result is found - * - * @return mixed The option value - */ - public function getParameterOption($values, $default = false); - - /** - * Binds the current Input instance with the given arguments and options. - * - * @param InputDefinition $definition A InputDefinition instance - */ - public function bind(InputDefinition $definition); - - /** - * Validates if arguments given are correct. - * - * Throws an exception when not enough arguments are given. - * - * @throws \RuntimeException - */ - public function validate(); - - /** - * Returns all the given arguments merged with the default values. - * - * @return array - */ - public function getArguments(); - - /** - * Gets argument by name. - * - * @param string $name The name of the argument - * - * @return mixed - */ - public function getArgument($name); - - /** - * Sets an argument value by name. - * - * @param string $name The argument name - * @param string $value The argument value - * - * @throws \InvalidArgumentException When argument given doesn't exist - */ - public function setArgument($name, $value); - - /** - * Returns true if an InputArgument object exists by name or position. - * - * @param string|integer $name The InputArgument name or position - * - * @return Boolean true if the InputArgument object exists, false otherwise - */ - public function hasArgument($name); - - /** - * Returns all the given options merged with the default values. - * - * @return array - */ - public function getOptions(); - - /** - * Gets an option by name. - * - * @param string $name The name of the option - * - * @return mixed - */ - public function getOption($name); - - /** - * Sets an option value by name. - * - * @param string $name The option name - * @param string|boolean $value The option value - * - * @throws \InvalidArgumentException When option given doesn't exist - */ - public function setOption($name, $value); - - /** - * Returns true if an InputOption object exists by name. - * - * @param string $name The InputOption name - * - * @return Boolean true if the InputOption object exists, false otherwise - */ - public function hasOption($name); - - /** - * Is this input means interactive? - * - * @return Boolean - */ - public function isInteractive(); - - /** - * Sets the input interactivity. - * - * @param Boolean $interactive If the input should be interactive - */ - public function setInteractive($interactive); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * Represents a command line argument. - * - * @author Fabien Potencier - * - * @api - */ -class InputArgument -{ - const REQUIRED = 1; - const OPTIONAL = 2; - const IS_ARRAY = 4; - - private $name; - private $mode; - private $default; - private $description; - - /** - * Constructor. - * - * @param string $name The argument name - * @param integer $mode The argument mode: self::REQUIRED or self::OPTIONAL - * @param string $description A description text - * @param mixed $default The default value (for self::OPTIONAL mode only) - * - * @throws \InvalidArgumentException When argument mode is not valid - * - * @api - */ - public function __construct($name, $mode = null, $description = '', $default = null) - { - if (null === $mode) { - $mode = self::OPTIONAL; - } elseif (!is_int($mode) || $mode > 7 || $mode < 1) { - throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->mode = $mode; - $this->description = $description; - - $this->setDefault($default); - } - - /** - * Returns the argument name. - * - * @return string The argument name - */ - public function getName() - { - return $this->name; - } - - /** - * Returns true if the argument is required. - * - * @return Boolean true if parameter mode is self::REQUIRED, false otherwise - */ - public function isRequired() - { - return self::REQUIRED === (self::REQUIRED & $this->mode); - } - - /** - * Returns true if the argument can take multiple values. - * - * @return Boolean true if mode is self::IS_ARRAY, false otherwise - */ - public function isArray() - { - return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); - } - - /** - * Sets the default value. - * - * @param mixed $default The default value - * - * @throws \LogicException When incorrect default value is given - */ - public function setDefault($default = null) - { - if (self::REQUIRED === $this->mode && null !== $default) { - throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = array(); - } elseif (!is_array($default)) { - throw new \LogicException('A default value for an array argument must be an array.'); - } - } - - $this->default = $default; - } - - /** - * Returns the default value. - * - * @return mixed The default value - */ - public function getDefault() - { - return $this->default; - } - - /** - * Returns the description text. - * - * @return string The description text - */ - public function getDescription() - { - return $this->description; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * InputAwareInterface should be implemented by classes that depends on the - * Console Input. - * - * @author Wouter J - */ -interface InputAwareInterface -{ - /** - * Sets the Console Input. - * - * @param InputInterface - */ - public function setInput(InputInterface $input); -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * Represents a command line option. - * - * @author Fabien Potencier - * - * @api - */ -class InputOption -{ - const VALUE_NONE = 1; - const VALUE_REQUIRED = 2; - const VALUE_OPTIONAL = 4; - const VALUE_IS_ARRAY = 8; - - private $name; - private $shortcut; - private $mode; - private $default; - private $description; - - /** - * Constructor. - * - * @param string $name The option name - * @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param integer $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param mixed $default The default value (must be null for self::VALUE_REQUIRED or self::VALUE_NONE) - * - * @throws \InvalidArgumentException If option mode is invalid or incompatible - * - * @api - */ - public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null) - { - if (0 === strpos($name, '--')) { - $name = substr($name, 2); - } - - if (empty($name)) { - throw new \InvalidArgumentException('An option name cannot be empty.'); - } - - if (empty($shortcut)) { - $shortcut = null; - } - - if (null !== $shortcut) { - if (is_array($shortcut)) { - $shortcut = implode('|', $shortcut); - } - $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); - $shortcuts = array_filter($shortcuts); - $shortcut = implode('|', $shortcuts); - - if (empty($shortcut)) { - throw new \InvalidArgumentException('An option shortcut cannot be empty.'); - } - } - - if (null === $mode) { - $mode = self::VALUE_NONE; - } elseif (!is_int($mode) || $mode > 15 || $mode < 1) { - throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->shortcut = $shortcut; - $this->mode = $mode; - $this->description = $description; - - if ($this->isArray() && !$this->acceptValue()) { - throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); - } - - $this->setDefault($default); - } - - /** - * Returns the option shortcut. - * - * @return string The shortcut - */ - public function getShortcut() - { - return $this->shortcut; - } - - /** - * Returns the option name. - * - * @return string The name - */ - public function getName() - { - return $this->name; - } - - /** - * Returns true if the option accepts a value. - * - * @return Boolean true if value mode is not self::VALUE_NONE, false otherwise - */ - public function acceptValue() - { - return $this->isValueRequired() || $this->isValueOptional(); - } - - /** - * Returns true if the option requires a value. - * - * @return Boolean true if value mode is self::VALUE_REQUIRED, false otherwise - */ - public function isValueRequired() - { - return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); - } - - /** - * Returns true if the option takes an optional value. - * - * @return Boolean true if value mode is self::VALUE_OPTIONAL, false otherwise - */ - public function isValueOptional() - { - return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); - } - - /** - * Returns true if the option can take multiple values. - * - * @return Boolean true if mode is self::VALUE_IS_ARRAY, false otherwise - */ - public function isArray() - { - return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); - } - - /** - * Sets the default value. - * - * @param mixed $default The default value - * - * @throws \LogicException When incorrect default value is given - */ - public function setDefault($default = null) - { - if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { - throw new \LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = array(); - } elseif (!is_array($default)) { - throw new \LogicException('A default value for an array option must be an array.'); - } - } - - $this->default = $this->acceptValue() ? $default : false; - } - - /** - * Returns the default value. - * - * @return mixed The default value - */ - public function getDefault() - { - return $this->default; - } - - /** - * Returns the description text. - * - * @return string The description text - */ - public function getDescription() - { - return $this->description; - } - - /** - * Checks whether the given option equals this one - * - * @param InputOption $option option to compare - * @return Boolean - */ - public function equals(InputOption $option) - { - return $option->getName() === $this->getName() - && $option->getShortcut() === $this->getShortcut() - && $option->getDefault() === $this->getDefault() - && $option->isArray() === $this->isArray() - && $option->isValueRequired() === $this->isValueRequired() - && $option->isValueOptional() === $this->isValueOptional() - ; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * Input is the base class for all concrete Input classes. - * - * Three concrete classes are provided by default: - * - * * `ArgvInput`: The input comes from the CLI arguments (argv) - * * `StringInput`: The input is provided as a string - * * `ArrayInput`: The input is provided as an array - * - * @author Fabien Potencier - */ -abstract class Input implements InputInterface -{ - /** - * @var InputDefinition - */ - protected $definition; - protected $options = array(); - protected $arguments = array(); - protected $interactive = true; - - /** - * Constructor. - * - * @param InputDefinition $definition A InputDefinition instance - */ - public function __construct(InputDefinition $definition = null) - { - if (null === $definition) { - $this->definition = new InputDefinition(); - } else { - $this->bind($definition); - $this->validate(); - } - } - - /** - * Binds the current Input instance with the given arguments and options. - * - * @param InputDefinition $definition A InputDefinition instance - */ - public function bind(InputDefinition $definition) - { - $this->arguments = array(); - $this->options = array(); - $this->definition = $definition; - - $this->parse(); - } - - /** - * Processes command line arguments. - */ - abstract protected function parse(); - - /** - * Validates the input. - * - * @throws \RuntimeException When not enough arguments are given - */ - public function validate() - { - if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) { - throw new \RuntimeException('Not enough arguments.'); - } - } - - /** - * Checks if the input is interactive. - * - * @return Boolean Returns true if the input is interactive - */ - public function isInteractive() - { - return $this->interactive; - } - - /** - * Sets the input interactivity. - * - * @param Boolean $interactive If the input should be interactive - */ - public function setInteractive($interactive) - { - $this->interactive = (Boolean) $interactive; - } - - /** - * Returns the argument values. - * - * @return array An array of argument values - */ - public function getArguments() - { - return array_merge($this->definition->getArgumentDefaults(), $this->arguments); - } - - /** - * Returns the argument value for a given argument name. - * - * @param string $name The argument name - * - * @return mixed The argument value - * - * @throws \InvalidArgumentException When argument given doesn't exist - */ - public function getArgument($name) - { - if (!$this->definition->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault(); - } - - /** - * Sets an argument value by name. - * - * @param string $name The argument name - * @param string $value The argument value - * - * @throws \InvalidArgumentException When argument given doesn't exist - */ - public function setArgument($name, $value) - { - if (!$this->definition->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $this->arguments[$name] = $value; - } - - /** - * Returns true if an InputArgument object exists by name or position. - * - * @param string|integer $name The InputArgument name or position - * - * @return Boolean true if the InputArgument object exists, false otherwise - */ - public function hasArgument($name) - { - return $this->definition->hasArgument($name); - } - - /** - * Returns the options values. - * - * @return array An array of option values - */ - public function getOptions() - { - return array_merge($this->definition->getOptionDefaults(), $this->options); - } - - /** - * Returns the option value for a given option name. - * - * @param string $name The option name - * - * @return mixed The option value - * - * @throws \InvalidArgumentException When option given doesn't exist - */ - public function getOption($name) - { - if (!$this->definition->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); - } - - /** - * Sets an option value by name. - * - * @param string $name The option name - * @param string|boolean $value The option value - * - * @throws \InvalidArgumentException When option given doesn't exist - */ - public function setOption($name, $value) - { - if (!$this->definition->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - $this->options[$name] = $value; - } - - /** - * Returns true if an InputOption object exists by name. - * - * @param string $name The InputOption name - * - * @return Boolean true if the InputOption object exists, false otherwise - */ - public function hasOption($name) - { - return $this->definition->hasOption($name); - } - - /** - * Escapes a token through escapeshellarg if it contains unsafe chars - * - * @param string $token - * - * @return string - */ - public function escapeToken($token) - { - return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * ArgvInput represents an input coming from the CLI arguments. - * - * Usage: - * - * $input = new ArgvInput(); - * - * By default, the `$_SERVER['argv']` array is used for the input values. - * - * This can be overridden by explicitly passing the input values in the constructor: - * - * $input = new ArgvInput($_SERVER['argv']); - * - * If you pass it yourself, don't forget that the first element of the array - * is the name of the running application. - * - * When passing an argument to the constructor, be sure that it respects - * the same rules as the argv one. It's almost always better to use the - * `StringInput` when you want to provide your own input. - * - * @author Fabien Potencier - * - * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html - * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02 - * - * @api - */ -class ArgvInput extends Input -{ - private $tokens; - private $parsed; - - /** - * Constructor. - * - * @param array $argv An array of parameters from the CLI (in the argv format) - * @param InputDefinition $definition A InputDefinition instance - * - * @api - */ - public function __construct(array $argv = null, InputDefinition $definition = null) - { - if (null === $argv) { - $argv = $_SERVER['argv']; - } - - // strip the application name - array_shift($argv); - - $this->tokens = $argv; - - parent::__construct($definition); - } - - protected function setTokens(array $tokens) - { - $this->tokens = $tokens; - } - - /** - * Processes command line arguments. - */ - protected function parse() - { - $parseOptions = true; - $this->parsed = $this->tokens; - while (null !== $token = array_shift($this->parsed)) { - if ($parseOptions && '' == $token) { - $this->parseArgument($token); - } elseif ($parseOptions && '--' == $token) { - $parseOptions = false; - } elseif ($parseOptions && 0 === strpos($token, '--')) { - $this->parseLongOption($token); - } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { - $this->parseShortOption($token); - } else { - $this->parseArgument($token); - } - } - } - - /** - * Parses a short option. - * - * @param string $token The current token. - */ - private function parseShortOption($token) - { - $name = substr($token, 1); - - if (strlen($name) > 1) { - if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { - // an option with a value (with no space) - $this->addShortOption($name[0], substr($name, 1)); - } else { - $this->parseShortOptionSet($name); - } - } else { - $this->addShortOption($name, null); - } - } - - /** - * Parses a short option set. - * - * @param string $name The current token - * - * @throws \RuntimeException When option given doesn't exist - */ - private function parseShortOptionSet($name) - { - $len = strlen($name); - for ($i = 0; $i < $len; $i++) { - if (!$this->definition->hasShortcut($name[$i])) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i])); - } - - $option = $this->definition->getOptionForShortcut($name[$i]); - if ($option->acceptValue()) { - $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); - - break; - } else { - $this->addLongOption($option->getName(), null); - } - } - } - - /** - * Parses a long option. - * - * @param string $token The current token - */ - private function parseLongOption($token) - { - $name = substr($token, 2); - - if (false !== $pos = strpos($name, '=')) { - $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1)); - } else { - $this->addLongOption($name, null); - } - } - - /** - * Parses an argument. - * - * @param string $token The current token - * - * @throws \RuntimeException When too many arguments are given - */ - private function parseArgument($token) - { - $c = count($this->arguments); - - // if input is expecting another argument, add it - if ($this->definition->hasArgument($c)) { - $arg = $this->definition->getArgument($c); - $this->arguments[$arg->getName()] = $arg->isArray()? array($token) : $token; - - // if last argument isArray(), append token to last argument - } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { - $arg = $this->definition->getArgument($c - 1); - $this->arguments[$arg->getName()][] = $token; - - // unexpected argument - } else { - throw new \RuntimeException('Too many arguments.'); - } - } - - /** - * Adds a short option value. - * - * @param string $shortcut The short option key - * @param mixed $value The value for the option - * - * @throws \RuntimeException When option given doesn't exist - */ - private function addShortOption($shortcut, $value) - { - if (!$this->definition->hasShortcut($shortcut)) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); - } - - /** - * Adds a long option value. - * - * @param string $name The long option key - * @param mixed $value The value for the option - * - * @throws \RuntimeException When option given doesn't exist - */ - private function addLongOption($name, $value) - { - if (!$this->definition->hasOption($name)) { - throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name)); - } - - $option = $this->definition->getOption($name); - - // Convert false values (from a previous call to substr()) to null - if (false === $value) { - $value = null; - } - - if (null !== $value && !$option->acceptValue()) { - throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value)); - } - - if (null === $value && $option->acceptValue() && count($this->parsed)) { - // if option accepts an optional or mandatory argument - // let's see if there is one provided - $next = array_shift($this->parsed); - if (isset($next[0]) && '-' !== $next[0]) { - $value = $next; - } elseif (empty($next)) { - $value = ''; - } else { - array_unshift($this->parsed, $next); - } - } - - if (null === $value) { - if ($option->isValueRequired()) { - throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); - } - - if (!$option->isArray()) { - $value = $option->isValueOptional() ? $option->getDefault() : true; - } - } - - if ($option->isArray()) { - $this->options[$name][] = $value; - } else { - $this->options[$name] = $value; - } - } - - /** - * Returns the first argument from the raw parameters (not parsed). - * - * @return string The value of the first argument or null otherwise - */ - public function getFirstArgument() - { - foreach ($this->tokens as $token) { - if ($token && '-' === $token[0]) { - continue; - } - - return $token; - } - } - - /** - * Returns true if the raw parameters (not parsed) contain a value. - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * - * @return Boolean true if the value is contained in the raw parameters - */ - public function hasParameterOption($values) - { - $values = (array) $values; - - foreach ($this->tokens as $token) { - foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value.'=')) { - return true; - } - } - } - - return false; - } - - /** - * Returns the value of a raw option (not parsed). - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param mixed $default The default value to return if no result is found - * - * @return mixed The option value - */ - public function getParameterOption($values, $default = false) - { - $values = (array) $values; - - $tokens = $this->tokens; - while ($token = array_shift($tokens)) { - foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value.'=')) { - if (false !== $pos = strpos($token, '=')) { - return substr($token, $pos + 1); - } - - return array_shift($tokens); - } - } - } - - return $default; - } - - /** - * Returns a stringified representation of the args passed to the command - * - * @return string - */ - public function __toString() - { - $self = $this; - $tokens = array_map(function ($token) use ($self) { - if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { - return $match[1] . $self->escapeToken($match[2]); - } - - if ($token && $token[0] !== '-') { - return $self->escapeToken($token); - } - - return $token; - }, $this->tokens); - - return implode(' ', $tokens); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Helper\DescriptorHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * HelpCommand displays the help for a given command. - * - * @author Fabien Potencier - */ -class HelpCommand extends Command -{ - private $command; - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->ignoreValidationErrors(); - - $this - ->setName('help') - ->setDefinition(array( - new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), - new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output help in other formats', 'txt'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), - )) - ->setDescription('Displays help for a command') - ->setHelp(<<%command.name% command displays help for a given command: - - php %command.full_name% list - -You can also output the help in other formats by using the --format option: - - php %command.full_name% --format=xml list - -To display the list of available commands, please use the list command. -EOF - ) - ; - } - - /** - * Sets the command - * - * @param Command $command The command to set - */ - public function setCommand(Command $command) - { - $this->command = $command; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if (null === $this->command) { - $this->command = $this->getApplication()->find($input->getArgument('command_name')); - } - - if ($input->getOption('xml')) { - $input->setOption('format', 'xml'); - } - - $helper = new DescriptorHelper(); - $helper->describe($output, $this->command, array( - 'format' => $input->getOption('format'), - 'raw' => $input->getOption('raw'), - )); - - $this->command = null; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\BufferedOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Helper\HelperSet; - -/** - * Base class for all commands. - * - * @author Fabien Potencier - * - * @api - */ -class Command -{ - private $application; - private $name; - private $aliases = array(); - private $definition; - private $help; - private $description; - private $ignoreValidationErrors = false; - private $applicationDefinitionMerged = false; - private $applicationDefinitionMergedWithArgs = false; - private $code; - private $synopsis; - private $helperSet; - - /** - * Constructor. - * - * @param string|null $name The name of the command; passing null means it must be set in configure() - * - * @throws \LogicException When the command name is empty - * - * @api - */ - public function __construct($name = null) - { - $this->definition = new InputDefinition(); - - if (null !== $name) { - $this->setName($name); - } - - $this->configure(); - - if (!$this->name) { - throw new \LogicException('The command name cannot be empty.'); - } - } - - /** - * Ignores validation errors. - * - * This is mainly useful for the help command. - */ - public function ignoreValidationErrors() - { - $this->ignoreValidationErrors = true; - } - - /** - * Sets the application instance for this command. - * - * @param Application $application An Application instance - * - * @api - */ - public function setApplication(Application $application = null) - { - $this->application = $application; - if ($application) { - $this->setHelperSet($application->getHelperSet()); - } else { - $this->helperSet = null; - } - } - - /** - * Sets the helper set. - * - * @param HelperSet $helperSet A HelperSet instance - */ - public function setHelperSet(HelperSet $helperSet) - { - $this->helperSet = $helperSet; - } - - /** - * Gets the helper set. - * - * @return HelperSet A HelperSet instance - */ - public function getHelperSet() - { - return $this->helperSet; - } - - /** - * Gets the application instance for this command. - * - * @return Application An Application instance - * - * @api - */ - public function getApplication() - { - return $this->application; - } - - /** - * Checks whether the command is enabled or not in the current environment - * - * Override this to check for x or y and return false if the command can not - * run properly under the current conditions. - * - * @return Boolean - */ - public function isEnabled() - { - return true; - } - - /** - * Configures the current command. - */ - protected function configure() - { - } - - /** - * Executes the current command. - * - * This method is not abstract because you can use this class - * as a concrete class. In this case, instead of defining the - * execute() method, you set the code to execute by passing - * a Closure to the setCode() method. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - * - * @return null|integer null or 0 if everything went fine, or an error code - * - * @throws \LogicException When this abstract method is not implemented - * @see setCode() - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - throw new \LogicException('You must override the execute() method in the concrete command class.'); - } - - /** - * Interacts with the user. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - */ - protected function interact(InputInterface $input, OutputInterface $output) - { - } - - /** - * Initializes the command just after the input has been validated. - * - * This is mainly useful when a lot of commands extends one main command - * where some things need to be initialized based on the input arguments and options. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - */ - protected function initialize(InputInterface $input, OutputInterface $output) - { - } - - /** - * Runs the command. - * - * The code to execute is either defined directly with the - * setCode() method or by overriding the execute() method - * in a sub-class. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - * - * @return integer The command exit code - * - * @throws \Exception - * - * @see setCode() - * @see execute() - * - * @api - */ - public function run(InputInterface $input, OutputInterface $output) - { - // force the creation of the synopsis before the merge with the app definition - $this->getSynopsis(); - - // add the application arguments and options - $this->mergeApplicationDefinition(); - - // bind the input against the command specific arguments/options - try { - $input->bind($this->definition); - } catch (\Exception $e) { - if (!$this->ignoreValidationErrors) { - throw $e; - } - } - - $this->initialize($input, $output); - - if ($input->isInteractive()) { - $this->interact($input, $output); - } - - $input->validate(); - - if ($this->code) { - $statusCode = call_user_func($this->code, $input, $output); - } else { - $statusCode = $this->execute($input, $output); - } - - return is_numeric($statusCode) ? (int) $statusCode : 0; - } - - /** - * Sets the code to execute when running this command. - * - * If this method is used, it overrides the code defined - * in the execute() method. - * - * @param callable $code A callable(InputInterface $input, OutputInterface $output) - * - * @return Command The current instance - * - * @throws \InvalidArgumentException - * - * @see execute() - * - * @api - */ - public function setCode($code) - { - if (!is_callable($code)) { - throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.'); - } - - $this->code = $code; - - return $this; - } - - /** - * Merges the application definition with the command definition. - * - * This method is not part of public API and should not be used directly. - * - * @param Boolean $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments - */ - public function mergeApplicationDefinition($mergeArgs = true) - { - if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) { - return; - } - - if ($mergeArgs) { - $currentArguments = $this->definition->getArguments(); - $this->definition->setArguments($this->application->getDefinition()->getArguments()); - $this->definition->addArguments($currentArguments); - } - - $this->definition->addOptions($this->application->getDefinition()->getOptions()); - - $this->applicationDefinitionMerged = true; - if ($mergeArgs) { - $this->applicationDefinitionMergedWithArgs = true; - } - } - - /** - * Sets an array of argument and option instances. - * - * @param array|InputDefinition $definition An array of argument and option instances or a definition instance - * - * @return Command The current instance - * - * @api - */ - public function setDefinition($definition) - { - if ($definition instanceof InputDefinition) { - $this->definition = $definition; - } else { - $this->definition->setDefinition($definition); - } - - $this->applicationDefinitionMerged = false; - - return $this; - } - - /** - * Gets the InputDefinition attached to this Command. - * - * @return InputDefinition An InputDefinition instance - * - * @api - */ - public function getDefinition() - { - return $this->definition; - } - - /** - * Gets the InputDefinition to be used to create XML and Text representations of this Command. - * - * Can be overridden to provide the original command representation when it would otherwise - * be changed by merging with the application InputDefinition. - * - * This method is not part of public API and should not be used directly. - * - * @return InputDefinition An InputDefinition instance - */ - public function getNativeDefinition() - { - return $this->getDefinition(); - } - - /** - * Adds an argument. - * - * @param string $name The argument name - * @param integer $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL - * @param string $description A description text - * @param mixed $default The default value (for InputArgument::OPTIONAL mode only) - * - * @return Command The current instance - * - * @api - */ - public function addArgument($name, $mode = null, $description = '', $default = null) - { - $this->definition->addArgument(new InputArgument($name, $mode, $description, $default)); - - return $this; - } - - /** - * Adds an option. - * - * @param string $name The option name - * @param string $shortcut The shortcut (can be null) - * @param integer $mode The option mode: One of the InputOption::VALUE_* constants - * @param string $description A description text - * @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE) - * - * @return Command The current instance - * - * @api - */ - public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) - { - $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default)); - - return $this; - } - - /** - * Sets the name of the command. - * - * This method can set both the namespace and the name if - * you separate them by a colon (:) - * - * $command->setName('foo:bar'); - * - * @param string $name The command name - * - * @return Command The current instance - * - * @throws \InvalidArgumentException When the name is invalid - * - * @api - */ - public function setName($name) - { - $this->validateName($name); - - $this->name = $name; - - return $this; - } - - /** - * Returns the command name. - * - * @return string The command name - * - * @api - */ - public function getName() - { - return $this->name; - } - - /** - * Sets the description for the command. - * - * @param string $description The description for the command - * - * @return Command The current instance - * - * @api - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Returns the description for the command. - * - * @return string The description for the command - * - * @api - */ - public function getDescription() - { - return $this->description; - } - - /** - * Sets the help for the command. - * - * @param string $help The help for the command - * - * @return Command The current instance - * - * @api - */ - public function setHelp($help) - { - $this->help = $help; - - return $this; - } - - /** - * Returns the help for the command. - * - * @return string The help for the command - * - * @api - */ - public function getHelp() - { - return $this->help; - } - - /** - * Returns the processed help for the command replacing the %command.name% and - * %command.full_name% patterns with the real values dynamically. - * - * @return string The processed help for the command - */ - public function getProcessedHelp() - { - $name = $this->name; - - $placeholders = array( - '%command.name%', - '%command.full_name%' - ); - $replacements = array( - $name, - $_SERVER['PHP_SELF'].' '.$name - ); - - return str_replace($placeholders, $replacements, $this->getHelp()); - } - - /** - * Sets the aliases for the command. - * - * @param array $aliases An array of aliases for the command - * - * @return Command The current instance - * - * @throws \InvalidArgumentException When an alias is invalid - * - * @api - */ - public function setAliases($aliases) - { - foreach ($aliases as $alias) { - $this->validateName($alias); - } - - $this->aliases = $aliases; - - return $this; - } - - /** - * Returns the aliases for the command. - * - * @return array An array of aliases for the command - * - * @api - */ - public function getAliases() - { - return $this->aliases; - } - - /** - * Returns the synopsis for the command. - * - * @return string The synopsis - */ - public function getSynopsis() - { - if (null === $this->synopsis) { - $this->synopsis = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis())); - } - - return $this->synopsis; - } - - /** - * Gets a helper instance by name. - * - * @param string $name The helper name - * - * @return mixed The helper value - * - * @throws \InvalidArgumentException if the helper is not defined - * - * @api - */ - public function getHelper($name) - { - return $this->helperSet->get($name); - } - - /** - * Returns a text representation of the command. - * - * @return string A string representing the command - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asText() - { - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); - $descriptor->describe($output, $this, array('raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the command. - * - * @param Boolean $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the command - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($asDom = false) - { - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getCommandDocument($this); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this); - - return $output->fetch(); - } - - /** - * Validates a command name. - * - * It must be non-empty and parts can optionally be separated by ":". - * - * @param string $name - * - * @throws \InvalidArgumentException When the name is invalid - */ - private function validateName($name) - { - if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { - throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Helper\DescriptorHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Input\InputDefinition; - -/** - * ListCommand displays the list of all available commands for the application. - * - * @author Fabien Potencier - */ -class ListCommand extends Command -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('list') - ->setDefinition($this->createDefinition()) - ->setDescription('Lists commands') - ->setHelp(<<%command.name% command lists all commands: - - php %command.full_name% - -You can also display the commands for a specific namespace: - - php %command.full_name% test - -You can also output the information in other formats by using the --format option: - - php %command.full_name% --format=xml - -It's also possible to get raw list of commands (useful for embedding command runner): - - php %command.full_name% --raw -EOF - ) - ; - } - - /** - * {@inheritdoc} - */ - public function getNativeDefinition() - { - return $this->createDefinition(); - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if ($input->getOption('xml')) { - $input->setOption('format', 'xml'); - } - - $helper = new DescriptorHelper(); - $helper->describe($output, $this->getApplication(), array( - 'format' => $input->getOption('format'), - 'raw_text' => $input->getOption('raw'), - 'namespace' => $input->getArgument('namespace'), - )); - } - - /** - * {@inheritdoc} - */ - private function createDefinition() - { - return new InputDefinition(array( - new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), - new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output list in other formats', 'txt'), - )); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputAwareInterface; -use Symfony\Component\Console\Output\BufferedOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Command\HelpCommand; -use Symfony\Component\Console\Command\ListCommand; -use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Helper\FormatterHelper; -use Symfony\Component\Console\Helper\DialogHelper; -use Symfony\Component\Console\Helper\ProgressHelper; -use Symfony\Component\Console\Helper\TableHelper; -use Symfony\Component\Console\Event\ConsoleCommandEvent; -use Symfony\Component\Console\Event\ConsoleExceptionEvent; -use Symfony\Component\Console\Event\ConsoleTerminateEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -/** - * An Application is the container for a collection of commands. - * - * It is the main entry point of a Console application. - * - * This class is optimized for a standard CLI environment. - * - * Usage: - * - * $app = new Application('myapp', '1.0 (stable)'); - * $app->add(new SimpleCommand()); - * $app->run(); - * - * @author Fabien Potencier - * - * @api - */ -class Application -{ - private $commands = array(); - private $wantHelps = false; - private $runningCommand; - private $name; - private $version; - private $catchExceptions = true; - private $autoExit = true; - private $definition; - private $helperSet; - private $dispatcher; - private $terminalDimensions; - - /** - * Constructor. - * - * @param string $name The name of the application - * @param string $version The version of the application - * - * @api - */ - public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') - { - $this->name = $name; - $this->version = $version; - $this->helperSet = $this->getDefaultHelperSet(); - $this->definition = $this->getDefaultInputDefinition(); - - foreach ($this->getDefaultCommands() as $command) { - $this->add($command); - } - } - - public function setDispatcher(EventDispatcherInterface $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - /** - * Runs the current application. - * - * @param InputInterface $input An Input instance - * @param OutputInterface $output An Output instance - * - * @return integer 0 if everything went fine, or an error code - * - * @throws \Exception When doRun returns Exception - * - * @api - */ - public function run(InputInterface $input = null, OutputInterface $output = null) - { - if (null === $input) { - $input = new ArgvInput(); - } - - if (null === $output) { - $output = new ConsoleOutput(); - } - - $this->configureIO($input, $output); - - try { - $exitCode = $this->doRun($input, $output); - } catch (\Exception $e) { - if (!$this->catchExceptions) { - throw $e; - } - - if ($output instanceof ConsoleOutputInterface) { - $this->renderException($e, $output->getErrorOutput()); - } else { - $this->renderException($e, $output); - } - - $exitCode = $e->getCode(); - if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if (0 === $exitCode) { - $exitCode = 1; - } - } else { - $exitCode = 1; - } - } - - if ($this->autoExit) { - if ($exitCode > 255) { - $exitCode = 255; - } - // @codeCoverageIgnoreStart - exit($exitCode); - // @codeCoverageIgnoreEnd - } - - return $exitCode; - } - - /** - * Runs the current application. - * - * @param InputInterface $input An Input instance - * @param OutputInterface $output An Output instance - * - * @return integer 0 if everything went fine, or an error code - */ - public function doRun(InputInterface $input, OutputInterface $output) - { - if (true === $input->hasParameterOption(array('--version', '-V'))) { - $output->writeln($this->getLongVersion()); - - return 0; - } - - $name = $this->getCommandName($input); - if (true === $input->hasParameterOption(array('--help', '-h'))) { - if (!$name) { - $name = 'help'; - $input = new ArrayInput(array('command' => 'help')); - } else { - $this->wantHelps = true; - } - } - - if (!$name) { - $name = 'list'; - $input = new ArrayInput(array('command' => 'list')); - } - - // the command name MUST be the first element of the input - $command = $this->find($name); - - $this->runningCommand = $command; - $exitCode = $this->doRunCommand($command, $input, $output); - $this->runningCommand = null; - - return $exitCode; - } - - /** - * Set a helper set to be used with the command. - * - * @param HelperSet $helperSet The helper set - * - * @api - */ - public function setHelperSet(HelperSet $helperSet) - { - $this->helperSet = $helperSet; - } - - /** - * Get the helper set associated with the command. - * - * @return HelperSet The HelperSet instance associated with this command - * - * @api - */ - public function getHelperSet() - { - return $this->helperSet; - } - - /** - * Set an input definition set to be used with this application - * - * @param InputDefinition $definition The input definition - * - * @api - */ - public function setDefinition(InputDefinition $definition) - { - $this->definition = $definition; - } - - /** - * Gets the InputDefinition related to this Application. - * - * @return InputDefinition The InputDefinition instance - */ - public function getDefinition() - { - return $this->definition; - } - - /** - * Gets the help message. - * - * @return string A help message. - */ - public function getHelp() - { - $messages = array( - $this->getLongVersion(), - '', - 'Usage:', - ' [options] command [arguments]', - '', - 'Options:', - ); - - foreach ($this->getDefinition()->getOptions() as $option) { - $messages[] = sprintf(' %-29s %s %s', - '--'.$option->getName().'', - $option->getShortcut() ? '-'.$option->getShortcut().'' : ' ', - $option->getDescription() - ); - } - - return implode(PHP_EOL, $messages); - } - - /** - * Sets whether to catch exceptions or not during commands execution. - * - * @param Boolean $boolean Whether to catch exceptions or not during commands execution - * - * @api - */ - public function setCatchExceptions($boolean) - { - $this->catchExceptions = (Boolean) $boolean; - } - - /** - * Sets whether to automatically exit after a command execution or not. - * - * @param Boolean $boolean Whether to automatically exit after a command execution or not - * - * @api - */ - public function setAutoExit($boolean) - { - $this->autoExit = (Boolean) $boolean; - } - - /** - * Gets the name of the application. - * - * @return string The application name - * - * @api - */ - public function getName() - { - return $this->name; - } - - /** - * Sets the application name. - * - * @param string $name The application name - * - * @api - */ - public function setName($name) - { - $this->name = $name; - } - - /** - * Gets the application version. - * - * @return string The application version - * - * @api - */ - public function getVersion() - { - return $this->version; - } - - /** - * Sets the application version. - * - * @param string $version The application version - * - * @api - */ - public function setVersion($version) - { - $this->version = $version; - } - - /** - * Returns the long version of the application. - * - * @return string The long application version - * - * @api - */ - public function getLongVersion() - { - if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { - return sprintf('%s version %s', $this->getName(), $this->getVersion()); - } - - return 'Console Tool'; - } - - /** - * Registers a new command. - * - * @param string $name The command name - * - * @return Command The newly created command - * - * @api - */ - public function register($name) - { - return $this->add(new Command($name)); - } - - /** - * Adds an array of command objects. - * - * @param Command[] $commands An array of commands - * - * @api - */ - public function addCommands(array $commands) - { - foreach ($commands as $command) { - $this->add($command); - } - } - - /** - * Adds a command object. - * - * If a command with the same name already exists, it will be overridden. - * - * @param Command $command A Command object - * - * @return Command The registered command - * - * @api - */ - public function add(Command $command) - { - $command->setApplication($this); - - if (!$command->isEnabled()) { - $command->setApplication(null); - - return; - } - - if (null === $command->getDefinition()) { - throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); - } - - $this->commands[$command->getName()] = $command; - - foreach ($command->getAliases() as $alias) { - $this->commands[$alias] = $command; - } - - return $command; - } - - /** - * Returns a registered command by name or alias. - * - * @param string $name The command name or alias - * - * @return Command A Command object - * - * @throws \InvalidArgumentException When command name given does not exist - * - * @api - */ - public function get($name) - { - if (!isset($this->commands[$name])) { - throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); - } - - $command = $this->commands[$name]; - - if ($this->wantHelps) { - $this->wantHelps = false; - - $helpCommand = $this->get('help'); - $helpCommand->setCommand($command); - - return $helpCommand; - } - - return $command; - } - - /** - * Returns true if the command exists, false otherwise. - * - * @param string $name The command name or alias - * - * @return Boolean true if the command exists, false otherwise - * - * @api - */ - public function has($name) - { - return isset($this->commands[$name]); - } - - /** - * Returns an array of all unique namespaces used by currently registered commands. - * - * It does not returns the global namespace which always exists. - * - * @return array An array of namespaces - */ - public function getNamespaces() - { - $namespaces = array(); - foreach ($this->commands as $command) { - $namespaces[] = $this->extractNamespace($command->getName()); - - foreach ($command->getAliases() as $alias) { - $namespaces[] = $this->extractNamespace($alias); - } - } - - return array_values(array_unique(array_filter($namespaces))); - } - - /** - * Finds a registered namespace by a name or an abbreviation. - * - * @param string $namespace A namespace or abbreviation to search for - * - * @return string A registered namespace - * - * @throws \InvalidArgumentException When namespace is incorrect or ambiguous - */ - public function findNamespace($namespace) - { - $allNamespaces = $this->getNamespaces(); - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace); - $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces); - - if (empty($namespaces)) { - $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); - - if ($alternatives = $this->findAlternatives($namespace, $allNamespaces, array())) { - if (1 == count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - - $message .= implode("\n ", $alternatives); - } - - throw new \InvalidArgumentException($message); - } - - $exact = in_array($namespace, $namespaces, true); - if (count($namespaces) > 1 && !$exact) { - throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); - } - - return $exact ? $namespace : reset($namespaces); - } - - /** - * Finds a command by name or alias. - * - * Contrary to get, this command tries to find the best - * match if you give it an abbreviation of a name or alias. - * - * @param string $name A command name or a command alias - * - * @return Command A Command instance - * - * @throws \InvalidArgumentException When command name is incorrect or ambiguous - * - * @api - */ - public function find($name) - { - $allCommands = array_keys($this->commands); - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); - $commands = preg_grep('{^'.$expr.'}', $allCommands); - - if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) { - if (false !== $pos = strrpos($name, ':')) { - // check if a namespace exists and contains commands - $this->findNamespace(substr($name, 0, $pos)); - } - - $message = sprintf('Command "%s" is not defined.', $name); - - if ($alternatives = $this->findAlternatives($name, $allCommands, array())) { - if (1 == count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - $message .= implode("\n ", $alternatives); - } - - throw new \InvalidArgumentException($message); - } - - // filter out aliases for commands which are already on the list - if (count($commands) > 1) { - $commandList = $this->commands; - $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { - $commandName = $commandList[$nameOrAlias]->getName(); - - return $commandName === $nameOrAlias || !in_array($commandName, $commands); - }); - } - - $exact = in_array($name, $commands, true); - if (count($commands) > 1 && !$exact) { - $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); - - throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); - } - - return $this->get($exact ? $name : reset($commands)); - } - - /** - * Gets the commands (registered in the given namespace if provided). - * - * The array keys are the full names and the values the command instances. - * - * @param string $namespace A namespace name - * - * @return Command[] An array of Command instances - * - * @api - */ - public function all($namespace = null) - { - if (null === $namespace) { - return $this->commands; - } - - $commands = array(); - foreach ($this->commands as $name => $command) { - if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) { - $commands[$name] = $command; - } - } - - return $commands; - } - - /** - * Returns an array of possible abbreviations given a set of names. - * - * @param array $names An array of names - * - * @return array An array of abbreviations - */ - public static function getAbbreviations($names) - { - $abbrevs = array(); - foreach ($names as $name) { - for ($len = strlen($name); $len > 0; --$len) { - $abbrev = substr($name, 0, $len); - $abbrevs[$abbrev][] = $name; - } - } - - return $abbrevs; - } - - /** - * Returns a text representation of the Application. - * - * @param string $namespace An optional namespace name - * @param boolean $raw Whether to return raw command list - * - * @return string A string representing the Application - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asText($namespace = null, $raw = false) - { - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw); - $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the Application. - * - * @param string $namespace An optional namespace name - * @param Boolean $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the Application - * - * @deprecated Deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($namespace = null, $asDom = false) - { - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getApplicationDocument($this, $namespace); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this, array('namespace' => $namespace)); - - return $output->fetch(); - } - - /** - * Renders a caught exception. - * - * @param \Exception $e An exception instance - * @param OutputInterface $output An OutputInterface instance - */ - public function renderException($e, $output) - { - $strlen = function ($string) { - if (!function_exists('mb_strlen')) { - return strlen($string); - } - - if (false === $encoding = mb_detect_encoding($string)) { - return strlen($string); - } - - return mb_strlen($string, $encoding); - }; - - do { - $title = sprintf(' [%s] ', get_class($e)); - $len = $strlen($title); - // HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327 - $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : (defined('HHVM_VERSION') ? 1 << 31 : PHP_INT_MAX); - $formatter = $output->getFormatter(); - $lines = array(); - foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { - foreach (str_split($line, $width - 4) as $line) { - // pre-format lines to get the right string length - $lineLength = $strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4; - $lines[] = array($line, $lineLength); - - $len = max($lineLength, $len); - } - } - - $messages = array('', ''); - $messages[] = $emptyLine = $formatter->format(sprintf('%s', str_repeat(' ', $len))); - $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $strlen($title))))); - foreach ($lines as $line) { - $messages[] = $formatter->format(sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1]))); - } - $messages[] = $emptyLine; - $messages[] = ''; - $messages[] = ''; - - $output->writeln($messages, OutputInterface::OUTPUT_RAW); - - if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $output->writeln('Exception trace:'); - - // exception related properties - $trace = $e->getTrace(); - array_unshift($trace, array( - 'function' => '', - 'file' => $e->getFile() != null ? $e->getFile() : 'n/a', - 'line' => $e->getLine() != null ? $e->getLine() : 'n/a', - 'args' => array(), - )); - - for ($i = 0, $count = count($trace); $i < $count; $i++) { - $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; - $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; - $function = $trace[$i]['function']; - $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; - $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; - - $output->writeln(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line)); - } - - $output->writeln(""); - $output->writeln(""); - } - } while ($e = $e->getPrevious()); - - if (null !== $this->runningCommand) { - $output->writeln(sprintf('%s', sprintf($this->runningCommand->getSynopsis(), $this->getName()))); - $output->writeln(""); - $output->writeln(""); - } - } - - /** - * Tries to figure out the terminal width in which this application runs - * - * @return int|null - */ - protected function getTerminalWidth() - { - $dimensions = $this->getTerminalDimensions(); - - return $dimensions[0]; - } - - /** - * Tries to figure out the terminal height in which this application runs - * - * @return int|null - */ - protected function getTerminalHeight() - { - $dimensions = $this->getTerminalDimensions(); - - return $dimensions[1]; - } - - /** - * Tries to figure out the terminal dimensions based on the current environment - * - * @return array Array containing width and height - */ - public function getTerminalDimensions() - { - if ($this->terminalDimensions) { - return $this->terminalDimensions; - } - - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - // extract [w, H] from "wxh (WxH)" - if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) { - return array((int) $matches[1], (int) $matches[2]); - } - // extract [w, h] from "wxh" - if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) { - return array((int) $matches[1], (int) $matches[2]); - } - } - - if ($sttyString = $this->getSttyColumns()) { - // extract [w, h] from "rows h; columns w;" - if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { - return array((int) $matches[2], (int) $matches[1]); - } - // extract [w, h] from "; h rows; w columns" - if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { - return array((int) $matches[2], (int) $matches[1]); - } - } - - return array(null, null); - } - - /** - * Sets terminal dimensions. - * - * Can be useful to force terminal dimensions for functional tests. - * - * @param integer $width The width - * @param integer $height The height - * - * @return Application The current application - */ - public function setTerminalDimensions($width, $height) - { - $this->terminalDimensions = array($width, $height); - - return $this; - } - - /** - * Configures the input and output instances based on the user arguments and options. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - */ - protected function configureIO(InputInterface $input, OutputInterface $output) - { - if (true === $input->hasParameterOption(array('--ansi'))) { - $output->setDecorated(true); - } elseif (true === $input->hasParameterOption(array('--no-ansi'))) { - $output->setDecorated(false); - } - - if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) { - $input->setInteractive(false); - } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('dialog')) { - $inputStream = $this->getHelperSet()->get('dialog')->getInputStream(); - if (!@posix_isatty($inputStream)) { - $input->setInteractive(false); - } - } - - if (true === $input->hasParameterOption(array('--quiet', '-q'))) { - $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); - } else { - if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) { - $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) { - $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); - } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) { - $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); - } - } - } - - /** - * Runs the current command. - * - * If an event dispatcher has been attached to the application, - * events are also dispatched during the life-cycle of the command. - * - * @param Command $command A Command instance - * @param InputInterface $input An Input instance - * @param OutputInterface $output An Output instance - * - * @return integer 0 if everything went fine, or an error code - */ - protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) - { - foreach ($command->getHelperSet() as $helper) { - if ($helper instanceof InputAwareInterface) { - $helper->setInput($input); - } - } - - if (null === $this->dispatcher) { - return $command->run($input, $output); - } - - $event = new ConsoleCommandEvent($command, $input, $output); - $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); - - try { - $exitCode = $command->run($input, $output); - } catch (\Exception $e) { - $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode()); - $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); - - $event = new ConsoleExceptionEvent($command, $input, $output, $e, $event->getExitCode()); - $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); - - throw $event->getException(); - } - - $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); - $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); - - return $event->getExitCode(); - } - - /** - * Gets the name of the command based on input. - * - * @param InputInterface $input The input interface - * - * @return string The command name - */ - protected function getCommandName(InputInterface $input) - { - return $input->getFirstArgument(); - } - - /** - * Gets the default input definition. - * - * @return InputDefinition An InputDefinition instance - */ - protected function getDefaultInputDefinition() - { - return new InputDefinition(array( - new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), - - new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message.'), - new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message.'), - new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), - new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version.'), - new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output.'), - new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output.'), - new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'), - )); - } - - /** - * Gets the default commands that should always be available. - * - * @return Command[] An array of default Command instances - */ - protected function getDefaultCommands() - { - return array(new HelpCommand(), new ListCommand()); - } - - /** - * Gets the default helper set with the helpers that should always be available. - * - * @return HelperSet A HelperSet instance - */ - protected function getDefaultHelperSet() - { - return new HelperSet(array( - new FormatterHelper(), - new DialogHelper(), - new ProgressHelper(), - new TableHelper(), - )); - } - - /** - * Runs and parses stty -a if it's available, suppressing any error output - * - * @return string - */ - private function getSttyColumns() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')); - $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - return $info; - } - } - - /** - * Runs and parses mode CON if it's available, suppressing any error output - * - * @return string x or null if it could not be parsed - */ - private function getConsoleMode() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')); - $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { - return $matches[2].'x'.$matches[1]; - } - } - } - - /** - * Returns abbreviated suggestions in string format. - * - * @param array $abbrevs Abbreviated suggestions to convert - * - * @return string A formatted string of abbreviated suggestions - */ - private function getAbbreviationSuggestions($abbrevs) - { - return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''); - } - - /** - * Returns the namespace part of the command name. - * - * This method is not part of public API and should not be used directly. - * - * @param string $name The full name of the command - * @param string $limit The maximum number of parts of the namespace - * - * @return string The namespace of the command - */ - public function extractNamespace($name, $limit = null) - { - $parts = explode(':', $name); - array_pop($parts); - - return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit)); - } - - /** - * Finds alternative of $name among $collection, - * if nothing is found in $collection, try in $abbrevs - * - * @param string $name The string - * @param array|\Traversable $collection The collection - * - * @return array A sorted array of similar string - */ - private function findAlternatives($name, $collection) - { - $threshold = 1e3; - $alternatives = array(); - - $collectionParts = array(); - foreach ($collection as $item) { - $collectionParts[$item] = explode(':', $item); - } - - foreach (explode(':', $name) as $i => $subname) { - foreach ($collectionParts as $collectionName => $parts) { - $exists = isset($alternatives[$collectionName]); - if (!isset($parts[$i]) && $exists) { - $alternatives[$collectionName] += $threshold; - continue; - } elseif (!isset($parts[$i])) { - continue; - } - - $lev = levenshtein($subname, $parts[$i]); - if ($lev <= strlen($subname) / 3 || false !== strpos($parts[$i], $subname)) { - $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; - } elseif ($exists) { - $alternatives[$collectionName] += $threshold; - } - } - } - - foreach ($collection as $item) { - $lev = levenshtein($name, $item); - if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { - $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; - } - } - - $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2*$threshold; }); - asort($alternatives); - - return array_keys($alternatives); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Input\StringInput; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Process\ProcessBuilder; -use Symfony\Component\Process\PhpExecutableFinder; - -/** - * A Shell wraps an Application to add shell capabilities to it. - * - * Support for history and completion only works with a PHP compiled - * with readline support (either --with-readline or --with-libedit) - * - * @author Fabien Potencier - * @author Martin Hasoň - */ -class Shell -{ - private $application; - private $history; - private $output; - private $hasReadline; - private $processIsolation = false; - - /** - * Constructor. - * - * If there is no readline support for the current PHP executable - * a \RuntimeException exception is thrown. - * - * @param Application $application An application instance - */ - public function __construct(Application $application) - { - $this->hasReadline = function_exists('readline'); - $this->application = $application; - $this->history = getenv('HOME').'/.history_'.$application->getName(); - $this->output = new ConsoleOutput(); - } - - /** - * Runs the shell. - */ - public function run() - { - $this->application->setAutoExit(false); - $this->application->setCatchExceptions(true); - - if ($this->hasReadline) { - readline_read_history($this->history); - readline_completion_function(array($this, 'autocompleter')); - } - - $this->output->writeln($this->getHeader()); - $php = null; - if ($this->processIsolation) { - $finder = new PhpExecutableFinder(); - $php = $finder->find(); - $this->output->writeln(<<Running with process isolation, you should consider this: - * each command is executed as separate process, - * commands don't support interactivity, all params must be passed explicitly, - * commands output is not colorized. - -EOF - ); - } - - while (true) { - $command = $this->readline(); - - if (false === $command) { - $this->output->writeln("\n"); - - break; - } - - if ($this->hasReadline) { - readline_add_history($command); - readline_write_history($this->history); - } - - if ($this->processIsolation) { - $pb = new ProcessBuilder(); - - $process = $pb - ->add($php) - ->add($_SERVER['argv'][0]) - ->add($command) - ->inheritEnvironmentVariables(true) - ->getProcess() - ; - - $output = $this->output; - $process->run(function ($type, $data) use ($output) { - $output->writeln($data); - }); - - $ret = $process->getExitCode(); - } else { - $ret = $this->application->run(new StringInput($command), $this->output); - } - - if (0 !== $ret) { - $this->output->writeln(sprintf('The command terminated with an error status (%s)', $ret)); - } - } - } - - /** - * Returns the shell header. - * - * @return string The header string - */ - protected function getHeader() - { - return <<{$this->application->getName()} shell ({$this->application->getVersion()}). - -At the prompt, type help for some help, -or list to get a list of available commands. - -To exit the shell, type ^D. - -EOF; - } - - /** - * Renders a prompt. - * - * @return string The prompt - */ - protected function getPrompt() - { - // using the formatter here is required when using readline - return $this->output->getFormatter()->format($this->application->getName().' > '); - } - - protected function getOutput() - { - return $this->output; - } - - protected function getApplication() - { - return $this->application; - } - - /** - * Tries to return autocompletion for the current entered text. - * - * @param string $text The last segment of the entered text - * - * @return Boolean|array A list of guessed strings or true - */ - private function autocompleter($text) - { - $info = readline_info(); - $text = substr($info['line_buffer'], 0, $info['end']); - - if ($info['point'] !== $info['end']) { - return true; - } - - // task name? - if (false === strpos($text, ' ') || !$text) { - return array_keys($this->application->all()); - } - - // options and arguments? - try { - $command = $this->application->find(substr($text, 0, strpos($text, ' '))); - } catch (\Exception $e) { - return true; - } - - $list = array('--help'); - foreach ($command->getDefinition()->getOptions() as $option) { - $list[] = '--'.$option->getName(); - } - - return $list; - } - - /** - * Reads a single line from standard input. - * - * @return string The single line from standard input - */ - private function readline() - { - if ($this->hasReadline) { - $line = readline($this->getPrompt()); - } else { - $this->output->write($this->getPrompt()); - $line = fgets(STDIN, 1024); - $line = (!$line && strlen($line) == 0) ? false : rtrim($line); - } - - return $line; - } - - public function getProcessIsolation() - { - return $this->processIsolation; - } - - public function setProcessIsolation($processIsolation) - { - $this->processIsolation = (Boolean) $processIsolation; - - if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) { - throw new \RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.'); - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package phpdcd - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\PHPDCD\Log; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/phpdcd/tree - * @since Class available since Release 1.0.0 - */ -class Text -{ - /** - * Prints a result set from PHPDCD_Detector::detectDeadCode(). - * - * @param Symfony\Component\Console\Output\OutputInterface $output - * @param array $result - */ - public function printResult(OutputInterface $output, array $result) - { - foreach ($result as $name => $source) { - $output->writeln( - sprintf( - " - %s()\n LOC: %d, declared in %s:%d\n", - $name, - $source['loc'], - $source['file'], - $source['line'] - ) - ); - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package phpdcd - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\PHPDCD; - -/** - * PHPDCD code analyser to be used on a body of source code. - * - * Analyses given source code (files) for declared and called functions - * and aggregates this information. - * - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/phpdcd/tree - * @since Class available since Release 1.0.0 - */ -class Analyser -{ - /** - * Function declaration mapping: maps declared function name to file and line number - * TODO: make mapping to file and line number optional for memory usage reduction? - * @var array - */ - private $functionDeclarations = array(); - - /** - * Function call mapping: maps "callees" to array of "callers" - * TODO: make callers array optional for memory usage reduction? - * @var array - */ - private $functionCalls = array(); - - /** - * Class hierarchy data: maps classes to their direct parent. - * @var array - */ - private $classParents = array(); - - - public function getFunctionDeclarations() - { - return $this->functionDeclarations; - } - - /** - * Get function calls we detected - * @return array maps "callees" to array of "callers" - */ - public function getFunctionCalls() - { - // Resolve parent(class) calls if possible - foreach ($this->functionCalls as $call => $callers) { - if (strpos($call, 'parent(') === 0) { - preg_match('/parent\\((.*?)\\)::(.*)/', $call, $matches); - $class = $matches[1]; - $method = $matches[2]; - foreach ($this->getAncestors($class) as $ancestor) { - $resolvedCall = $ancestor . '::' . $method; - if (isset($this->functionDeclarations[$resolvedCall])) { - $this->functionCalls[$resolvedCall] = $callers; - // TODO: also remove unresolved parent(class) entries? - break; - } - } - } - } - - return $this->functionCalls; - } - - /** - * Get array of a class's ancestors. - * @param $child - * @return array of ancestors - */ - public function getAncestors($child) - { - $ancestors = array(); - while (isset($this->classParents[$child])) { - $child = $this->classParents[$child]; - if (in_array($child, $ancestors)) { - $cycle = implode(' -> ', $ancestors) . ' -> ' . $child; - throw new \RuntimeException('Class hierarchy cycle detected: ' . $cycle); - } - $ancestors[] = $child; - } - return $ancestors; - } - - /** - * Build a mapping between parent classes and all their descendants - * @return array maps each parent classes to array of its subclasses, subsubclasses, ... - */ - public function getClassDescendants() - { - $descendants = array(); - foreach ($this->classParents as $child => $parent) { - // Direct child - $descendants[$parent][] = $child; - // Store child for further ancestors - $ancestor = $parent; - while (isset($this->classParents[$ancestor])) { - $ancestor = $this->classParents[$ancestor]; - $descendants[$ancestor][] = $child; - } - } - return $descendants; - } - - /** - * Analyse a PHP source code file for defined and called functions. - * @param $filename - */ - public function analyseFile($filename) - { - $sourceCode = file_get_contents($filename); - return $this->analyseSourceCode($sourceCode, $filename); - } - - /** - * Analyse PHP source code for defined and called functions - * - * @param string $sourceCode source code. - * @param string $filename optional file name to use in declaration definition - */ - public function analyseSourceCode($sourceCode, $filename = 'undefined') - { - - $blocks = array(); - $currentBlock = null; - $currentClass = ''; - $currentFunction = ''; - $currentInterface = ''; - $namespace = ''; - $variables = array(); - - $tokens = new \PHP_Token_Stream($sourceCode); - $count = count($tokens); - - for ($i = 0; $i < $count; $i++) { - if ($tokens[$i] instanceof \PHP_Token_NAMESPACE) { - $namespace = $tokens[$i]->getName(); - } elseif ($tokens[$i] instanceof \PHP_Token_CLASS) { - $currentClass = $tokens[$i]->getName(); - - if ($namespace != '') { - $currentClass = $namespace . '\\' . $currentClass; - } - - $currentBlock = $currentClass; - } elseif ($tokens[$i] instanceof \PHP_Token_EXTENDS - && $tokens[$i+2] instanceof \PHP_Token_STRING) { - // Store parent-child class relationship. - $this->classParents[$currentClass] = (string)$tokens[$i+2]; - } elseif ($tokens[$i] instanceof \PHP_Token_INTERFACE) { - $currentInterface = $tokens[$i]->getName(); - - if ($namespace != '') { - $currentInterface = $namespace . '\\' . $currentClass; - } - - $currentBlock = $currentInterface; - } elseif ($tokens[$i] instanceof \PHP_Token_NEW && - !$tokens[$i+2] instanceof \PHP_Token_VARIABLE) { - if ($tokens[$i-1] instanceof \PHP_Token_EQUAL) { - $j = -1; - } elseif ($tokens[$i-1] instanceof \PHP_Token_WHITESPACE && - $tokens[$i-2] instanceof \PHP_Token_EQUAL) { - $j = -2; - } else { - continue; - } - - if ($tokens[$i+$j-1] instanceof \PHP_Token_WHITESPACE) { - $j--; - } - - if ($tokens[$i+$j-1] instanceof \PHP_Token_VARIABLE) { - $name = (string)$tokens[$i+$j-1]; - $variables[$name] = (string)$tokens[$i+2]; - } elseif ($tokens[$i+$j-1] instanceof \PHP_Token_STRING && - $tokens[$i+$j-2] instanceof \PHP_Token_OBJECT_OPERATOR && - $tokens[$i+$j-3] instanceof \PHP_Token_VARIABLE) { - $name = (string)$tokens[$i+$j-3] . '->' . - (string)$tokens[$i+$j-1]; - $variables[$name] = (string)$tokens[$i+2]; - } - } elseif ($tokens[$i] instanceof \PHP_Token_FUNCTION) { - if ($currentInterface != '') { - continue; - } - - // Ignore abstract methods. - for ($j=1; $j<=4; $j++) { - if (isset($tokens[$i-$j]) && - $tokens[$i-$j] instanceof \PHP_Token_ABSTRACT) { - continue 2; - } - } - - $function = $tokens[$i]->getName(); - - if ($function == 'anonymous function') { - continue; - } - - $variables = $tokens[$i]->getArguments(); - - if ($currentClass != '') { - $function = $currentClass . '::' . $function; - $variables['$this'] = $currentClass; - } - - $currentFunction = $function; - $currentBlock = $currentFunction; - - $this->functionDeclarations[$function] = array( - 'file' => $filename, 'line' => $tokens[$i]->getLine() - ); - } elseif ($tokens[$i] instanceof \PHP_Token_OPEN_CURLY - || $tokens[$i] instanceof \PHP_Token_CURLY_OPEN - || $tokens[$i] instanceof \PHP_Token_DOLLAR_OPEN_CURLY_BRACES ) { - array_push($blocks, $currentBlock); - $currentBlock = null; - } elseif ($tokens[$i] instanceof \PHP_Token_CLOSE_CURLY) { - $block = array_pop($blocks); - - if ($block == $currentClass) { - $currentClass = ''; - } elseif ($block == $currentFunction) { - $this->functionDeclarations[$currentFunction]['loc'] = - $tokens[$i]->getLine() - $this->functionDeclarations[$currentFunction]['line'] + 1; - $currentFunction = ''; - $variables = array(); - } - } elseif ($tokens[$i] instanceof \PHP_Token_OPEN_BRACKET) { - for ($j = 1; $j <= 4; $j++) { - if (isset($tokens[$i-$j]) && - $tokens[$i-$j] instanceof \PHP_Token_FUNCTION) { - continue 2; - } - } - - if ($tokens[$i-1] instanceof \PHP_Token_STRING) { - $j = -1; - } elseif ($tokens[$i-1] instanceof \PHP_Token_WHITESPACE && - $tokens[$i-2] instanceof \PHP_Token_STRING) { - $j = -2; - } else { - continue; - } - - $function = (string)$tokens[$i+$j]; - $lookForNamespace = true; - - if (isset($tokens[$i+$j-2]) && - $tokens[$i+$j-2] instanceof \PHP_Token_NEW) { - $function .= '::__construct'; - } elseif ((isset($tokens[$i+$j-1]) && - $tokens[$i+$j-1] instanceof \PHP_Token_OBJECT_OPERATOR) || - (isset($tokens[$i+$j-2]) && - $tokens[$i+$j-2] instanceof \PHP_Token_OBJECT_OPERATOR)) { - $_function = $tokens[$i+$j]; - $lookForNamespace = false; - - if ($tokens[$i+$j-1] instanceof \PHP_Token_OBJECT_OPERATOR) { - $j -= 2; - } else { - $j -= 3; - } - - if ($tokens[$i+$j] instanceof \PHP_Token_VARIABLE) { - if (isset($variables[(string)$tokens[$i+$j]])) { - $function = $variables[(string)$tokens[$i+$j]] . - '::' . $_function; - } else { - $function = '::' . $_function; - } - } elseif ($tokens[$i+$j] instanceof \PHP_Token_STRING && - $tokens[$i+$j-1] instanceof \PHP_Token_OBJECT_OPERATOR && - $tokens[$i+$j-2] instanceof \PHP_Token_VARIABLE) { - $variable = (string)$tokens[$i+$j-2] . '->' . - (string)$tokens[$i+$j]; - - if (isset($variables[$variable])) { - $function = $variables[$variable] . '::' . - $_function; - } - } - } elseif ($tokens[$i+$j-1] instanceof \PHP_Token_DOUBLE_COLON) { - $class = (string)$tokens[$i+$j-2]; - - if ($class == 'self' || $class == 'static') { - $class = $currentClass; - } elseif ($class == 'parent') { - $class = "parent($currentClass)"; - } - - $function = $class . '::' . $function; - $j -= 2; - } - - if ($lookForNamespace) { - while ($tokens[$i+$j-1] instanceof \PHP_Token_NS_SEPARATOR) { - $function = $tokens[$i+$j-2] . '\\' . $function; - $j -= 2; - } - } - - if (!isset($this->functionCalls[$function])) { - $this->functionCalls[$function] = array(); - } - $this->functionCalls[$function][] = $currentFunction; - } - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package phpdcd - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\PHPDCD; - -/** - * PHPDCD detector for unused functions. - * - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/phpdcd/tree - * @since Class available since Release 1.0.0 - */ -class Detector -{ - /** - * @param array $files - * @param boolean $recursive - * @return array - */ - public function detectDeadCode(array $files, $recursive = false) - { - - // Analyse files and collect declared and called functions - $analyser = new Analyser(); - foreach ($files as $file) { - $analyser->analyseFile($file); - } - - // Get info on declared and called functions. - $declared = $analyser->getFunctionDeclarations(); - $called = $analyser->getFunctionCalls(); - $classDescendants = $analyser->getClassDescendants(); - - // Search for declared, unused functions. - $result = array(); - foreach ($declared as $name => $source) { - if (!isset($called[$name])) { - // Unused function/method at first sight. - $used = false; - // For methods: check calls from subclass instances as well - $parts = explode('::', $name); - if (count($parts) == 2) { - $class = $parts[0]; - $subclasses = isset($classDescendants[$class]) ? $classDescendants[$class] : array(); - foreach ($subclasses as $subclass) { - if (isset($called[$subclass . '::' . $parts[1]])) { - $used = true; - break; - } - } - } - - if (!$used) { - $result[$name] = $source; - } - } - } - - if ($recursive) { - $done = false; - - while (!$done) { - $done = true; - - foreach ($called as $callee => $callers) { - $_called = false; - - foreach ($callers as $caller) { - if (!isset($result[$caller])) { - $_called = true; - break; - } - } - - if (!$_called) { - if (isset($declared[$callee])) { - $result[$callee] = $declared[$callee]; - } - - $done = false; - - unset($called[$callee]); - } - } - } - } - - ksort($result); - - return $result; - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package phpdcd - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\PHPDCD\CLI; - -use SebastianBergmann\PHPDCD\Detector; -use SebastianBergmann\PHPDCD\Log\Text; -use SebastianBergmann\FinderFacade\FinderFacade; -use Symfony\Component\Console\Command\Command as AbstractCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/phpdcd/tree - * @since Class available since Release 1.0.0 - */ -class Command extends AbstractCommand -{ - /** - * Configures the current command. - */ - protected function configure() - { - $this->setName('phpdcd') - ->setDefinition( - array( - new InputArgument( - 'values', - InputArgument::IS_ARRAY - ) - ) - ) - ->addOption( - 'names', - null, - InputOption::VALUE_REQUIRED, - 'A comma-separated list of file names to check', - array('*.php') - ) - ->addOption( - 'names-exclude', - null, - InputOption::VALUE_REQUIRED, - 'A comma-separated list of file names to exclude', - array() - ) - ->addOption( - 'exclude', - null, - InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, - 'Exclude a directory from code analysis' - ) - ->addOption( - 'recursive', - null, - InputOption::VALUE_NONE, - 'Report code as dead if it is only called by dead code' - ); - } - - /** - * Executes the current command. - * - * @param InputInterface $input An InputInterface instance - * @param OutputInterface $output An OutputInterface instance - * - * @return null|integer null or 0 if everything went fine, or an error code - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $finder = new FinderFacade( - $input->getArgument('values'), - $input->getOption('exclude'), - $this->handleCSVOption($input, 'names'), - $this->handleCSVOption($input, 'names-exclude') - ); - - $files = $finder->findFiles(); - - if (empty($files)) { - $output->writeln('No files found to scan'); - exit(1); - } - - $quiet = $output->getVerbosity() == OutputInterface::VERBOSITY_QUIET; - - $detector = new Detector; - - $result = $detector->detectDeadCode( - $files, - $input->getOption('recursive') - ); - - if (!$quiet) { - $printer = new Text; - $printer->printResult($output, $result); - - $output->writeln(\PHP_Timer::resourceUsage()); - } - } - - /** - * @param Symfony\Component\Console\Input\InputOption $input - * @param string $option - * @return array - */ - private function handleCSVOption(InputInterface $input, $option) - { - $result = $input->getOption($option); - - if (!is_array($result)) { - $result = explode(',', $result); - array_map('trim', $result); - } - - return $result; - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package phpdcd - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\PHPDCD\CLI; - -use SebastianBergmann\Version; -use Symfony\Component\Console\Application as AbstractApplication; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Input\ArrayInput; - -/** - * TextUI frontend for PHPDCD. - * - * @author Sebastian Bergmann - * @copyright 2009-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/phpdcd/tree - * @since Class available since Release 1.0.0 - */ -class Application extends AbstractApplication -{ - public function __construct() - { - $version = new Version('1.0.2', dirname(dirname(__DIR__))); - parent::__construct('phpdcd', $version->getVersion()); - } - - /** - * Gets the name of the command based on input. - * - * @param InputInterface $input The input interface - * - * @return string The command name - */ - protected function getCommandName(InputInterface $input) - { - return 'phpdcd'; - } - - /** - * Gets the default commands that should always be available. - * - * @return array An array of default Command instances - */ - protected function getDefaultCommands() - { - $defaultCommands = parent::getDefaultCommands(); - - $defaultCommands[] = new Command; - - return $defaultCommands; - } - - /** - * Overridden so that the application doesn't expect the command - * name to be the first argument. - */ - public function getDefinition() - { - $inputDefinition = parent::getDefinition(); - $inputDefinition->setArguments(); - - return $inputDefinition; - } - - /** - * Runs the current application. - * - * @param InputInterface $input An Input instance - * @param OutputInterface $output An Output instance - * - * @return integer 0 if everything went fine, or an error code - */ - public function doRun(InputInterface $input, OutputInterface $output) - { - if (!$input->hasParameterOption('--quiet')) { - $output->write( - sprintf( - "phpdcd %s by Sebastian Bergmann.\n\n", - $this->getVersion() - ) - ); - } - - if ($input->hasParameterOption('--version') || - $input->hasParameterOption('-V')) { - exit; - } - - if (!$input->getFirstArgument()) { - $input = new ArrayInput(array('--help')); - } - - parent::doRun($input, $output); - } -} -sebastian/phpdcd: 1.0.2 -phpunit/php-timer: 1.0.5 -phpunit/php-token-stream: 1.2.2 -sebastian/finder-facade: 1.1.0 -sebastian/version: 1.0.3 -symfony/console: v2.4.3 -symfony/finder: v2.4.3 -theseer/fdomdocument: 1.5.0 -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package Version - * @author Sebastian Bergmann - * @copyright 2013-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/version - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann; - -/** - * @package Version - * @author Sebastian Bergmann - * @copyright 2013-2014 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/version - * @since Class available since Release 1.0.0 - */ -class Version -{ - private $path; - private $release; - private $version; - - /** - * @param string $release - * @param string $path - */ - public function __construct($release, $path) - { - $this->release = $release; - $this->path = $path; - } - - /** - * @return string - */ - public function getVersion() - { - if ($this->version === null) { - if (count(explode('.', $this->release)) == 3) { - $this->version = $this->release; - } else { - $this->version = $this->release . '-dev'; - } - - $git = $this->getGitInformation($this->path); - - if ($git) { - if (count(explode('.', $this->release)) == 3) { - $this->version = $git; - } else { - $git = explode('-', $git); - - $this->version = $this->release . '-' . $git[2]; - } - } - } - - return $this->version; - } - - /** - * @param string $path - * @return boolean|string - */ - private function getGitInformation($path) - { - if (!is_dir($path . DIRECTORY_SEPARATOR . '.git')) { - return false; - } - - $dir = getcwd(); - chdir($path); - $result = @exec('git describe --tags 2>&1', $output, $returnCode); - chdir($dir); - - if ($returnCode !== 0) { - return false; - } - - return $result; - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package FinderFacade - * @author Sebastian Bergmann - * @copyright 2012-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\FinderFacade -{ - use Symfony\Component\Finder\Finder; - - /** - * Convenience wrapper for Symfony's Finder component. - * - * @author Sebastian Bergmann - * @copyright 2012-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/finder-facade/tree - * @since Class available since Release 1.0.0 - */ - class FinderFacade - { - /** - * @var array - */ - protected $items = array(); - - /** - * @var array - */ - protected $excludes = array(); - - /** - * @var array - */ - protected $names = array(); - - - /** - * @var array - */ - protected $notNames = array(); - - /** - * @param array $items - * @param array $excludes - * @param array $names - * @param array $notNames - */ - public function __construct(array $items = array(), array $excludes = array(), array $names = array(), array $notNames = array()) - { - $this->items = $items; - $this->excludes = $excludes; - $this->names = $names; - $this->notNames = $notNames; - } - - /** - * @return array - */ - public function findFiles() - { - $files = array(); - $finder = new Finder; - $iterate = FALSE; - - foreach ($this->items as $item) { - if (!is_file($item)) { - $finder->in($item); - $iterate = TRUE; - } - - else { - $files[] = realpath($item); - } - } - - foreach ($this->excludes as $exclude) { - $finder->exclude($exclude); - } - - foreach ($this->names as $name) { - $finder->name($name); - } - - foreach ($this->notNames as $notName) { - $finder->notName($notName); - } - - if ($iterate) { - foreach ($finder as $file) { - $files[] = $file->getRealpath(); - } - } - - return $files; - } - - /** - * @param string $file - */ - public function loadConfiguration($file) - { - $configuration = new Configuration($file); - $configuration = $configuration->parse(); - - $this->items = $configuration['items']; - $this->excludes = $configuration['excludes']; - $this->names = $configuration['names']; - $this->notNames = $configuration['notNames']; - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package FinderFacade - * @author Sebastian Bergmann - * @copyright 2012-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -namespace SebastianBergmann\FinderFacade -{ - use TheSeer\fDOM\fDOMDocument; - - /** - * - * - * - * /path/to/directory - * /path/to/file - * - * /path/to/directory - * *.php - * - * - * - * @author Sebastian Bergmann - * @copyright 2012-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/finder-facade/tree - * @since Class available since Release 1.0.0 - */ - class Configuration - { - /** - * @var string - */ - protected $basePath; - - /** - * @var fDOMDocument - */ - protected $xml; - - /** - * @param string $file - */ - public function __construct($file) - { - $this->basePath = dirname($file); - - $this->xml = new fDOMDocument; - $this->xml->load($file); - } - - /** - * @param string $xpath - * @return array - */ - public function parse($xpath = '') - { - $result = array( - 'items' => array(), 'excludes' => array(), 'names' => array(), 'notNames' => array() - ); - - foreach ($this->xml->getDOMXPath()->query($xpath . 'include/directory') as $item) { - $result['items'][] = $this->toAbsolutePath($item->nodeValue); - } - - foreach ($this->xml->getDOMXPath()->query($xpath . 'include/file') as $item) { - $result['items'][] = $this->toAbsolutePath($item->nodeValue); - } - - foreach ($this->xml->getDOMXPath()->query($xpath . 'exclude') as $exclude) { - $result['excludes'][] = $exclude->nodeValue; - } - - foreach ($this->xml->getDOMXPath()->query($xpath . 'name') as $name) { - $result['names'][] = $name->nodeValue; - } - - foreach ($this->xml->getDOMXPath()->query($xpath . 'notName') as $name) { - $result['notNames'][] = $name->nodeValue; - } - - return $result; - } - - /** - * @param string $path - * @return string - */ - protected function toAbsolutePath($path) - { - // Check whether the path is already absolute. - if ($path[0] === '/' || $path[0] === '\\' || - (strlen($path) > 3 && ctype_alpha($path[0]) && - $path[1] === ':' && ($path[2] === '\\' || $path[2] === '/'))) { - return $path; - } - - // Check whether a stream is used. - if (strpos($path, '://') !== FALSE) { - return $path; - } - - return $this->basePath . DIRECTORY_SEPARATOR . $path; - } - } -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - /** - * fDomElement - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMElement extends \DOMElement { - - public function __toString() { - return $this->C14N(); - } - - /** - * Forward to fDomDocument->query() - * - * @param string $q XPath to use - * @param \DOMNode $ctx \DOMNode to overwrite context - * @param boolean $registerNodeNS Register flag pass thru - * - * @return \DomNodeList - */ - public function query($q, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->query($q, $ctx ? $ctx : $this, $registerNodeNS); - } - - /** - * Forward to fDomDocument->queryOne() - * - * @param string $q XPath to use - * @param \DOMNode $ctx (optional) \DOMNode to overwrite context - * @param boolean $registerNodeNS Register flag pass thru - * - * @return mixed - */ - public function queryOne($q, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->queryOne($q, $ctx ? $ctx : $this, $registerNodeNS); - } - - /** - * Forward to fDomDocument->select() - * - * @param string $selector A CSS Level 3 Selector string - * @param \DOMNode $ctx - * @param bool $registerNodeNS - * - * @return \DOMNodeList - */ - - public function select($selector, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->select($selector, $ctx, $registerNodeNS); - } - - /** - * Parse and append XML String to node - * - * @param String $str string to process - * - * @return fDomDocumentFragment Reference to the created Fragment - */ - public function appendXML($str) { - $frag = $this->ownerDocument->createDocumentFragment(); - $frag->appendXML($str); - $this->appendChild($frag); - return $frag; - } - - /** - * Create a new element and append it - * - * @param string $name Name of not element to create - * @param string $content Optional content to be set - * - * @return fDOMElement Reference to created fDOMElement - */ - public function appendElement($name, $content = null) { - $node = $this->ownerDocument->createElement($name, $content); - $this->appendChild($node); - return $node; - } - - /** - * Create a new element in given namespace and append it - * - * @param string $ns Namespace of node to create - * @param string $name Name of not element to create - * @param string $content Optional content to be set - * - * @return fDOMElement Reference to created fDOMElement - */ - public function appendElementNS($ns, $name, $content = null) { - $node = $this->ownerDocument->createElementNS($ns, $name, $content); - $this->appendChild($node); - return $node; - } - - /** - * Create a new element in given namespace and append it - * - * @param string $prefix Namespace prefix for node to create - * @param string $name Name of not element to create - * @param string $content Optional content to be set - * - * @return fDOMElement Reference to created fDOMElement - */ - public function appendElementPrefix($prefix, $name, $content = null) { - $node = $this->ownerDocument->createElementPrefix($prefix, $name, $content); - $this->appendChild($node); - return $node; - } - - /** - * Create a new text node and append it - * - * @param string $content Text content to be added - * - * @return \DOMText - */ - public function appendTextNode($content) { - $text = $this->ownerDocument->createTextNode($content); - $this->appendChild($text); - return $text; - } - - /** - * Wrapper to DomElement->getAttribute with default value option - * - * Note: A set but emptry attribute does NOT trigger use of the default - * - * @param string $attr Attribute to access - * @param string $default Default value to use if the attribute is not set - * - * @return string - */ - public function getAttribute($attr, $default='') { - return $this->hasAttribute($attr) ? parent::getAttribute($attr) : $default; - } - - /** - * Wrapper to DomElement->getAttributeNS with default value option - * - * Note: A set but empty attribute does NOT trigger use of the default - * - * @param string $ns Namespace of attribute - * @param string $attr Attribute to access - * @param string $default Default value to use if the attribute is not set - * - * @return string - */ - public function getAttributeNS($ns, $attr, $default='') { - return $this->hasAttributeNS($ns, $attr) ? parent::getAttributeNS($ns, $attr) : $default; - } - - /** - * Wrapper to DOMElement::setAttribute with additional entities support - * - * @param string $attr Attribute name to set - * @param string $value Value to set attribute to - * @param bool $keepEntitites Flag to signale if entities should be kept - * - * @throws fDOMException - * - * @return DOMAttr - * - * @see DOMElement::setAttribute() - */ - public function setAttribute($attr, $value, $keepEntities=false) { - if ($keepEntities === true) { - $attrNode = $this->ownerDocument->createAttribute($attr); - if (!$attrNode) { - throw new fDOMException("Setting attribute '$attr' failed.", fDOMException::SetFailedError); - } - $attrNode->value = $value; - $this->appendChild($attrNode); - return $attrNode; - } - return parent::setAttribute($attr, $value); - } - - /** - * Wrapper to namespace aware DOMElement::setAttributeNS with additional entities support - * - * @param string $ns namespace attribute should be in - * @param string $attr Attribute name to set - * @param string $value Value to set attribute to - * @param boolean $keepEntitites Flag to signale if entities should be kept - * - * @return \DOMAttr - * - * @see DOMElement::setAttribute() - */ - public function setAttributeNS($ns, $attr, $value, $keepEntities=false) { - if ($keepEntities === true) { - $attrNode = $this->ownerDocument->createAttributeNS($ns, $attr); - if (!$attrNode) { - throw new fDOMException("Setting attribute '$attr' failed.", fDOMException::SetFailedError); - } - $attrNode->value = $value; - $this->appendChild($attrNode); - return $attrNode; - } - return parent::setAttributeNS($ns, $attr, $value); - } - - /** - * Helper to add multiple attributes to an element - * - * @param array $attr Attributes to add as key-value pair - * @param bool $keepEntities Flag wether to keep entities - * - * @return array List with references to created DOMAttr - */ - public function setAttributes(array $attr, $keepEntities=false) { - $attList = array(); - foreach($attr as $name => $value) { - $attList[] = $this->setAttribute($name, $value, $keepEntities); - } - return $attList; - } - - /** - * Helper to add multiple attributes with the given namespace and prefix - * - * @param string $ns Namespace of attribute - * @param string $prefix Namespace prefix for attribute to create - * @param array $attr Attributes to add - * @param bool $keepEntities Flag wether to keep entities - * - * @return void - */ - public function setAttributesNS($ns, $prefix, array $attr, $keepEntities=false) { - foreach($attr as $name => $value) { - $this->setAttributeNS($ns, $prefix.':'.$name, $value, $keepEntities); - } - } - - /** - * Helper method to get children by name - * - * @param string $tagName tagname to search for - * - * @return DomNodeList - */ - public function getChildrenByTagName($tagName) { - return $this->query("*[local-name()='$tagName']"); - } - - /** - * Helper method to get children by name and namespace - * - * @param string $ns namespace nodes have to be in - * @param string $tagName tagname to search for - * - * @return DomNodeList - */ - public function getChildrenByTagNameNS($ns, $tagName) { - return $this->query("*[local-name()='$tagName' and namespace-uri()='$ns']"); - } - - /** - * Check if the given node is in the same document - * - * @param \DomNode $node Node to compare with - * - * @return boolean true on match, false if they differ - * - */ - public function inSameDocument(\DomNode $node) { - return $this->ownerDocument->inSameDocument($node); - } - - /** - * Wrapper to DomDocument::saveXML() with current node as context - * - * @return string - */ - public function saveXML() { - return $this->ownerDocument->saveXML($this); - } - - /** - * Wrapper to DomDocument::saveHTML() with current node as context - * - * @return string - */ - public function saveHTML() { - return $this->ownerDocument->saveHTML($this); - } - - } // fDOMElement - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - /** - * fDomNode - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMNode extends \DOMNode { - - public function __toString() { - return $this->C14N(); - } - - /** - * Forward to fDomDocument->query() - * - * @param string $q XPath to use - * @param \DOMNode $ctx \DOMNode to overwrite context - * @param boolean $registerNodeNS Register flag pass thru - * - * @return \DomNodeList - */ - public function query($q, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->query($q, $ctx ? $ctx : $this, $registerNodeNS); - } - - /** - * Forward to fDomDocument->queryOne() - * - * @param string $q XPath to use - * @param \DOMNode $ctx (optional) \DOMNode to overwrite context - * @param boolean $registerNodeNS Register flag pass thru - * - * @return mixed - */ - public function queryOne($q, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->queryOne($q, $ctx ? $ctx : $this, $registerNodeNS); - } - - /** - * Forward to fDomDocument->select() - * - * @param string $selector A CSS Level 3 Selector string - * @param \DOMNode $ctx - * @param bool $registerNodeNS - * - * @return \DOMNodeList - */ - - public function select($selector, \DOMNode $ctx = null, $registerNodeNS = true) { - return $this->ownerDocument->select($selector, $ctx, $registerNodeNS); - } - - /** - * Check if the given node is in the same document - * - * @param \DomNode $node Node to compare with - * - * @return boolean true on match, false if they differ - * - */ - public function inSameDocument(\DOMNode $node) { - return $this->ownerDocument->inSameDocument($node); - } - - /** - * Wrapper to DomDocument::saveXML() with current node as context - * - * @return string - */ - public function saveXML() { - return $this->ownerDocument->saveXML($this); - } - - /** - * Wrapper to DomDocument::saveHTML() with current node as context - * - * @return string - */ - public function saveHTML() { - return $this->ownerDocument->saveHTML($this); - } - - - - } // fDOMNode - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - /** - * Class XPathQuery - * - * @package TheSeer\fDOM - */ - class XPathQuery { - - /** - * @var string - */ - private $query; - - /** - * Key-value Map for bound values - * - * @var array - */ - private $values = array(); - - /** - * @param string $query - */ - public function __construct($query) { - $this->setQuery($query); - } - - /** - * @param string $query - */ - private function setQuery($query) { - $this->query = $query; - $res = preg_match_all('/(:(\w*))/', $query, $matches); - if ($res > 0) { - $this->values = array_fill_keys($matches[2], ''); - } - } - - public function getKeys() { - return array_keys($this->values); - } - - public function bind($key, $value) { - if (!array_key_exists($key, $this->values)) { - throw new XPathQueryException("'$key' not found in query'", XPathQueryException::KeyNotFound ); - } - $this->values[$key] = $value; - } - - public function generate(\DOMNode $ctx, array $values = NULL) { - return $this->buildQuery($this->getXPathObjectFor($ctx), $values); - } - - public function evaluate(\DOMNode $ctx, array $values = NULL, $registerNodeNS = TRUE) { - $xp = $this->getXPathObjectFor($ctx); - return $xp->evaluate($this->buildQuery($xp, $values), $ctx, $registerNodeNS); - } - - public function query(\DOMNode $ctx, array $values = NULL, $registerNodeNS = TRUE) { - $xp = $this->getXPathObjectFor($ctx); - return $xp->evaluate($this->buildQuery($xp, $values), $ctx, $registerNodeNS); - } - - public function queryOne(\DOMNode $ctx, array $values = NULL, $registerNodeNS = TRUE) { - $xp = $this->getXPathObjectFor($ctx); - return $xp->queryOne($this->buildQuery($xp, $values), $ctx, $registerNodeNS); - } - - private function getXPathObjectFor(\DOMNode $ctx) { - $dom = $ctx instanceof \DOMDocument ? $ctx : $ctx->ownerDocument; - if ($dom instanceOf fDOMDocument) { - return $dom->getDOMXPath(); - } - return new fDOMXPath($dom); - } - - private function buildQuery(fDOMXPath $xp, array $values = NULL) { - $backup = $this->values; - if (count($values) > 0) { - foreach($values as $k => $v) { - $this->bind($k, $v); - } - } - $query = $xp->prepare($this->query, $this->values); - $this->values = $backup; - return $query; - } - } - -} -translator = $translator; - } - - /** - * @param $selector - * - * @return string - */ - public function apply($selector) { - return preg_replace_callback( - '/([a-zA-Z0-9\_\-\*]+):not\(([^\)]*)\)/', - array($this, 'callback'), - $selector - ); - } - - private function callback(array $matches) { - $subresult = preg_replace( - '/^[^\[]+\[([^\]]*)\].*$/', - '$1', - $this->translator->translate($matches[2]) - ); - return $matches[1] . '[not(' . $subresult . ')]'; - } - - } - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM\CSS { - - /** - * Class Translator - * - * The regular expressions used in this class are heavily inspired by and mostly adopted from - * the css2xpath.js code by Andrea Giammarchi (http://code.google.com/p/css2xpath/). - * The JavaScript version (css2xpath.js) is licensed under the MIT License - * - */ - class Translator { - - /** - * @var array - */ - private $rules; - - /** - * @param string $selector A CSS Selector string - * - * @return string - */ - public function translate($selector) { - foreach($this->getRules() as $rule) { - /** @var RuleInterface $rule */ - $selector = $rule->apply($selector); - } - return '//' . $selector; - } - - /** - * @return array - */ - private function getRules() { - if ($this->rules != NULL) { - return $this->rules; - } - - $this->rules = array( - - // prefix|name - new RegexRule('/([a-zA-Z0-9\_\-\*]+)\|([a-zA-Z0-9\_\-\*]+)/', '$1:$2'), - - // add @ for attribs - new RegexRule("/\[([^\]~\$\*\^\|\!]+)(=[^\]]+)?\]/", '[@$1$2]'), - - // multiple queries - new RegexRule("/\s*,\s*/", '|'), - - // , + ~ > - new RegexRule("/\s*(\+|~|>)\s*/", '$1'), - - //* ~ + > - new RegexRule("/([a-zA-Z0-9\_\-\*])~([a-zA-Z0-9\_\-\*])/", '$1/following-sibling::$2'), - new RegexRule("/([a-zA-Z0-9\_\-\*])\+([a-zA-Z0-9\_\-\*])/", '$1/following-sibling::*[1]/self::$2'), - new RegexRule("/([a-zA-Z0-9\_\-\*])>([a-zA-Z0-9\_\-\*])/", '$1/$2'), - - // all unescaped stuff escaped - new RegexRule("/\[([^=]+)=([^'|'][^\]]*)\]/", '[$1="$2"]'), - - // all descendant or self to // - new RegexRule("/(^|[^a-zA-Z0-9\_\-\*])(#|\.)([a-zA-Z0-9\_\-]+)/", '$1*$2$3'), - new RegexRule("/([\>\+\|\~\,\s])([a-zA-Z\*]+)/", '$1//$2'), - new RegexRule("/\s+\/\//", '//'), - - // :first-child - new RegexRule("/([a-zA-Z0-9\_\-\*]+):first-child/", '*[1]/self::$1'), - - // :last-child - new RegexRule("/([a-zA-Z0-9\_\-\*]+):last-child/", '$1[not(following-sibling::*)]'), - - // :only-child - new RegexRule("/([a-zA-Z0-9\_\-\*]+):only-child/", '*[last()=1]/self::$1'), - - // :empty - new RegexRule("/([a-zA-Z0-9\_\-\*]+):empty/", '$1[not(*) and not(normalize-space())]'), - - // :not - new NotRule($this), - - // :nth-child - new NthChildRule(), - - // :contains(selectors) - new RegexRule('/:contains\(([^\)]*)\)/', '[contains(string(.),"$1")]'), - - // |= attrib - new RegexRule("/\[([a-zA-Z0-9\_\-]+)\|=([^\]]+)\]/", '[@$1=$2 or starts-with(@$1,concat($2,"-"))]'), - - // *= attrib - new RegexRule("/\[([a-zA-Z0-9\_\-]+)\*=([^\]]+)\]/", '[contains(@$1,$2)]'), - - // ~= attrib - new RegexRule("/\[([a-zA-Z0-9\_\-]+)~=([^\]]+)\]/", '[contains(concat(" ",normalize-space(@$1)," "),concat(" ",$2," "))]'), - - // ^= attrib - new RegexRule("/\[([a-zA-Z0-9\_\-]+)\^=([^\]]+)\]/", '[starts-with(@$1,$2)]'), - - // $= attrib - new DollarEqualRule(), - - // != attrib - new RegexRule("/\[([a-zA-Z0-9\_\-]+)\!=([^\]]+)\]/", '[not(@$1) or @$1!=$2]'), - - // ids and classes - new RegexRule("/#([a-zA-Z0-9\_\-]+)/", '[@id="$1"]'), - new RegexRule("/\.([a-zA-Z0-9\_\-]+)/", '[contains(concat(" ",normalize-space(@class)," ")," $1 ")]'), - - // normalize multiple filters - new RegexRule("/\]\[([^\]]+)/", ' and ($1)') - - - ); - return $this->rules; - } - } - -} -=0]/self::' . $matches[1]; - } - case 'odd': { - return $matches[1] . '[(count(preceding-sibling::*) + 1) mod 2=1]'; - } - default: { - $b = !isset($matches[2]) || empty($matches[2]) ? '0' : $matches[2]; - $b = preg_replace('/^([0-9]*)n.*?([0-9]*)$/', '$1+$2', $b); - $b = explode('+', $b); - if (!isset($b[1])) { - $b[1] = '0'; - } - return '*[(position()-' . $b[1] . ') mod ' . $b[0] . '=0 and position()>=' . $b[1] . ']/self::' . $matches[1]; - } - } - } - - } - -} -regex = $regex; - $this->replacement = $replacement; - } - - /** - * @param $selector - * - * @return string - */ - public function apply($selector) { - return preg_replace($this->regex, $this->replacement, $selector); - } - - } - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - /** - * fDOMXPath extension to PHP's DOMXPath. - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMXPath extends \DOMXPath { - - protected $doc; - - public function __construct(\DOMDocument $doc) { - parent::__construct($doc); - $this->doc = $doc; - } - - public function prepare($xpath, array $valueMap) { - if (count($valueMap)==0) { - return $xpath; - } - foreach($valueMap as $key => $value) { - $xpath = str_replace(':'.$key, $this->quote($value), $xpath); - } - return $xpath; - } - - public function query($q, \DOMNode $ctx = null, $registerNodeNS = true) { - libxml_clear_errors(); - if (version_compare(PHP_VERSION, '5.3.3', '<') || strpos(PHP_VERSION, 'hiphop')) { - $rc = parent::query($q, ($ctx instanceof \DOMNode) ? $ctx : $this->doc->documentElement); - } else { - $rc = parent::query($q, ($ctx instanceof \DOMNode) ? $ctx : $this->doc->documentElement, $registerNodeNS); - } - - if (libxml_get_last_error()) { - throw new fDOMException('evaluating xpath expression failed.', fDOMException::QueryError); - } - return $rc; - } - - public function evaluate($q, \DOMNode $ctx = null, $registerNodeNS = true) { - libxml_clear_errors(); - if (version_compare(PHP_VERSION, '5.3.3', '<') || strpos(PHP_VERSION, 'hiphop')) { - $rc = parent::evaluate($q, ($ctx instanceof \DOMNode) ? $ctx : $this->doc->documentElement); - } else { - $rc = parent::evaluate($q, ($ctx instanceof \DOMNode) ? $ctx : $this->doc->documentElement, $registerNodeNS); - } - if (libxml_get_last_error()) { - throw new fDOMException('evaluating xpath expression failed.', fDOMException::QueryError); - } - return $rc; - } - - public function queryOne($q, \DOMNode $ctx = null, $registerNodeNS = true) { - $rc = $this->evaluate($q, $ctx, $registerNodeNS); - if ($rc instanceof \DOMNodelist) { - return $rc->item(0); - } - return $rc; - } - - public function quote($str) { - if (strpos($str, '"') === false) { - return '"'.$str.'"'; - } - $parts = explode('"', $str); - return 'concat("' . join('",\'"\',"', $parts).'")'; - } - } -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - class XPathQueryException extends \Exception { - const KeyNotFound = 1; - } - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license BSD License - */ - -namespace TheSeer\fDOM { - - /** - * fDOMException - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMException extends \Exception { - - const LoadError = 1; - const ParseError = 2; - const SaveError = 3; - const QueryError = 4; - const RegistrationFailed = 5; - const NoDOMXPath = 6; - const UnboundPrefix = 7; - const SetFailedError = 8; - const NameInvalid = 9; - - /** - * List of libxml error objects - * - * @var array - */ - private $errorList; - - - /** - * Full Error message - * - * @var string - */ - private $fullMessage = null; - - - /** - * Short Error Message - * - * @var string - */ - private $shortMessage = null; - - - private static $fullMesageMode = true; - - /** - * Constructor - * - * @param string $message Exception message - * @param integer $code Exception code - * @param Exception $chain optional chained exception - * - */ - public function __construct($message, $code = 0, \Exception $chain = NULL) { - $this->shortMessage = $message; - $this->errorList = libxml_get_errors(); - libxml_clear_errors(); - parent :: __construct($message, $code, $chain); - - $this->fullMessage = $message."\n\n"; - - foreach ($this->errorList as $error) { - // hack, skip "attempt to load external pseudo error" - if ($error->code=='1543') { - continue; - } - - if (empty($error->file)) { - $this->fullMessage .= '[XML-STRING] '; - } else { - $this->fullMessage .= '['.$error->file.'] '; - } - - $this->fullMessage .= '[Line: '.$error->line.' - Column: '.$error->column.'] '; - - switch ($error->level) { - case LIBXML_ERR_WARNING: - $this->fullMessage .= "Warning $error->code: "; - break; - case LIBXML_ERR_ERROR: - $this->fullMessage .= "Error $error->code: "; - break; - case LIBXML_ERR_FATAL: - $this->fullMessage .= "Fatal Error $error->code: "; - break; - } - - $this->fullMessage .= str_replace("\n", '', $error->message)."\n"; - - if (self::$fullMesageMode) { - $this->message = $this->fullMessage; - } - - } - } - - /** - * Accessor to fullMessage - * - * @return string - */ - public function getFullMessage() { - return $this->fullMessage; - } - - /** - * Access to shortMessage - * - * @return string - */ - public function getShortMessage() { - return $this->shortMessage; - } - - /** - * Accessor to errorList objets - * - * @return array - */ - public function getErrorList() { - return $this->errorList; - } - - /** - * Toggle wehter getMessage() should return full or only exception message - * - * @param boolean $full Flag to enable or disable full message output - * - * @return void - */ - public function toggleFullMessage($full = true) { - $this->message = $full ? $this->fullMessage : $this->shortMessage; - } - - /** - * Magic method for string context - * - * @return string - */ - public function __toString() { - return $this->fullMessage; - } - - } // fDOMException - -} - '/css/DollarEqualRule.php', - 'theseer\\fdom\\css\\notrule' => '/css/NotRule.php', - 'theseer\\fdom\\css\\nthchildrule' => '/css/NthChildRule.php', - 'theseer\\fdom\\css\\regexrule' => '/css/RegexRule.php', - 'theseer\\fdom\\css\\ruleinterface' => '/css/RuleInterface.php', - 'theseer\\fdom\\css\\translator' => '/css/Translator.php', - 'theseer\\fdom\\fdomdocument' => '/fDOMDocument.php', - 'theseer\\fdom\\fdomdocumentfragment' => '/fDOMDocumentFragment.php', - 'theseer\\fdom\\fdomelement' => '/fDOMElement.php', - 'theseer\\fdom\\fdomexception' => '/fDOMException.php', - 'theseer\\fdom\\fdomnode' => '/fDOMNode.php', - 'theseer\\fdom\\fdomxpath' => '/fDOMXPath.php', - 'theseer\\fdom\\xpathquery' => '/XPathQuery.php', - 'theseer\\fdom\\xpathqueryexception' => '/XPathQueryException.php' - ); - } - $cn = strtolower($class); - if (isset($classes[$cn])) { - require __DIR__ . $classes[$cn]; - } - } -); -// @codeCoverageIgnoreEnd - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - use TheSeer\fDOM\CSS\Translator; - - /** - * fDOMDocument extension to PHP's DOMDocument. - * This class adds various convenience methods to simplify APIs - * It is set to final since further extending it would even more - * break the Object structure after use of registerNodeClass. - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMDocument extends \DOMDocument { - - /** - * XPath Object instance - * - * @var fDOMXPath - */ - private $xp = NULL; - - /** - * List of registered prefixes and their namespace uri - * @var Array - */ - private $prefixes = array(); - - /** - * Extended DOMDocument constructor - * - * @param string $version XML Version, should be 1.0 - * @param string $encoding Encoding, defaults to utf-8 - * @param array $streamOptions optional stream options array - * - * @return fDOMDocument - */ - public function __construct($version = '1.0', $encoding = 'utf-8', $streamOptions = NULL) { - if (!is_null($streamOptions)) { - $this->setStreamContext($streamOptions); - } - - libxml_use_internal_errors(TRUE); - $rc = parent::__construct($version, $encoding); - - $this->registerNodeClass('DOMDocument', get_called_class()); - $this->registerNodeClass('DOMNode', 'TheSeer\fDOM\fDOMNode'); - $this->registerNodeClass('DOMElement', 'TheSeer\fDOM\fDOMElement'); - $this->registerNodeClass('DOMDocumentFragment', 'TheSeer\fDOM\fDOMDocumentFragment'); - - return $rc; - } - - /** - * Reset XPath object so the clone gets a new instance when needed - */ - public function __clone() { - $this->xp = new fDOMXPath($this); - foreach($this->prefixes as $prefix => $uri) { - $this->xp->registerNamespace($prefix, $uri); - } - } - - public function __toString() { - return $this->C14N(); - } - - /** - * Set Stream context options - * - * @param Array $options Stream context options - * - * @return boolean true on success, false on failure - */ - public function setStreamContext(Array $options) { - if (!count($options)) { - return FALSE; - } - $context = stream_context_create($options); - libxml_set_streams_context($context); - return TRUE; - } - - /** - * Wrapper to DOMDocument load with exception handling - * Returns true on success to satisfy the compatibilty of the original DOM Api - * - * @param string $fname File to load - * @param int|null $options LibXML Flags to pass - * - * @throws fDOMException - * - * @return bool|mixed - */ - public function load($fname, $options = LIBXML_NONET) { - $this->xp = NULL; - $tmp = parent :: load($fname, $options); - if (!$tmp || libxml_get_last_error()) { - throw new fDOMException("loading file '$fname' failed.", fDOMException::LoadError); - } - return TRUE; - } - - /** - * Wrapper to DOMDocument loadXML with exception handling - * Returns true on success to satisfy the compatibilty of the original DOM Api - * - * @param string $source XML source code - * @param integer $options LibXML option flags - * - * @throws fDOMException - * - * @return boolean - */ - public function loadXML($source, $options = LIBXML_NONET) { - $this->xp = NULL; - $tmp = parent :: loadXML($source, $options); - if (!$tmp || libxml_get_last_error()) { - throw new fDOMException('parsing string failed', fDOMException::ParseError); - } - return TRUE; - } - - /** - * Wrapper to DOMDocument loadHTMLFile with exception handling. - * Returns true on success to satisfy the compatibilty of the original DOM Api - * - * @param string $fname html file to load - * @param integer $options Options bitmask (@see DOMDocument::loadHTMLFile) - * - * @throws fDOMException - * - * @return boolean - */ - public function loadHTMLFile($fname, $options = NULL) { - $this->xp = NULL; - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - if ($options != NULL) { - throw new fDOMException('Passing options requires PHP 5.4.0+', fDOMException::LoadError); - } - $tmp = parent :: loadHTMLFile($fname); - } else { - $tmp = parent :: loadHTMLFile($fname, $options); - } - if (!$tmp || libxml_get_last_error()) { - throw new fDOMException("loading html file '$fname' failed", fDOMException::LoadError); - } - return TRUE; - } - - /** - * Wrapper to DOMDocument loadHTML with exception handling - * Returns true on success to satisfy the compatibilty of the original DOM Api - * - * @param string $source html source code - * @param integer $options Options bitmask (@see DOMDocument::loadHTML) - * - * @throws fDOMException - * - * @return boolean - */ - public function loadHTML($source, $options = NULL) { - $this->xp = NULL; - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - if ($options != NULL) { - throw new fDOMException('Passing options requires PHP 5.4.0+', fDOMException::LoadError); - } - $tmp = parent :: loadHTML($source); - } else { - $tmp = parent :: loadHTML($source, $options); - } - if (!$tmp || libxml_get_last_error()) { - throw new fDOMException('parsing html string failed', fDOMException::ParseError); - } - return TRUE; - } - - /** - * Wrapper to DOMDocument::save with exception handling - * - * @param string $filename filename to save to - * @param integer $options Options bitmask (@see DOMDocument::save) - * - * @throws fDOMException - * - * @return integer bytes saved - */ - public function save($filename, $options = NULL) { - $tmp = parent::save($filename, $options); - if (!$tmp) { - throw new fDOMException('saving xml file failed', fDOMException::SaveError); - } - return $tmp; - } - - /** - * Wrapper to DOMDocument::saveHTML with exception handling - * - * @param DOMNode|null $node Context DOMNode (optional) - * - * @throws fDOMException - * @return string html content - */ - public function saveHTML(\DOMNode $node = NULL) { - if (version_compare(PHP_VERSION, '5.3.6', '<') && $node != NULL) { - throw new fDOMException('Passing a context node requires PHP 5.3.6+', fDOMException::SaveError); - } - $tmp = parent::saveHTML($node); - if (!$tmp) { - throw new fDOMException('serializing to HTML failed', fDOMException::SaveError); - } - return $tmp; - } - - /** - * Wrapper to DOMDocument::saveHTMLfile with exception handling - * - * @param string $filename filename to save to - * @param integer $options Options bitmask (@see DOMDocument::saveHTMLFile) - * - * @throws fDOMException - * - * @return integer bytes saved - */ - public function saveHTMLFile($filename, $options = NULL) { - $tmp = parent::saveHTMLFile($filename, $options); - if (!$tmp) { - throw new fDOMException('saving to HTML file failed', fDOMException::SaveError); - } - return $tmp; - } - - /** - * Wrapper to DOMDocument::saveXML with exception handling - * - * @param \DOMNode $node node to start serializing at - * @param integer $options options flags as bitmask - * - * @throws fDOMException - * - * @return string serialized XML - */ - public function saveXML(\DOMNode $node = NULL, $options = NULL) { - try { - $tmp = parent::saveXML($node, $options); - if (!$tmp) { - throw new fDOMException('serializing to XML failed', fDOMException::SaveError); - } - return $tmp; - } catch (\Exception $e) { - if (!$e instanceof fDOMException) { - throw new fDOMException($e->getMessage(), fDOMException::SaveError, $e); - } - throw $e; - } - } - - /** - * get Instance of DOMXPath Object for current DOM - * - * @throws fDOMException - * - * @return fDOMXPath - */ - public function getDOMXPath() { - if (is_null($this->xp)) { - $this->xp = new fDOMXPath($this); - } - if (!$this->xp) { - throw new fDOMException('creating DOMXPath object failed.', fDOMException::NoDOMXPath); - } - return $this->xp; - } - - /** - * Convert a given DOMNodeList into a DOMFragment - * - * @param \DOMNodeList $list The Nodelist to process - * @param boolean $move Signale if nodes are to be moved into fragment or not - * - * @return fDOMDocumentFragment - */ - public function nodeList2Fragment(\DOMNodeList $list, $move=FALSE) { - $frag = $this->createDocumentFragment(); - /** @var fDOMNode $node */ - foreach($list as $node) { - $frag->appendChild($move ? $node : $node->cloneNode(TRUE)); - } - return $frag; - } - - /** - * Perform an xpath query - * - * @param String $q query string containing xpath - * @param \DOMNode|null $ctx (optional) Context DOMNode - * @param boolean $registerNodeNS Register flag pass through - * - * @return \DOMNodeList - */ - public function query($q, \DOMNode $ctx = NULL, $registerNodeNS = TRUE) { - if (is_null($this->xp)) { - $this->getDOMXPath(); - } - return $this->xp->evaluate($q, $ctx, $registerNodeNS); - } - - /** - * Perform an xpath query and return only the 1st match - * - * @param String $q query string containing xpath - * @param \DOMNode $ctx (optional) Context DOMNode - * @param boolean $registerNodeNS Register flag pass thru - * - * @return fDOMNode - */ - public function queryOne($q, \DOMNode $ctx = NULL, $registerNodeNS = TRUE) { - if (is_null($this->xp)) { - $this->getDOMXPath(); - } - return $this->xp->queryOne($q, $ctx, $registerNodeNS); - } - - /** - * Forwarder to fDOMXPath's prepare method allowing for easy and secure - * placeholder replacement comparable to sql's prepared statements - * . - * @param string $xpath String containing xpath with :placeholder markup - * @param array $valueMap Array containing keys (:placeholder) and value pairs to be quoted - * - * @return string - */ - public function prepareQuery($xpath, array $valueMap) { - if (is_null($this->xp)) { - $this->getDOMXPath(); - } - return $this->xp->prepare($xpath, $valueMap); - } - - /** - * Use a CSS Level 3 Selector string to query select nodes - * - * @param string $selector A CSS Level 3 Selector string - * @param \DOMNode $ctx - * @param bool $registerNodeNS - * - * @return \DOMNodeList - */ - public function select($selector, \DOMNode $ctx = NULL, $registerNodeNS = TRUE) { - $translator = new Translator(); - $xpath = $translator->translate($selector); - if ($ctx != NULL) { - $xpath = '.' . $xpath; - } - return $this->query($xpath, $ctx, $registerNodeNS); - } - - /** - * Forward to DOMXPath->registerNamespace() - * - * @param string $prefix The prefix to use - * @param string $uri The uri to assign to this prefix - * - * @throws fDOMException - * - * @return void - */ - public function registerNamespace($prefix, $uri) { - if (is_null($this->xp)) { - $this->getDOMXPath(); - } - if (!$this->xp->registerNamespace($prefix, $uri)) { - throw new fDOMException("Registering namespace '$uri' with prefix '$prefix' failed.", fDOMException::RegistrationFailed); - } - $this->prefixes[$prefix] = $uri; - } - - /** - * Forward to DOMXPath->registerPHPFunctions() - * - * @param mixed $restrict Array of function names or string with functionname to restrict callabilty to - * - * @throws fDOMException - * - * @return void - */ - public function registerPHPFunctions($restrict = NULL) { - if (is_null($this->xp)) { - $this->getDOMXPath(); - } - $this->xp->registerPHPFunctions($restrict); - if (libxml_get_last_error()) { - throw new fDOMException("Registering php functions failed.", fDOMException::RegistrationFailed); - } - } - - /** - * Create a new element in namespace defined by given prefix - * - * @param string $prefix Namespace prefix for node to create - * @param string $name Name of not element to create - * @param string $content Optional content to be set - * @param bool $asTextNode Create content as textNode rather then setting nodeValue - * - * @throws fDOMException - * - * @return fDOMElement Reference to created fDOMElement - */ - public function createElementPrefix($prefix, $name, $content = NULL, $asTextNode = FALSE) { - if (!isset($this->prefixes[$prefix])) { - throw new fDOMException("'$prefix' not bound", fDOMException::UnboundPrefix); - } - return $this->createElementNS($this->prefixes[$prefix], $prefix.':'.$name, $content, $asTextNode); - } - - /** - * Create a new fDOMElement and return it, optionally set content - * - * @param string $name Name of node to create - * @param null $content Content to set (optional) - * @param bool $asTextNode Create content as textNode rather then setting nodeValue - * - * @throws fDOMException - * - * @return fDOMElement Reference to created fDOMElement - */ - public function createElement($name, $content = NULL, $asTextnode = FALSE) { - try { - $node = parent::createElement($name); - if (!$node) { - throw new fDOMException("Creating element with name '$name' failed", fDOMException::NameInvalid); - } - if ($content !== NULL) { - if ($asTextnode) { - $node->appendChild($this->createTextnode($content)); - } else { - $node->nodeValue = $content; - } - if (libxml_get_errors()) { - throw new fDOMException("Setting content value failed", fDOMException::SetFailedError); - } - } - } catch (\DOMException $e) { - throw new fDOMException("Creating elemnt with name '$name' failed", 0, $e); - } - return $node; - } - - /** - * Create a new fDOMElement within given namespace and return it - * - * @param string $namespace Namespace URI for node to create - * @param string $name Name of node to create - * @param null $content Content to set (optional) - * @param bool $asTextNode Create content as textNode rather then setting nodeValue - * - * @throws fDOMException - * - * @return fDOMElement - */ - public function createElementNS($namespace, $name, $content = NULL, $asTextNode = FALSE) { - $node = parent::createElementNS($namespace, $name); - if (!$node) { - throw new fDOMException("Creating element with name '$name' failed", fDOMException::NameInvalid); - } - if ($content !== NULL) { - if ($asTextNode) { - $node->appendChild($this->createTextnode($content)); - } else { - $node->nodeValue = $content; - } - if (libxml_get_errors()) { - throw new fDOMException("Setting content value failed", fDOMException::SetFailedError); - } - } - return $node; - } - - /** - * Check if the given node is in the same document - * - * @param \DOMNode $node Node to compare with - * - * @return boolean true on match, false if they differ - * - */ - public function inSameDocument(\DOMNode $node) { - if ($node instanceof \DOMDocument) { - return $this->isSameNode($node); - } - return $this->isSameNode($node->ownerDocument); - } - - /** - * Create a new element and append it as documentElement - * - * @param $name Name of not element to create - * @param $content Optional content to be set - * - * @return fDOMElement Reference to created fDOMElement - */ - public function appendElement($name, $content = NULL, $asTextNode = FALSE) { - return $this->appendChild( - $this->createElement($name, $content, $asTextNode) - ); - } - - /** - * Create a new element in given namespace and append it as documentElement - * - * @param $ns Namespace of node to create - * @param $name Name of not element to create - * @param $content Optional content to be set - * - * @return fDOMElement Reference to created fDOMElement - */ - public function appendElementNS($ns, $name, $content = NULL, $asTextNode = FALSE) { - return $this->appendChild( - $this->createElementNS($ns, $name, $content, $asTextNode) - ); - } - - } // fDOMDocument - -} - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Arne Blankerts nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @copyright Arne Blankerts , All rights reserved. - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @link http://github.com/theseer/fdomdocument - * - */ - -namespace TheSeer\fDOM { - - /** - * fDOMDocumentFragment - * - * @category PHP - * @package TheSeer\fDOM - * @author Arne Blankerts - * @access public - * - */ - class fDOMDocumentFragment extends \DOMDocumentFragment { - - public function __toString() { - return $this->C14N(); - } - - /** - * Wrapper to standard method with exception support - * - * @param string $str Data string to parse and append - * - * @return boolean true on success - */ - public function appendXML($str) { - if (!parent::appendXML($str)) { - throw new fDOMException('Appending xml string failed', fDOMException::ParseError); - } - return true; - } - - /** - * Check if the given node is in the same document - * - * @param \DOMNode $node Node to compare with - * - * @return boolean true on match, false if they differ - * - */ - public function inSameDocument(\DOMNode $node) { - return $this->ownerDocument->inSameDocument($node); - } - - } // fDOMDocumentFragment - -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHP - * @subpackage Timer - * @author Sebastian Bergmann - * @copyright 2010-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/php-timer - * @since File available since Release 1.0.0 - */ - -/** - * Utility class for timing. - * - * @package PHP - * @subpackage Timer - * @author Sebastian Bergmann - * @copyright 2010-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/php-timer - * @since Class available since Release 1.0.0 - */ -class PHP_Timer -{ - /** - * @var array - */ - private static $times = array( - 'hour' => 3600000, - 'minute' => 60000, - 'second' => 1000 - ); - - /** - * @var array - */ - private static $startTimes = array(); - - /** - * @var float - */ - public static $requestTime; - - /** - * Starts the timer. - */ - public static function start() - { - array_push(self::$startTimes, microtime(TRUE)); - } - - /** - * Stops the timer and returns the elapsed time. - * - * @return float - */ - public static function stop() - { - return microtime(TRUE) - array_pop(self::$startTimes); - } - - /** - * Formats the elapsed time as a string. - * - * @param float $time - * @return string - */ - public static function secondsToTimeString($time) - { - $ms = round($time * 1000); - - foreach (self::$times as $unit => $value) { - if ($ms >= $value) { - $time = floor($ms / $value * 100.0) / 100.0; - return $time . ' ' . ($time == 1 ? $unit : $unit . 's'); - } - } - - return $ms . ' ms'; - } - - /** - * Formats the elapsed time since the start of the request as a string. - * - * @return string - */ - public static function timeSinceStartOfRequest() - { - return self::secondsToTimeString(microtime(TRUE) - self::$requestTime); - } - - /** - * Returns the resources (time, memory) of the request as a string. - * - * @return string - */ - public static function resourceUsage() - { - return sprintf( - 'Time: %s, Memory: %4.2fMb', - self::timeSinceStartOfRequest(), - memory_get_peak_usage(TRUE) / 1048576 - ); - } -} - -if (isset($_SERVER['REQUEST_TIME_FLOAT'])) { - PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME_FLOAT']; -} - -else { - PHP_Timer::$requestTime = microtime(TRUE); -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHP_TokenStream - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -/** - * A caching factory for token stream objects. - * - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -class PHP_Token_Stream_CachingFactory -{ - /** - * @var array - */ - protected static $cache = array(); - - /** - * @param string $filename - * @return PHP_Token_Stream - */ - public static function get($filename) - { - if (!isset(self::$cache[$filename])) { - self::$cache[$filename] = new PHP_Token_Stream($filename); - } - - return self::$cache[$filename]; - } - - /** - * @param string $filename - */ - public static function clear($filename = NULL) - { - if (is_string($filename)) { - unset(self::$cache[$filename]); - } else { - self::$cache = array(); - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHP_TokenStream - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -/** - * A stream of PHP tokens. - * - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator -{ - /** - * @var array - */ - protected static $customTokens = array( - '(' => 'PHP_Token_OPEN_BRACKET', - ')' => 'PHP_Token_CLOSE_BRACKET', - '[' => 'PHP_Token_OPEN_SQUARE', - ']' => 'PHP_Token_CLOSE_SQUARE', - '{' => 'PHP_Token_OPEN_CURLY', - '}' => 'PHP_Token_CLOSE_CURLY', - ';' => 'PHP_Token_SEMICOLON', - '.' => 'PHP_Token_DOT', - ',' => 'PHP_Token_COMMA', - '=' => 'PHP_Token_EQUAL', - '<' => 'PHP_Token_LT', - '>' => 'PHP_Token_GT', - '+' => 'PHP_Token_PLUS', - '-' => 'PHP_Token_MINUS', - '*' => 'PHP_Token_MULT', - '/' => 'PHP_Token_DIV', - '?' => 'PHP_Token_QUESTION_MARK', - '!' => 'PHP_Token_EXCLAMATION_MARK', - ':' => 'PHP_Token_COLON', - '"' => 'PHP_Token_DOUBLE_QUOTES', - '@' => 'PHP_Token_AT', - '&' => 'PHP_Token_AMPERSAND', - '%' => 'PHP_Token_PERCENT', - '|' => 'PHP_Token_PIPE', - '$' => 'PHP_Token_DOLLAR', - '^' => 'PHP_Token_CARET', - '~' => 'PHP_Token_TILDE', - '`' => 'PHP_Token_BACKTICK' - ); - - /** - * @var string - */ - protected $filename; - - /** - * @var array - */ - protected $tokens = array(); - - /** - * @var integer - */ - protected $position = 0; - - /** - * @var array - */ - protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0); - - /** - * @var array - */ - protected $classes; - - /** - * @var array - */ - protected $functions; - - /** - * @var array - */ - protected $includes; - - /** - * @var array - */ - protected $interfaces; - - /** - * @var array - */ - protected $traits; - - /** - * @var array - */ - protected $lineToFunctionMap = array(); - - /** - * Constructor. - * - * @param string $sourceCode - */ - public function __construct($sourceCode) - { - if (is_file($sourceCode)) { - $this->filename = $sourceCode; - $sourceCode = file_get_contents($sourceCode); - } - - $this->scan($sourceCode); - } - - /** - * Destructor. - */ - public function __destruct() - { - $this->tokens = array(); - } - - /** - * @return string - */ - public function __toString() - { - $buffer = ''; - - foreach ($this as $token) { - $buffer .= $token; - } - - return $buffer; - } - - /** - * @return string - * @since Method available since Release 1.1.0 - */ - public function getFilename() - { - return $this->filename; - } - - /** - * Scans the source for sequences of characters and converts them into a - * stream of tokens. - * - * @param string $sourceCode - */ - protected function scan($sourceCode) - { - $line = 1; - $tokens = token_get_all($sourceCode); - $numTokens = count($tokens); - - $lastNonWhitespaceTokenWasDoubleColon = FALSE; - - for ($i = 0; $i < $numTokens; ++$i) { - $token = $tokens[$i]; - unset($tokens[$i]); - - if (is_array($token)) { - $name = substr(token_name($token[0]), 2); - $text = $token[1]; - - if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { - $name = 'CLASS_NAME_CONSTANT'; - } - - $tokenClass = 'PHP_Token_' . $name; - } else { - $text = $token; - $tokenClass = self::$customTokens[$token]; - } - - $this->tokens[] = new $tokenClass($text, $line, $this, $i); - $lines = substr_count($text, "\n"); - $line += $lines; - - if ($tokenClass == 'PHP_Token_HALT_COMPILER') { - break; - } - - else if ($tokenClass == 'PHP_Token_COMMENT' || - $tokenClass == 'PHP_Token_DOC_COMMENT') { - $this->linesOfCode['cloc'] += $lines + 1; - } - - if ($name == 'DOUBLE_COLON') { - $lastNonWhitespaceTokenWasDoubleColon = TRUE; - } - - else if ($name != 'WHITESPACE') { - $lastNonWhitespaceTokenWasDoubleColon = FALSE; - } - } - - $this->linesOfCode['loc'] = substr_count($sourceCode, "\n"); - $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - - $this->linesOfCode['cloc']; - } - - /** - * @return integer - */ - public function count() - { - return count($this->tokens); - } - - /** - * @return PHP_Token[] - */ - public function tokens() - { - return $this->tokens; - } - - /** - * @return array - */ - public function getClasses() - { - if ($this->classes !== NULL) { - return $this->classes; - } - - $this->parse(); - - return $this->classes; - } - - /** - * @return array - */ - public function getFunctions() - { - if ($this->functions !== NULL) { - return $this->functions; - } - - $this->parse(); - - return $this->functions; - } - - /** - * @return array - */ - public function getInterfaces() - { - if ($this->interfaces !== NULL) { - return $this->interfaces; - } - - $this->parse(); - - return $this->interfaces; - } - - /** - * @return array - * @since Method available since Release 1.1.0 - */ - public function getTraits() - { - if ($this->traits !== NULL) { - return $this->traits; - } - - $this->parse(); - - return $this->traits; - } - - /** - * Gets the names of all files that have been included - * using include(), include_once(), require() or require_once(). - * - * Parameter $categorize set to TRUE causing this function to return a - * multi-dimensional array with categories in the keys of the first dimension - * and constants and their values in the second dimension. - * - * Parameter $category allow to filter following specific inclusion type - * - * @param bool $categorize OPTIONAL - * @param string $category OPTIONAL Either 'require_once', 'require', - * 'include_once', 'include'. - * @return array - * @since Method available since Release 1.1.0 - */ - public function getIncludes($categorize = FALSE, $category = NULL) - { - if ($this->includes === NULL) { - $this->includes = array( - 'require_once' => array(), - 'require' => array(), - 'include_once' => array(), - 'include' => array() - ); - - foreach ($this->tokens as $token) { - switch (get_class($token)) { - case 'PHP_Token_REQUIRE_ONCE': - case 'PHP_Token_REQUIRE': - case 'PHP_Token_INCLUDE_ONCE': - case 'PHP_Token_INCLUDE': { - $this->includes[$token->getType()][] = $token->getName(); - } - break; - } - } - } - - if (isset($this->includes[$category])) { - $includes = $this->includes[$category]; - } - - else if ($categorize === FALSE) { - $includes = array_merge( - $this->includes['require_once'], - $this->includes['require'], - $this->includes['include_once'], - $this->includes['include'] - ); - } else { - $includes = $this->includes; - } - - return $includes; - } - - /** - * Returns the name of the function or method a line belongs to. - * - * @return string or null if the line is not in a function or method - * @since Method available since Release 1.2.0 - */ - public function getFunctionForLine($line) - { - $this->parse(); - - if (isset($this->lineToFunctionMap[$line])) { - return $this->lineToFunctionMap[$line]; - } - } - - protected function parse() - { - $this->interfaces = array(); - $this->classes = array(); - $this->traits = array(); - $this->functions = array(); - $class = FALSE; - $classEndLine = FALSE; - $trait = FALSE; - $traitEndLine = FALSE; - $interface = FALSE; - $interfaceEndLine = FALSE; - - foreach ($this->tokens as $token) { - switch (get_class($token)) { - case 'PHP_Token_HALT_COMPILER': { - return; - } - break; - - case 'PHP_Token_INTERFACE': { - $interface = $token->getName(); - $interfaceEndLine = $token->getEndLine(); - - $this->interfaces[$interface] = array( - 'methods' => array(), - 'parent' => $token->getParent(), - 'keywords' => $token->getKeywords(), - 'docblock' => $token->getDocblock(), - 'startLine' => $token->getLine(), - 'endLine' => $interfaceEndLine, - 'package' => $token->getPackage(), - 'file' => $this->filename - ); - } - break; - - case 'PHP_Token_CLASS': - case 'PHP_Token_TRAIT': { - $tmp = array( - 'methods' => array(), - 'parent' => $token->getParent(), - 'interfaces'=> $token->getInterfaces(), - 'keywords' => $token->getKeywords(), - 'docblock' => $token->getDocblock(), - 'startLine' => $token->getLine(), - 'endLine' => $token->getEndLine(), - 'package' => $token->getPackage(), - 'file' => $this->filename - ); - - if ($token instanceof PHP_Token_CLASS) { - $class = $token->getName(); - $classEndLine = $token->getEndLine(); - $this->classes[$class] = $tmp; - } else { - $trait = $token->getName(); - $traitEndLine = $token->getEndLine(); - $this->traits[$trait] = $tmp; - } - } - break; - - case 'PHP_Token_FUNCTION': { - $name = $token->getName(); - $tmp = array( - 'docblock' => $token->getDocblock(), - 'keywords' => $token->getKeywords(), - 'visibility'=> $token->getVisibility(), - 'signature' => $token->getSignature(), - 'startLine' => $token->getLine(), - 'endLine' => $token->getEndLine(), - 'ccn' => $token->getCCN(), - 'file' => $this->filename - ); - - if ($class === FALSE && - $trait === FALSE && - $interface === FALSE) { - $this->functions[$name] = $tmp; - - $this->addFunctionToMap( - $name, $tmp['startLine'], $tmp['endLine'] - ); - } - - else if ($class !== FALSE) { - $this->classes[$class]['methods'][$name] = $tmp; - - $this->addFunctionToMap( - $class . '::' . $name, - $tmp['startLine'], - $tmp['endLine'] - ); - } - - else if ($trait !== FALSE) { - $this->traits[$trait]['methods'][$name] = $tmp; - - $this->addFunctionToMap( - $trait . '::' . $name, - $tmp['startLine'], - $tmp['endLine'] - ); - } - - else { - $this->interfaces[$interface]['methods'][$name] = $tmp; - } - } - break; - - case 'PHP_Token_CLOSE_CURLY': { - if ($classEndLine !== FALSE && - $classEndLine == $token->getLine()) { - $class = FALSE; - $classEndLine = FALSE; - } - - else if ($traitEndLine !== FALSE && - $traitEndLine == $token->getLine()) { - $trait = FALSE; - $traitEndLine = FALSE; - } - - else if ($interfaceEndLine !== FALSE && - $interfaceEndLine == $token->getLine()) { - $interface = FALSE; - $interfaceEndLine = FALSE; - } - } - break; - } - } - } - - /** - * @return array - */ - public function getLinesOfCode() - { - return $this->linesOfCode; - } - - /** - */ - public function rewind() - { - $this->position = 0; - } - - /** - * @return boolean - */ - public function valid() - { - return isset($this->tokens[$this->position]); - } - - /** - * @return integer - */ - public function key() - { - return $this->position; - } - - /** - * @return PHP_Token - */ - public function current() - { - return $this->tokens[$this->position]; - } - - /** - */ - public function next() - { - $this->position++; - } - - /** - * @param mixed $offset - */ - public function offsetExists($offset) - { - return isset($this->tokens[$offset]); - } - - /** - * @param mixed $offset - * @return mixed - */ - public function offsetGet($offset) - { - return $this->tokens[$offset]; - } - - /** - * @param mixed $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) - { - $this->tokens[$offset] = $value; - } - - /** - * @param mixed $offset - */ - public function offsetUnset($offset) - { - unset($this->tokens[$offset]); - } - - /** - * Seek to an absolute position. - * - * @param integer $position - * @throws OutOfBoundsException - */ - public function seek($position) - { - $this->position = $position; - - if (!$this->valid()) { - throw new OutOfBoundsException('Invalid seek position'); - } - } - - private function addFunctionToMap($name, $startLine, $endLine) - { - for ($line = $startLine; $line <= $endLine; $line++) { - $this->lineToFunctionMap[$line] = $name; - } - } -} -. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHP_TokenStream - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @since File available since Release 1.0.0 - */ - -/** - * A PHP token. - * - * @author Sebastian Bergmann - * @copyright 2009-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @version Release: @package_version@ - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -abstract class PHP_Token -{ - /** - * @var string - */ - protected $text; - - /** - * @var integer - */ - protected $line; - - /** - * @var PHP_Token_Stream - */ - protected $tokenStream; - - /** - * @var integer - */ - protected $id; - - /** - * Constructor. - * - * @param string $text - * @param integer $line - * @param PHP_Token_Stream $tokenStream - * @param integer $id - */ - public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id) - { - $this->text = $text; - $this->line = $line; - $this->tokenStream = $tokenStream; - $this->id = $id; - } - - /** - * @return string - */ - public function __toString() - { - return $this->text; - } - - /** - * @return integer - */ - public function getLine() - { - return $this->line; - } -} - -abstract class PHP_TokenWithScope extends PHP_Token -{ - protected $endTokenId; - - /** - * Get the docblock for this token - * - * This method will fetch the docblock belonging to the current token. The - * docblock must be placed on the line directly above the token to be - * recognized. - * - * @return string|null Returns the docblock as a string if found - */ - public function getDocblock() - { - $tokens = $this->tokenStream->tokens(); - $currentLineNumber = $tokens[$this->id]->getLine(); - $prevLineNumber = $currentLineNumber - 1; - - for ($i = $this->id - 1; $i; $i--) { - if (!isset($tokens[$i])) { - return; - } - - if ($tokens[$i] instanceof PHP_Token_FUNCTION || - $tokens[$i] instanceof PHP_Token_CLASS || - $tokens[$i] instanceof PHP_Token_TRAIT) { - // Some other trait, class or function, no docblock can be - // used for the current token - break; - } - - $line = $tokens[$i]->getLine(); - - if ($line == $currentLineNumber || - ($line == $prevLineNumber && - $tokens[$i] instanceof PHP_Token_WHITESPACE)) { - continue; - } - - if ($line < $currentLineNumber && - !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) { - break; - } - - return (string)$tokens[$i]; - } - } - - public function getEndTokenId() - { - $block = 0; - $i = $this->id; - $tokens = $this->tokenStream->tokens(); - - while ($this->endTokenId === NULL && isset($tokens[$i])) { - if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY || - $tokens[$i] instanceof PHP_Token_CURLY_OPEN) { - $block++; - } - - else if ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) { - $block--; - - if ($block === 0) { - $this->endTokenId = $i; - } - } - - else if (($this instanceof PHP_Token_FUNCTION || - $this instanceof PHP_Token_NAMESPACE) && - $tokens[$i] instanceof PHP_Token_SEMICOLON) { - if ($block === 0) { - $this->endTokenId = $i; - } - } - - $i++; - } - - if ($this->endTokenId === NULL) { - $this->endTokenId = $this->id; - } - - return $this->endTokenId; - } - - public function getEndLine() - { - return $this->tokenStream[$this->getEndTokenId()]->getLine(); - } - -} - -abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope { - - public function getVisibility() - { - $tokens = $this->tokenStream->tokens(); - - for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { - if (isset($tokens[$i]) && - ($tokens[$i] instanceof PHP_Token_PRIVATE || - $tokens[$i] instanceof PHP_Token_PROTECTED || - $tokens[$i] instanceof PHP_Token_PUBLIC)) { - return strtolower( - str_replace('PHP_Token_', '', get_class($tokens[$i])) - ); - } - if (isset($tokens[$i]) && - !($tokens[$i] instanceof PHP_Token_STATIC || - $tokens[$i] instanceof PHP_Token_FINAL || - $tokens[$i] instanceof PHP_Token_ABSTRACT)) { - // no keywords; stop visibility search - break; - } - } - } - - public function getKeywords() - { - $keywords = array(); - $tokens = $this->tokenStream->tokens(); - - for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { - if (isset($tokens[$i]) && - ($tokens[$i] instanceof PHP_Token_PRIVATE || - $tokens[$i] instanceof PHP_Token_PROTECTED || - $tokens[$i] instanceof PHP_Token_PUBLIC)) { - continue; - } - - if (isset($tokens[$i]) && - ($tokens[$i] instanceof PHP_Token_STATIC || - $tokens[$i] instanceof PHP_Token_FINAL || - $tokens[$i] instanceof PHP_Token_ABSTRACT)) { - $keywords[] = strtolower( - str_replace('PHP_Token_', '', get_class($tokens[$i])) - ); - } - } - - return implode(',', $keywords); - } - -} - -abstract class PHP_Token_Includes extends PHP_Token -{ - protected $name; - protected $type; - - public function getName() - { - if ($this->name !== NULL) { - return $this->name; - } - - $tokens = $this->tokenStream->tokens(); - - if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) { - $this->name = trim($tokens[$this->id+2], "'\""); - $this->type = strtolower( - str_replace('PHP_Token_', '', get_class($tokens[$this->id])) - ); - } - - return $this->name; - } - - public function getType() - { - $this->getName(); - return $this->type; - } -} - -class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {} -class PHP_Token_REQUIRE extends PHP_Token_Includes {} -class PHP_Token_EVAL extends PHP_Token {} -class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {} -class PHP_Token_INCLUDE extends PHP_Token_Includes {} -class PHP_Token_LOGICAL_OR extends PHP_Token {} -class PHP_Token_LOGICAL_XOR extends PHP_Token {} -class PHP_Token_LOGICAL_AND extends PHP_Token {} -class PHP_Token_PRINT extends PHP_Token {} -class PHP_Token_SR_EQUAL extends PHP_Token {} -class PHP_Token_SL_EQUAL extends PHP_Token {} -class PHP_Token_XOR_EQUAL extends PHP_Token {} -class PHP_Token_OR_EQUAL extends PHP_Token {} -class PHP_Token_AND_EQUAL extends PHP_Token {} -class PHP_Token_MOD_EQUAL extends PHP_Token {} -class PHP_Token_CONCAT_EQUAL extends PHP_Token {} -class PHP_Token_DIV_EQUAL extends PHP_Token {} -class PHP_Token_MUL_EQUAL extends PHP_Token {} -class PHP_Token_MINUS_EQUAL extends PHP_Token {} -class PHP_Token_PLUS_EQUAL extends PHP_Token {} -class PHP_Token_BOOLEAN_OR extends PHP_Token {} -class PHP_Token_BOOLEAN_AND extends PHP_Token {} -class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {} -class PHP_Token_IS_IDENTICAL extends PHP_Token {} -class PHP_Token_IS_NOT_EQUAL extends PHP_Token {} -class PHP_Token_IS_EQUAL extends PHP_Token {} -class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {} -class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {} -class PHP_Token_SR extends PHP_Token {} -class PHP_Token_SL extends PHP_Token {} -class PHP_Token_INSTANCEOF extends PHP_Token {} -class PHP_Token_UNSET_CAST extends PHP_Token {} -class PHP_Token_BOOL_CAST extends PHP_Token {} -class PHP_Token_OBJECT_CAST extends PHP_Token {} -class PHP_Token_ARRAY_CAST extends PHP_Token {} -class PHP_Token_STRING_CAST extends PHP_Token {} -class PHP_Token_DOUBLE_CAST extends PHP_Token {} -class PHP_Token_INT_CAST extends PHP_Token {} -class PHP_Token_DEC extends PHP_Token {} -class PHP_Token_INC extends PHP_Token {} -class PHP_Token_CLONE extends PHP_Token {} -class PHP_Token_NEW extends PHP_Token {} -class PHP_Token_EXIT extends PHP_Token {} -class PHP_Token_IF extends PHP_Token {} -class PHP_Token_ELSEIF extends PHP_Token {} -class PHP_Token_ELSE extends PHP_Token {} -class PHP_Token_ENDIF extends PHP_Token {} -class PHP_Token_LNUMBER extends PHP_Token {} -class PHP_Token_DNUMBER extends PHP_Token {} -class PHP_Token_STRING extends PHP_Token {} -class PHP_Token_STRING_VARNAME extends PHP_Token {} -class PHP_Token_VARIABLE extends PHP_Token {} -class PHP_Token_NUM_STRING extends PHP_Token {} -class PHP_Token_INLINE_HTML extends PHP_Token {} -class PHP_Token_CHARACTER extends PHP_Token {} -class PHP_Token_BAD_CHARACTER extends PHP_Token {} -class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {} -class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {} -class PHP_Token_ECHO extends PHP_Token {} -class PHP_Token_DO extends PHP_Token {} -class PHP_Token_WHILE extends PHP_Token {} -class PHP_Token_ENDWHILE extends PHP_Token {} -class PHP_Token_FOR extends PHP_Token {} -class PHP_Token_ENDFOR extends PHP_Token {} -class PHP_Token_FOREACH extends PHP_Token {} -class PHP_Token_ENDFOREACH extends PHP_Token {} -class PHP_Token_DECLARE extends PHP_Token {} -class PHP_Token_ENDDECLARE extends PHP_Token {} -class PHP_Token_AS extends PHP_Token {} -class PHP_Token_SWITCH extends PHP_Token {} -class PHP_Token_ENDSWITCH extends PHP_Token {} -class PHP_Token_CASE extends PHP_Token {} -class PHP_Token_DEFAULT extends PHP_Token {} -class PHP_Token_BREAK extends PHP_Token {} -class PHP_Token_CONTINUE extends PHP_Token {} -class PHP_Token_GOTO extends PHP_Token {} -class PHP_Token_CALLABLE extends PHP_Token {} -class PHP_Token_INSTEADOF extends PHP_Token {} - -class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility -{ - protected $arguments; - protected $ccn; - protected $name; - protected $signature; - - public function getArguments() - { - if ($this->arguments !== NULL) { - return $this->arguments; - } - - $this->arguments = array(); - $tokens = $this->tokenStream->tokens(); - $typeHint = NULL; - - // Search for first token inside brackets - $i = $this->id + 2; - while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) { - $i++; - } - - while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) { - if ($tokens[$i] instanceof PHP_Token_STRING) { - $typeHint = (string)$tokens[$i]; - } - - else if ($tokens[$i] instanceof PHP_Token_VARIABLE) { - $this->arguments[(string)$tokens[$i]] = $typeHint; - $typeHint = NULL; - } - - $i++; - } - - return $this->arguments; - } - - public function getName() - { - if ($this->name !== NULL) { - return $this->name; - } - - $tokens = $this->tokenStream->tokens(); - - for ($i = $this->id + 1; $i < count($tokens); $i++) { - if ($tokens[$i] instanceof PHP_Token_STRING) { - $this->name = (string)$tokens[$i]; - break; - } - - else if ($tokens[$i] instanceof PHP_Token_AMPERSAND && - $tokens[$i+1] instanceof PHP_Token_STRING) { - $this->name = (string)$tokens[$i+1]; - break; - } - - else if ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) { - $this->name = 'anonymous function'; - break; - } - } - - if ($this->name != 'anonymous function') { - for ($i = $this->id; $i; --$i) { - if ($tokens[$i] instanceof PHP_Token_NAMESPACE) { - $this->name = $tokens[$i]->getName() . '\\' . $this->name; - break; - } - - if ($tokens[$i] instanceof PHP_Token_INTERFACE) { - break; - } - } - } - - return $this->name; - } - - public function getCCN() - { - if ($this->ccn !== NULL) { - return $this->ccn; - } - - $this->ccn = 1; - $end = $this->getEndTokenId(); - $tokens = $this->tokenStream->tokens(); - - for ($i = $this->id; $i <= $end; $i++) { - switch (get_class($tokens[$i])) { - case 'PHP_Token_IF': - case 'PHP_Token_ELSEIF': - case 'PHP_Token_FOR': - case 'PHP_Token_FOREACH': - case 'PHP_Token_WHILE': - case 'PHP_Token_CASE': - case 'PHP_Token_CATCH': - case 'PHP_Token_BOOLEAN_AND': - case 'PHP_Token_LOGICAL_AND': - case 'PHP_Token_BOOLEAN_OR': - case 'PHP_Token_LOGICAL_OR': - case 'PHP_Token_QUESTION_MARK': { - $this->ccn++; - } - break; - } - } - - return $this->ccn; - } - - public function getSignature() - { - if ($this->signature !== NULL) { - return $this->signature; - } - - if ($this->getName() == 'anonymous function') { - $this->signature = 'anonymous function'; - $i = $this->id + 1; - } else { - $this->signature = ''; - $i = $this->id + 2; - } - - $tokens = $this->tokenStream->tokens(); - - while (isset($tokens[$i]) && - !$tokens[$i] instanceof PHP_Token_OPEN_CURLY && - !$tokens[$i] instanceof PHP_Token_SEMICOLON) { - $this->signature .= $tokens[$i++]; - } - - $this->signature = trim($this->signature); - - return $this->signature; - } -} - -class PHP_Token_CONST extends PHP_Token {} -class PHP_Token_RETURN extends PHP_Token {} -class PHP_Token_YIELD extends PHP_Token {} -class PHP_Token_TRY extends PHP_Token {} -class PHP_Token_CATCH extends PHP_Token {} -class PHP_Token_FINALLY extends PHP_Token {} -class PHP_Token_THROW extends PHP_Token {} -class PHP_Token_USE extends PHP_Token {} -class PHP_Token_GLOBAL extends PHP_Token {} -class PHP_Token_PUBLIC extends PHP_Token {} -class PHP_Token_PROTECTED extends PHP_Token {} -class PHP_Token_PRIVATE extends PHP_Token {} -class PHP_Token_FINAL extends PHP_Token {} -class PHP_Token_ABSTRACT extends PHP_Token {} -class PHP_Token_STATIC extends PHP_Token {} -class PHP_Token_VAR extends PHP_Token {} -class PHP_Token_UNSET extends PHP_Token {} -class PHP_Token_ISSET extends PHP_Token {} -class PHP_Token_EMPTY extends PHP_Token {} -class PHP_Token_HALT_COMPILER extends PHP_Token {} - -class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility -{ - protected $interfaces; - - public function getName() - { - return (string)$this->tokenStream[$this->id + 2]; - } - - public function hasParent() - { - return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS; - } - - public function getPackage() - { - $className = $this->getName(); - $docComment = $this->getDocblock(); - - $result = array( - 'namespace' => '', - 'fullPackage' => '', - 'category' => '', - 'package' => '', - 'subpackage' => '' - ); - - for ($i = $this->id; $i; --$i) { - if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) { - $result['namespace'] = $this->tokenStream[$i]->getName(); - break; - } - } - - if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) { - $result['category'] = $matches[1]; - } - - if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) { - $result['package'] = $matches[1]; - $result['fullPackage'] = $matches[1]; - } - - if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) { - $result['subpackage'] = $matches[1]; - $result['fullPackage'] .= '.' . $matches[1]; - } - - if (empty($result['fullPackage'])) { - $result['fullPackage'] = $this->arrayToName( - explode('_', str_replace('\\', '_', $className)), '.' - ); - } - - return $result; - } - - protected function arrayToName(array $parts, $join = '\\') - { - $result = ''; - - if (count($parts) > 1) { - array_pop($parts); - - $result = join($join, $parts); - } - - return $result; - } - - public function getParent() - { - if (!$this->hasParent()) { - return FALSE; - } - - $i = $this->id + 6; - $tokens = $this->tokenStream->tokens(); - $className = (string)$tokens[$i]; - - while (isset($tokens[$i+1]) && - !$tokens[$i+1] instanceof PHP_Token_WHITESPACE) { - $className .= (string)$tokens[++$i]; - } - - return $className; - } - - public function hasInterfaces() - { - return (isset($this->tokenStream[$this->id + 4]) && - $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) || - (isset($this->tokenStream[$this->id + 8]) && - $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS); - } - - public function getInterfaces() - { - if ($this->interfaces !== NULL) { - return $this->interfaces; - } - - if (!$this->hasInterfaces()) { - return ($this->interfaces = FALSE); - } - - if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) { - $i = $this->id + 3; - } else { - $i = $this->id + 7; - } - - $tokens = $this->tokenStream->tokens(); - - while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) { - $i++; - - if ($tokens[$i] instanceof PHP_Token_STRING) { - $this->interfaces[] = (string)$tokens[$i]; - } - } - - return $this->interfaces; - } -} - -class PHP_Token_CLASS extends PHP_Token_INTERFACE {} -class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token {} -class PHP_Token_TRAIT extends PHP_Token_INTERFACE {} -class PHP_Token_EXTENDS extends PHP_Token {} -class PHP_Token_IMPLEMENTS extends PHP_Token {} -class PHP_Token_OBJECT_OPERATOR extends PHP_Token {} -class PHP_Token_DOUBLE_ARROW extends PHP_Token {} -class PHP_Token_LIST extends PHP_Token {} -class PHP_Token_ARRAY extends PHP_Token {} -class PHP_Token_CLASS_C extends PHP_Token {} -class PHP_Token_TRAIT_C extends PHP_Token {} -class PHP_Token_METHOD_C extends PHP_Token {} -class PHP_Token_FUNC_C extends PHP_Token {} -class PHP_Token_LINE extends PHP_Token {} -class PHP_Token_FILE extends PHP_Token {} -class PHP_Token_COMMENT extends PHP_Token {} -class PHP_Token_DOC_COMMENT extends PHP_Token {} -class PHP_Token_OPEN_TAG extends PHP_Token {} -class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {} -class PHP_Token_CLOSE_TAG extends PHP_Token {} -class PHP_Token_WHITESPACE extends PHP_Token {} -class PHP_Token_START_HEREDOC extends PHP_Token {} -class PHP_Token_END_HEREDOC extends PHP_Token {} -class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {} -class PHP_Token_CURLY_OPEN extends PHP_Token {} -class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {} - -class PHP_Token_NAMESPACE extends PHP_TokenWithScope -{ - public function getName() - { - $tokens = $this->tokenStream->tokens(); - $namespace = (string)$tokens[$this->id+2]; - - for ($i = $this->id + 3; ; $i += 2) { - if (isset($tokens[$i]) && - $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) { - $namespace .= '\\' . $tokens[$i+1]; - } else { - break; - } - } - - return $namespace; - } -} - -class PHP_Token_NS_C extends PHP_Token {} -class PHP_Token_DIR extends PHP_Token {} -class PHP_Token_NS_SEPARATOR extends PHP_Token {} -class PHP_Token_DOUBLE_COLON extends PHP_Token {} -class PHP_Token_OPEN_BRACKET extends PHP_Token {} -class PHP_Token_CLOSE_BRACKET extends PHP_Token {} -class PHP_Token_OPEN_SQUARE extends PHP_Token {} -class PHP_Token_CLOSE_SQUARE extends PHP_Token {} -class PHP_Token_OPEN_CURLY extends PHP_Token {} -class PHP_Token_CLOSE_CURLY extends PHP_Token {} -class PHP_Token_SEMICOLON extends PHP_Token {} -class PHP_Token_DOT extends PHP_Token {} -class PHP_Token_COMMA extends PHP_Token {} -class PHP_Token_EQUAL extends PHP_Token {} -class PHP_Token_LT extends PHP_Token {} -class PHP_Token_GT extends PHP_Token {} -class PHP_Token_PLUS extends PHP_Token {} -class PHP_Token_MINUS extends PHP_Token {} -class PHP_Token_MULT extends PHP_Token {} -class PHP_Token_DIV extends PHP_Token {} -class PHP_Token_QUESTION_MARK extends PHP_Token {} -class PHP_Token_EXCLAMATION_MARK extends PHP_Token {} -class PHP_Token_COLON extends PHP_Token {} -class PHP_Token_DOUBLE_QUOTES extends PHP_Token {} -class PHP_Token_AT extends PHP_Token {} -class PHP_Token_AMPERSAND extends PHP_Token {} -class PHP_Token_PERCENT extends PHP_Token {} -class PHP_Token_PIPE extends PHP_Token {} -class PHP_Token_DOLLAR extends PHP_Token {} -class PHP_Token_CARET extends PHP_Token {} -class PHP_Token_TILDE extends PHP_Token {} -class PHP_Token_BACKTICK extends PHP_Token {} -á3rMEŠ»Ž‚2Xjªx.Ô)ßGBMB \ No newline at end of file