@vituum/vite-plugin-latte 2.0.0-next.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +1 -1
  2. package/index.js +4 -2
  3. package/package.json +11 -9
  4. package/types/index.d.ts +1 -1
  5. package/vendor/autoload.php +1 -4
  6. package/vendor/composer/InstalledVersions.php +36 -2
  7. package/vendor/composer/autoload_classmap.php +14 -15
  8. package/vendor/composer/autoload_psr4.php +2 -0
  9. package/vendor/composer/autoload_static.php +38 -15
  10. package/vendor/composer/installed.json +32 -22
  11. package/vendor/composer/installed.php +12 -12
  12. package/vendor/composer/platform_check.php +4 -5
  13. package/vendor/latte/latte/bin/latte-lint +10 -3
  14. package/vendor/latte/latte/composer.json +16 -6
  15. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +13 -38
  16. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +9 -7
  17. package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
  18. package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +94 -0
  19. package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +10 -0
  20. package/vendor/latte/latte/src/Latte/Compiler/Block.php +4 -6
  21. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +67 -86
  22. package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
  23. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +16 -6
  24. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +25 -12
  25. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
  26. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +5 -4
  27. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +8 -4
  28. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +7 -15
  29. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
  30. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
  31. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +37 -67
  32. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +60 -0
  33. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +70 -0
  34. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
  35. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
  36. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -15
  37. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
  38. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
  39. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
  40. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +6 -22
  41. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +18 -5
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +18 -7
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +5 -4
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +38 -9
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +14 -6
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +12 -4
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +10 -6
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +7 -6
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +10 -4
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +14 -5
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +14 -5
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +6 -3
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +6 -3
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +18 -5
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +14 -4
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +14 -6
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +14 -6
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +14 -15
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +16 -11
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +19 -9
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +33 -8
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +6 -3
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +6 -3
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +29 -41
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +9 -4
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +27 -0
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +9 -6
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +8 -6
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +9 -5
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +6 -4
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +6 -3
  90. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
  91. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/{Expression/NotNode.php → VariadicPlaceholderNode.php} +9 -9
  92. package/vendor/latte/latte/src/Latte/{Essential → Compiler}/Nodes/PrintNode.php +9 -15
  93. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
  94. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
  95. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +6 -4
  96. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +32 -18
  97. package/vendor/latte/latte/src/Latte/Compiler/Position.php +7 -7
  98. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +72 -104
  99. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +17 -16
  100. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +11 -8
  101. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +28 -23
  102. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +360 -336
  103. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +49 -38
  104. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +37 -12
  105. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +35 -21
  106. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +121 -71
  107. package/vendor/latte/latte/src/Latte/Compiler/Token.php +79 -70
  108. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +21 -14
  109. package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
  110. package/vendor/latte/latte/src/Latte/Engine.php +147 -188
  111. package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +5 -7
  112. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +5 -5
  113. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +5 -4
  114. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +155 -127
  115. package/vendor/latte/latte/src/Latte/Essential/Filters.php +99 -44
  116. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +14 -13
  117. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
  118. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
  119. package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +46 -0
  120. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
  121. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +10 -7
  122. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
  123. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
  124. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +8 -9
  125. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
  126. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
  127. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +6 -5
  128. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -7
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +11 -11
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +5 -6
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +26 -27
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +7 -10
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +35 -47
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +4 -5
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +69 -34
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +9 -33
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +7 -4
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +3 -4
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +4 -4
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
  149. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +5 -5
  150. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
  151. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +10 -6
  152. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
  153. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
  154. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
  155. package/vendor/latte/latte/src/Latte/Essential/Passes.php +82 -21
  156. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +2 -4
  157. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
  158. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +24 -28
  159. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +14 -14
  160. package/vendor/latte/latte/src/Latte/Extension.php +12 -6
  161. package/vendor/latte/latte/src/Latte/Feature.php +24 -0
  162. package/vendor/latte/latte/src/Latte/Helpers.php +65 -15
  163. package/vendor/latte/latte/src/Latte/Loader.php +1 -9
  164. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +11 -17
  165. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +7 -21
  166. package/vendor/latte/latte/src/Latte/Policy.php +4 -3
  167. package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
  168. package/vendor/latte/latte/src/Latte/Runtime/Cache.php +143 -0
  169. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +5 -6
  170. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +11 -11
  171. package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +5 -6
  172. package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +91 -0
  173. package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
  174. package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +374 -0
  175. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
  176. package/vendor/latte/latte/src/Latte/Runtime/Template.php +162 -182
  177. package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +108 -0
  178. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +12 -4
  179. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +15 -5
  180. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
  181. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +5 -6
  182. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +14 -4
  183. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
  184. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +8 -6
  185. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +16 -12
  186. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +18 -16
  187. package/vendor/latte/latte/src/Latte/attributes.php +7 -3
  188. package/vendor/latte/latte/src/Latte/exceptions.php +52 -6
  189. package/vendor/latte/latte/src/Tools/Linter.php +74 -28
  190. package/vendor/latte/latte/src/Tools/LinterExtension.php +176 -0
  191. package/vendor/nette/utils/composer.json +15 -5
  192. package/vendor/nette/utils/readme.md +1 -1
  193. package/vendor/nette/utils/src/HtmlStringable.php +4 -1
  194. package/vendor/nette/utils/src/Iterators/CachingIterator.php +10 -25
  195. package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
  196. package/vendor/nette/utils/src/SmartObject.php +3 -0
  197. package/vendor/nette/utils/src/StaticClass.php +1 -11
  198. package/vendor/nette/utils/src/Translator.php +1 -1
  199. package/vendor/nette/utils/src/Utils/ArrayHash.php +6 -10
  200. package/vendor/nette/utils/src/Utils/ArrayList.php +8 -12
  201. package/vendor/nette/utils/src/Utils/Arrays.php +38 -18
  202. package/vendor/nette/utils/src/Utils/Callback.php +13 -8
  203. package/vendor/nette/utils/src/Utils/DateTime.php +95 -26
  204. package/vendor/nette/utils/src/Utils/FileInfo.php +6 -7
  205. package/vendor/nette/utils/src/Utils/FileSystem.php +10 -5
  206. package/vendor/nette/utils/src/Utils/Finder.php +31 -12
  207. package/vendor/nette/utils/src/Utils/Floats.php +1 -0
  208. package/vendor/nette/utils/src/Utils/Helpers.php +22 -2
  209. package/vendor/nette/utils/src/Utils/Html.php +130 -127
  210. package/vendor/nette/utils/src/Utils/Image.php +80 -60
  211. package/vendor/nette/utils/src/Utils/ImageColor.php +5 -0
  212. package/vendor/nette/utils/src/Utils/ImageType.php +2 -0
  213. package/vendor/nette/utils/src/Utils/Iterables.php +41 -7
  214. package/vendor/nette/utils/src/Utils/Json.php +2 -0
  215. package/vendor/nette/utils/src/Utils/ObjectHelpers.php +2 -0
  216. package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
  217. package/vendor/nette/utils/src/Utils/Random.php +2 -0
  218. package/vendor/nette/utils/src/Utils/Reflection.php +22 -15
  219. package/vendor/nette/utils/src/Utils/ReflectionMethod.php +6 -1
  220. package/vendor/nette/utils/src/Utils/Strings.php +62 -57
  221. package/vendor/nette/utils/src/Utils/Type.php +91 -42
  222. package/vendor/nette/utils/src/Utils/Validators.php +9 -7
  223. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +0 -101
  224. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +0 -15
  225. package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +0 -129
  226. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +0 -36
  227. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +0 -39
  228. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +0 -42
  229. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallableNode.php +0 -57
  230. package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
  231. package/vendor/latte/latte/src/Latte/Runtime/Filters.php +0 -283
  232. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +0 -29
  233. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +0 -30
  234. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallableNode.php +0 -30
@@ -10,6 +10,8 @@ declare(strict_types=1);
10
10
  namespace Nette\Utils;
11
11
 
12
12
  use Nette;
13
+ use function is_array, is_int, is_string;
14
+ use const IMG_BMP, IMG_FLIP_BOTH, IMG_FLIP_HORIZONTAL, IMG_FLIP_VERTICAL, IMG_GIF, IMG_JPG, IMG_PNG, IMG_WEBP, PATHINFO_EXTENSION;
13
15
 
14
16
 
15
17
  /**
@@ -22,7 +24,7 @@ use Nette;
22
24
  * $image->send();
23
25
  * </code>
24
26
  *
25
- * @method Image affine(array $affine, ?array $clip = null)
27
+ * @method Image affine(array<int, float|int> $affine, ?array{x: int, y: int, width: int, height: int} $clip = null)
26
28
  * @method void alphaBlending(bool $enable)
27
29
  * @method void antialias(bool $enable)
28
30
  * @method void arc(int $centerX, int $centerY, int $width, int $height, int $startAngle, int $endAngle, ImageColor $color)
@@ -39,51 +41,51 @@ use Nette;
39
41
  * @method int colorResolve(int $red, int $green, int $blue)
40
42
  * @method int colorResolveAlpha(int $red, int $green, int $blue, int $alpha)
41
43
  * @method void colorSet(int $index, int $red, int $green, int $blue, int $alpha = 0)
42
- * @method array colorsForIndex(int $color)
44
+ * @method array{red: int, green: int, blue: int, alpha: int} colorsForIndex(int $color)
43
45
  * @method int colorsTotal()
44
46
  * @method int colorTransparent(?int $color = null)
45
- * @method void convolution(array $matrix, float $div, float $offset)
47
+ * @method void convolution(array<int, array<int, float>> $matrix, float $div, float $offset)
46
48
  * @method void copy(Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH)
47
49
  * @method void copyMerge(Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH, int $pct)
48
50
  * @method void copyMergeGray(Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH, int $pct)
49
51
  * @method void copyResampled(Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $dstW, int $dstH, int $srcW, int $srcH)
50
52
  * @method void copyResized(Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $dstW, int $dstH, int $srcW, int $srcH)
51
- * @method Image cropAuto(int $mode = IMG_CROP_DEFAULT, float $threshold = .5, ?ImageColor $color = null)
53
+ * @method Image cropAuto(int $mode = 0, float $threshold = .5, ?ImageColor $color = null)
52
54
  * @method void ellipse(int $centerX, int $centerY, int $width, int $height, ImageColor $color)
53
55
  * @method void fill(int $x, int $y, ImageColor $color)
54
56
  * @method void filledArc(int $centerX, int $centerY, int $width, int $height, int $startAngle, int $endAngle, ImageColor $color, int $style)
55
57
  * @method void filledEllipse(int $centerX, int $centerY, int $width, int $height, ImageColor $color)
56
- * @method void filledPolygon(array $points, ImageColor $color)
58
+ * @method void filledPolygon(array<int, int> $points, ImageColor $color)
57
59
  * @method void filledRectangle(int $x1, int $y1, int $x2, int $y2, ImageColor $color)
58
60
  * @method void fillToBorder(int $x, int $y, ImageColor $borderColor, ImageColor $color)
59
61
  * @method void filter(int $filter, ...$args)
60
62
  * @method void flip(int $mode)
61
- * @method array ftText(float $size, float $angle, int $x, int $y, ImageColor $color, string $fontFile, string $text, array $options = [])
63
+ * @method array<int, int> ftText(float $size, float $angle, int $x, int $y, ImageColor $color, string $fontFile, string $text, array<string, mixed> $options = [])
62
64
  * @method void gammaCorrect(float $inputgamma, float $outputgamma)
63
- * @method array getClip()
65
+ * @method array{int, int, int, int} getClip()
64
66
  * @method int getInterpolation()
65
67
  * @method int interlace(?bool $enable = null)
66
68
  * @method bool isTrueColor()
67
69
  * @method void layerEffect(int $effect)
68
70
  * @method void line(int $x1, int $y1, int $x2, int $y2, ImageColor $color)
69
- * @method void openPolygon(array $points, ImageColor $color)
71
+ * @method void openPolygon(array<int, int> $points, ImageColor $color)
70
72
  * @method void paletteCopy(Image $source)
71
73
  * @method void paletteToTrueColor()
72
- * @method void polygon(array $points, ImageColor $color)
74
+ * @method void polygon(array<int, int> $points, ImageColor $color)
73
75
  * @method void rectangle(int $x1, int $y1, int $x2, int $y2, ImageColor $color)
74
76
  * @method mixed resolution(?int $resolutionX = null, ?int $resolutionY = null)
75
77
  * @method Image rotate(float $angle, ImageColor $backgroundColor)
76
78
  * @method void saveAlpha(bool $enable)
77
- * @method Image scale(int $newWidth, int $newHeight = -1, int $mode = IMG_BILINEAR_FIXED)
79
+ * @method Image scale(int $newWidth, int $newHeight = -1, int $mode = 3)
78
80
  * @method void setBrush(Image $brush)
79
81
  * @method void setClip(int $x1, int $y1, int $x2, int $y2)
80
- * @method void setInterpolation(int $method = IMG_BILINEAR_FIXED)
82
+ * @method void setInterpolation(int $method = 3)
81
83
  * @method void setPixel(int $x, int $y, ImageColor $color)
82
- * @method void setStyle(array $style)
84
+ * @method void setStyle(array<int, int> $style)
83
85
  * @method void setThickness(int $thickness)
84
86
  * @method void setTile(Image $tile)
85
87
  * @method void trueColorToPalette(bool $dither, int $ncolors)
86
- * @method array ttfText(float $size, float $angle, int $x, int $y, ImageColor $color, string $fontfile, string $text, array $options = [])
88
+ * @method array<int, int> ttfText(float $size, float $angle, int $x, int $y, ImageColor $color, string $fontfile, string $text, array<string, mixed> $options = [])
87
89
  * @property-read positive-int $width
88
90
  * @property-read positive-int $height
89
91
  * @property-read \GdImage $imageResource
@@ -144,6 +146,7 @@ class Image
144
146
  /**
145
147
  * Returns RGB color (0..255) and transparency (0..127).
146
148
  * @deprecated use ImageColor::rgb()
149
+ * @return array{red: int, green: int, blue: int, alpha: int}
147
150
  */
148
151
  public static function rgb(int $red, int $green, int $blue, int $transparency = 0): array
149
152
  {
@@ -190,6 +193,7 @@ class Image
190
193
  }
191
194
 
192
195
 
196
+ /** @param callable-string $func */
193
197
  private static function invokeSafe(string $func, string $arg, string $message, string $callee): static
194
198
  {
195
199
  $errors = [];
@@ -211,6 +215,7 @@ class Image
211
215
  * Creates a new true color image of the given dimensions. The default color is black.
212
216
  * @param positive-int $width
213
217
  * @param positive-int $height
218
+ * @param ImageColor|array{red: int, green: int, blue: int, alpha?: int}|null $color
214
219
  * @throws Nette\NotSupportedException if gd extension is not loaded
215
220
  */
216
221
  public static function fromBlank(int $width, int $height, ImageColor|array|null $color = null): static
@@ -222,9 +227,9 @@ class Image
222
227
 
223
228
  $image = new static(imagecreatetruecolor($width, $height));
224
229
  if ($color) {
225
- $image->alphablending(false);
226
- $image->filledrectangle(0, 0, $width - 1, $height - 1, $color);
227
- $image->alphablending(true);
230
+ $image->alphaBlending(false);
231
+ $image->filledRectangle(0, 0, $width - 1, $height - 1, self::normalizeColor($color));
232
+ $image->alphaBlending(true);
228
233
  }
229
234
 
230
235
  return $image;
@@ -233,23 +238,27 @@ class Image
233
238
 
234
239
  /**
235
240
  * Returns the type of image from file.
236
- * @return ImageType::*|null
241
+ * @param-out ?int $width
242
+ * @param-out ?int $height
243
+ * @return ?ImageType::*
237
244
  */
238
- public static function detectTypeFromFile(string $file, &$width = null, &$height = null): ?int
245
+ public static function detectTypeFromFile(string $file, mixed &$width = null, mixed &$height = null): ?int
239
246
  {
240
- [$width, $height, $type] = @getimagesize($file); // @ - files smaller than 12 bytes causes read error
241
- return isset(self::Formats[$type]) ? $type : null;
247
+ [$width, $height, $type] = Helpers::falseToNull(@getimagesize($file)); // @ - files smaller than 12 bytes causes read error
248
+ return $type && isset(self::Formats[$type]) ? $type : null;
242
249
  }
243
250
 
244
251
 
245
252
  /**
246
253
  * Returns the type of image from string.
247
- * @return ImageType::*|null
254
+ * @param-out ?int $width
255
+ * @param-out ?int $height
256
+ * @return ?ImageType::*
248
257
  */
249
- public static function detectTypeFromString(string $s, &$width = null, &$height = null): ?int
258
+ public static function detectTypeFromString(string $s, mixed &$width = null, mixed &$height = null): ?int
250
259
  {
251
- [$width, $height, $type] = @getimagesizefromstring($s); // @ - strings smaller than 12 bytes causes read error
252
- return isset(self::Formats[$type]) ? $type : null;
260
+ [$width, $height, $type] = Helpers::falseToNull(@getimagesizefromstring($s)); // @ - strings smaller than 12 bytes causes read error
261
+ return $type && isset(self::Formats[$type]) ? $type : null;
253
262
  }
254
263
 
255
264
 
@@ -312,7 +321,7 @@ class Image
312
321
  }
313
322
 
314
323
 
315
- /** @return ImageType[] */
324
+ /** @return ImageType::*[] */
316
325
  public static function getSupportedTypes(): array
317
326
  {
318
327
  self::ensureExtension();
@@ -384,6 +393,10 @@ class Image
384
393
  public function resize(int|string|null $width, int|string|null $height, int $mode = self::OrSmaller): static
385
394
  {
386
395
  if ($mode & self::Cover) {
396
+ if ($width === null || $height === null) {
397
+ throw new Nette\InvalidArgumentException('Both width and height must be set for Cover mode.');
398
+ }
399
+
387
400
  return $this->resize($width, $height, self::OrBigger)->crop('50%', '50%', $width, $height);
388
401
  }
389
402
 
@@ -417,12 +430,13 @@ class Image
417
430
  /**
418
431
  * Calculates dimensions of resized image. Width and height accept pixels or percent.
419
432
  * @param int-mask-of<self::OrSmaller|self::OrBigger|self::Stretch|self::Cover|self::ShrinkOnly> $mode
433
+ * @return array{int<1, max>, int<1, max>}
420
434
  */
421
435
  public static function calculateSize(
422
436
  int $srcWidth,
423
437
  int $srcHeight,
424
- $newWidth,
425
- $newHeight,
438
+ int|string|null $newWidth,
439
+ int|string|null $newHeight,
426
440
  int $mode = self::OrSmaller,
427
441
  ): array
428
442
  {
@@ -466,19 +480,19 @@ class Image
466
480
  }
467
481
 
468
482
  if ($mode & self::OrBigger) {
469
- $scale = [max($scale)];
483
+ $scale = [max($scale ?: [1])];
470
484
  }
471
485
 
472
486
  if ($mode & self::ShrinkOnly) {
473
487
  $scale[] = 1;
474
488
  }
475
489
 
476
- $scale = min($scale);
490
+ $scale = min($scale ?: [1]);
477
491
  $newWidth = (int) round($srcWidth * $scale);
478
492
  $newHeight = (int) round($srcHeight * $scale);
479
493
  }
480
494
 
481
- return [max($newWidth, 1), max($newHeight, 1)];
495
+ return [max((int) $newWidth, 1), max((int) $newHeight, 1)];
482
496
  }
483
497
 
484
498
 
@@ -493,7 +507,7 @@ class Image
493
507
  $this->image = imagecrop($this->image, $r);
494
508
  imagesavealpha($this->image, true);
495
509
  } else {
496
- $newImage = static::fromBlank($r['width'], $r['height'], ImageColor::rgb(0, 0, 0, 0))->getImageResource();
510
+ $newImage = static::fromBlank(max(1, $r['width']), max(1, $r['height']), ImageColor::rgb(0, 0, 0, 0))->getImageResource();
497
511
  imagecopy($newImage, $this->image, 0, 0, $r['x'], $r['y'], $r['width'], $r['height']);
498
512
  $this->image = $newImage;
499
513
  }
@@ -504,6 +518,7 @@ class Image
504
518
 
505
519
  /**
506
520
  * Calculates dimensions of cutout in image. Arguments accepts pixels or percent.
521
+ * @return array{int, int, int, int}
507
522
  */
508
523
  public static function calculateCutout(
509
524
  int $srcWidth,
@@ -514,21 +529,10 @@ class Image
514
529
  int|string $newHeight,
515
530
  ): array
516
531
  {
517
- if (self::isPercent($newWidth)) {
518
- $newWidth = (int) round($srcWidth / 100 * $newWidth);
519
- }
520
-
521
- if (self::isPercent($newHeight)) {
522
- $newHeight = (int) round($srcHeight / 100 * $newHeight);
523
- }
524
-
525
- if (self::isPercent($left)) {
526
- $left = (int) round(($srcWidth - $newWidth) / 100 * $left);
527
- }
528
-
529
- if (self::isPercent($top)) {
530
- $top = (int) round(($srcHeight - $newHeight) / 100 * $top);
531
- }
532
+ $newWidth = (int) (self::isPercent($newWidth) ? round($srcWidth / 100 * $newWidth) : $newWidth);
533
+ $newHeight = (int) (self::isPercent($newHeight) ? round($srcHeight / 100 * $newHeight) : $newHeight);
534
+ $left = (int) (self::isPercent($left) ? round(($srcWidth - $newWidth) / 100 * $left) : $left);
535
+ $top = (int) (self::isPercent($top) ? round(($srcHeight - $newHeight) / 100 * $top) : $top);
532
536
 
533
537
  if ($left < 0) {
534
538
  $newWidth += $left;
@@ -573,14 +577,8 @@ class Image
573
577
 
574
578
  $width = $image->getWidth();
575
579
  $height = $image->getHeight();
576
-
577
- if (self::isPercent($left)) {
578
- $left = (int) round(($this->getWidth() - $width) / 100 * $left);
579
- }
580
-
581
- if (self::isPercent($top)) {
582
- $top = (int) round(($this->getHeight() - $height) / 100 * $top);
583
- }
580
+ $left = (int) (self::isPercent($left) ? round(($this->getWidth() - $width) / 100 * $left) : $left);
581
+ $top = (int) (self::isPercent($top) ? round(($this->getHeight() - $height) / 100 * $top) : $top);
584
582
 
585
583
  $output = $input = $image->image;
586
584
  if ($opacity < 100) {
@@ -593,7 +591,7 @@ class Image
593
591
  imagealphablending($output, false);
594
592
  if (!$image->isTrueColor()) {
595
593
  $input = $output;
596
- imagefilledrectangle($output, 0, 0, $width, $height, imagecolorallocatealpha($output, 0, 0, 0, 127));
594
+ imagefilledrectangle($output, 0, 0, $width, $height, (int) imagecolorallocatealpha($output, 0, 0, 0, 127));
597
595
  imagecopy($output, $image->image, 0, 0, 0, 0, $width, $height);
598
596
  }
599
597
 
@@ -624,6 +622,8 @@ class Image
624
622
 
625
623
  /**
626
624
  * Calculates the bounding box for a TrueType text. Returns keys left, top, width and height.
625
+ * @param array<string, mixed> $options
626
+ * @return array{left: int, top: int, width: int, height: int}
627
627
  */
628
628
  public static function calculateTextBox(
629
629
  string $text,
@@ -668,7 +668,7 @@ class Image
668
668
 
669
669
  /**
670
670
  * Saves image to the file. Quality is in the range 0..100 for JPEG (default 85), WEBP (default 80) and AVIF (default 30) and 0..9 for PNG (default 9).
671
- * @param ImageType::*|null $type
671
+ * @param ?ImageType::* $type
672
672
  * @throws ImageException
673
673
  */
674
674
  public function save(string $file, ?int $quality = null, ?int $type = null): void
@@ -744,6 +744,7 @@ class Image
744
744
 
745
745
  /**
746
746
  * Call to undefined method.
747
+ * @param mixed[] $args
747
748
  * @throws Nette\MemberAccessException
748
749
  */
749
750
  public function __call(string $name, array $args): mixed
@@ -758,6 +759,7 @@ class Image
758
759
  $args[$key] = $value->getImageResource();
759
760
 
760
761
  } elseif ($value instanceof ImageColor || (is_array($value) && isset($value['red']))) {
762
+ /** @var ImageColor|array{red: int, green: int, blue: int, alpha?: int} $value */
761
763
  $args[$key] = $this->resolveColor($value);
762
764
  }
763
765
  }
@@ -771,12 +773,13 @@ class Image
771
773
 
772
774
  public function __clone()
773
775
  {
774
- ob_start(function () {});
776
+ ob_start(fn() => '');
775
777
  imagepng($this->image, null, 0);
776
- $this->setImageResource(imagecreatefromstring(ob_get_clean()));
778
+ $this->setImageResource(imagecreatefromstring(ob_get_clean()) ?: throw new Nette\ShouldNotHappenException);
777
779
  }
778
780
 
779
781
 
782
+ /** @param-out int|float $num */
780
783
  private static function isPercent(int|string &$num): bool
781
784
  {
782
785
  if (is_string($num) && str_ends_with($num, '%')) {
@@ -794,19 +797,36 @@ class Image
794
797
  /**
795
798
  * Prevents serialization.
796
799
  */
797
- public function __sleep(): array
800
+ public function __serialize(): array
798
801
  {
799
802
  throw new Nette\NotSupportedException('You cannot serialize or unserialize ' . self::class . ' instances.');
800
803
  }
801
804
 
802
805
 
806
+ /**
807
+ * @param ImageColor|array{red: int, green: int, blue: int, alpha?: int} $color
808
+ */
803
809
  public function resolveColor(ImageColor|array $color): int
804
810
  {
805
- $color = $color instanceof ImageColor ? $color->toRGBA() : array_values($color);
811
+ $color = self::normalizeColor($color)->toRGBA();
806
812
  return imagecolorallocatealpha($this->image, ...$color) ?: imagecolorresolvealpha($this->image, ...$color);
807
813
  }
808
814
 
809
815
 
816
+ /** @param ImageColor|array{red: int, green: int, blue: int, alpha?: int} $color */
817
+ private static function normalizeColor(ImageColor|array $color): ImageColor
818
+ {
819
+ return $color instanceof ImageColor
820
+ ? $color
821
+ : ImageColor::rgb(
822
+ $color['red'],
823
+ $color['green'],
824
+ $color['blue'],
825
+ (127 - ($color['alpha'] ?? 0)) / 127,
826
+ );
827
+ }
828
+
829
+
810
830
  private static function ensureExtension(): void
811
831
  {
812
832
  if (!extension_loaded('gd')) {
@@ -10,6 +10,7 @@ declare(strict_types=1);
10
10
  namespace Nette\Utils;
11
11
 
12
12
  use Nette;
13
+ use function hexdec, ltrim, max, min, round, strlen;
13
14
 
14
15
 
15
16
  /**
@@ -63,6 +64,10 @@ class ImageColor
63
64
  }
64
65
 
65
66
 
67
+ /**
68
+ * Returns GD-compatible color array [R, G, B, alpha].
69
+ * @return array{int<0, 255>, int<0, 255>, int<0, 255>, int<0, 127>}
70
+ */
66
71
  public function toRGBA(): array
67
72
  {
68
73
  return [
@@ -9,6 +9,8 @@ declare(strict_types=1);
9
9
 
10
10
  namespace Nette\Utils;
11
11
 
12
+ use const IMAGETYPE_BMP, IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_WEBP;
13
+
12
14
 
13
15
  /**
14
16
  * Type of image file.
@@ -10,6 +10,7 @@ declare(strict_types=1);
10
10
  namespace Nette\Utils;
11
11
 
12
12
  use Nette;
13
+ use function is_array;
13
14
 
14
15
 
15
16
  /**
@@ -21,6 +22,7 @@ final class Iterables
21
22
 
22
23
  /**
23
24
  * Tests for the presence of value.
25
+ * @param iterable<mixed> $iterable
24
26
  */
25
27
  public static function contains(iterable $iterable, mixed $value): bool
26
28
  {
@@ -35,6 +37,7 @@ final class Iterables
35
37
 
36
38
  /**
37
39
  * Tests for the presence of key.
40
+ * @param iterable<mixed> $iterable
38
41
  */
39
42
  public static function containsKey(iterable $iterable, mixed $key): bool
40
43
  {
@@ -51,9 +54,11 @@ final class Iterables
51
54
  * Returns the first item (matching the specified predicate if given). If there is no such item, it returns result of invoking $else or null.
52
55
  * @template K
53
56
  * @template V
57
+ * @template E
54
58
  * @param iterable<K, V> $iterable
55
59
  * @param ?callable(V, K, iterable<K, V>): bool $predicate
56
- * @return ?V
60
+ * @param ?callable(): E $else
61
+ * @return ($else is null ? ?V : V|E)
57
62
  */
58
63
  public static function first(iterable $iterable, ?callable $predicate = null, ?callable $else = null): mixed
59
64
  {
@@ -70,9 +75,11 @@ final class Iterables
70
75
  * Returns the key of first item (matching the specified predicate if given). If there is no such item, it returns result of invoking $else or null.
71
76
  * @template K
72
77
  * @template V
78
+ * @template E
73
79
  * @param iterable<K, V> $iterable
74
80
  * @param ?callable(V, K, iterable<K, V>): bool $predicate
75
- * @return ?K
81
+ * @param ?callable(): E $else
82
+ * @return ($else is null ? ?K : K|E)
76
83
  */
77
84
  public static function firstKey(iterable $iterable, ?callable $predicate = null, ?callable $else = null): mixed
78
85
  {
@@ -160,11 +167,11 @@ final class Iterables
160
167
  * Iterator that transforms keys and values by calling $transformer. If it returns null, the element is skipped.
161
168
  * @template K
162
169
  * @template V
163
- * @template ResV
164
170
  * @template ResK
171
+ * @template ResV
165
172
  * @param iterable<K, V> $iterable
166
- * @param callable(V, K, iterable<K, V>): ?array{ResV, ResK} $transformer
167
- * @return \Generator<ResV, ResK>
173
+ * @param callable(V, K, iterable<K, V>): ?array{ResK, ResV} $transformer
174
+ * @return \Generator<ResK, ResV>
168
175
  */
169
176
  public static function mapWithKeys(iterable $iterable, callable $transformer): \Generator
170
177
  {
@@ -177,6 +184,32 @@ final class Iterables
177
184
  }
178
185
 
179
186
 
187
+ /**
188
+ * Creates a repeatable iterator from a factory function.
189
+ * The factory is called every time the iterator is iterated.
190
+ * @template K
191
+ * @template V
192
+ * @param callable(): iterable<K, V> $factory
193
+ * @return \IteratorAggregate<K, V>
194
+ */
195
+ public static function repeatable(callable $factory): \IteratorAggregate
196
+ {
197
+ return new class ($factory(...)) implements \IteratorAggregate {
198
+ public function __construct(
199
+ /** @var \Closure(): iterable<mixed, mixed> */
200
+ private \Closure $factory,
201
+ ) {
202
+ }
203
+
204
+
205
+ public function getIterator(): \Iterator
206
+ {
207
+ return Iterables::toIterator(($this->factory)());
208
+ }
209
+ };
210
+ }
211
+
212
+
180
213
  /**
181
214
  * Wraps around iterator and caches its keys and values during iteration.
182
215
  * This allows the data to be re-iterated multiple times.
@@ -185,11 +218,12 @@ final class Iterables
185
218
  * @param iterable<K, V> $iterable
186
219
  * @return \IteratorAggregate<K, V>
187
220
  */
188
- public static function memoize(iterable $iterable): iterable
221
+ public static function memoize(iterable $iterable): \IteratorAggregate
189
222
  {
190
223
  return new class (self::toIterator($iterable)) implements \IteratorAggregate {
191
224
  public function __construct(
192
- private \Iterator $iterator,
225
+ private readonly \Iterator $iterator,
226
+ /** @var array<array{mixed, mixed}> */
193
227
  private array $cache = [],
194
228
  ) {
195
229
  }
@@ -10,6 +10,8 @@ declare(strict_types=1);
10
10
  namespace Nette\Utils;
11
11
 
12
12
  use Nette;
13
+ use function defined, is_int, json_decode, json_encode, json_last_error, json_last_error_msg;
14
+ use const JSON_BIGINT_AS_STRING, JSON_FORCE_OBJECT, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT, JSON_HEX_TAG, JSON_OBJECT_AS_ARRAY, JSON_PRESERVE_ZERO_FRACTION, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE;
13
15
 
14
16
 
15
17
  /**
@@ -11,6 +11,8 @@ namespace Nette\Utils;
11
11
 
12
12
  use Nette;
13
13
  use Nette\MemberAccessException;
14
+ use function array_filter, array_merge, array_pop, array_unique, get_class_methods, get_parent_class, implode, is_a, levenshtein, method_exists, preg_match_all, preg_replace, strlen, ucfirst;
15
+ use const PREG_SET_ORDER, SORT_REGULAR;
14
16
 
15
17
 
16
18
  /**
@@ -17,17 +17,17 @@ use Nette;
17
17
  *
18
18
  * @property int $page
19
19
  * @property-read int $firstPage
20
- * @property-read int|null $lastPage
20
+ * @property-read ?int $lastPage
21
21
  * @property-read int<0,max> $firstItemOnPage
22
22
  * @property-read int<0,max> $lastItemOnPage
23
23
  * @property int $base
24
24
  * @property-read bool $first
25
25
  * @property-read bool $last
26
- * @property-read int<0,max>|null $pageCount
26
+ * @property-read ?int<0,max> $pageCount
27
27
  * @property positive-int $itemsPerPage
28
- * @property int<0,max>|null $itemCount
28
+ * @property ?int<0,max> $itemCount
29
29
  * @property-read int<0,max> $offset
30
- * @property-read int<0,max>|null $countdownOffset
30
+ * @property-read ?int<0,max> $countdownOffset
31
31
  * @property-read int<0,max> $length
32
32
  */
33
33
  class Paginator
@@ -41,13 +41,10 @@ class Paginator
41
41
 
42
42
  private int $page = 1;
43
43
 
44
- /** @var int<0, max>|null */
44
+ /** @var ?int<0, max> */
45
45
  private ?int $itemCount = null;
46
46
 
47
47
 
48
- /**
49
- * Sets current page number.
50
- */
51
48
  public function setPage(int $page): static
52
49
  {
53
50
  $this->page = $page;
@@ -55,27 +52,18 @@ class Paginator
55
52
  }
56
53
 
57
54
 
58
- /**
59
- * Returns current page number.
60
- */
61
55
  public function getPage(): int
62
56
  {
63
57
  return $this->base + $this->getPageIndex();
64
58
  }
65
59
 
66
60
 
67
- /**
68
- * Returns first page number.
69
- */
70
61
  public function getFirstPage(): int
71
62
  {
72
63
  return $this->base;
73
64
  }
74
65
 
75
66
 
76
- /**
77
- * Returns last page number.
78
- */
79
67
  public function getLastPage(): ?int
80
68
  {
81
69
  return $this->itemCount === null
@@ -106,9 +94,6 @@ class Paginator
106
94
  }
107
95
 
108
96
 
109
- /**
110
- * Sets first page (base) number.
111
- */
112
97
  public function setBase(int $base): static
113
98
  {
114
99
  $this->base = $base;
@@ -116,9 +101,6 @@ class Paginator
116
101
  }
117
102
 
118
103
 
119
- /**
120
- * Returns first page (base) number.
121
- */
122
104
  public function getBase(): int
123
105
  {
124
106
  return $this->base;
@@ -138,18 +120,12 @@ class Paginator
138
120
  }
139
121
 
140
122
 
141
- /**
142
- * Is the current page the first one?
143
- */
144
123
  public function isFirst(): bool
145
124
  {
146
125
  return $this->getPageIndex() === 0;
147
126
  }
148
127
 
149
128
 
150
- /**
151
- * Is the current page the last one?
152
- */
153
129
  public function isLast(): bool
154
130
  {
155
131
  return $this->itemCount === null
@@ -159,20 +135,16 @@ class Paginator
159
135
 
160
136
 
161
137
  /**
162
- * Returns the total number of pages.
163
- * @return int<0, max>|null
138
+ * @return ?int<0, max>
164
139
  */
165
140
  public function getPageCount(): ?int
166
141
  {
167
142
  return $this->itemCount === null
168
143
  ? null
169
- : (int) ceil($this->itemCount / $this->itemsPerPage);
144
+ : max(0, (int) ceil($this->itemCount / $this->itemsPerPage));
170
145
  }
171
146
 
172
147
 
173
- /**
174
- * Sets the number of items to display on a single page.
175
- */
176
148
  public function setItemsPerPage(int $itemsPerPage): static
177
149
  {
178
150
  $this->itemsPerPage = max(1, $itemsPerPage);
@@ -181,7 +153,6 @@ class Paginator
181
153
 
182
154
 
183
155
  /**
184
- * Returns the number of items to display on a single page.
185
156
  * @return positive-int
186
157
  */
187
158
  public function getItemsPerPage(): int
@@ -190,9 +161,6 @@ class Paginator
190
161
  }
191
162
 
192
163
 
193
- /**
194
- * Sets the total number of items.
195
- */
196
164
  public function setItemCount(?int $itemCount = null): static
197
165
  {
198
166
  $this->itemCount = $itemCount === null ? null : max(0, $itemCount);
@@ -201,8 +169,7 @@ class Paginator
201
169
 
202
170
 
203
171
  /**
204
- * Returns the total number of items.
205
- * @return int<0, max>|null
172
+ * @return ?int<0, max>
206
173
  */
207
174
  public function getItemCount(): ?int
208
175
  {
@@ -222,7 +189,7 @@ class Paginator
222
189
 
223
190
  /**
224
191
  * Returns the absolute index of the first item on current page in countdown paging.
225
- * @return int<0, max>|null
192
+ * @return ?int<0, max>
226
193
  */
227
194
  public function getCountdownOffset(): ?int
228
195
  {
@@ -240,6 +207,6 @@ class Paginator
240
207
  {
241
208
  return $this->itemCount === null
242
209
  ? $this->itemsPerPage
243
- : min($this->itemsPerPage, $this->itemCount - $this->getPageIndex() * $this->itemsPerPage);
210
+ : max(0, min($this->itemsPerPage, $this->itemCount - $this->getPageIndex() * $this->itemsPerPage));
244
211
  }
245
212
  }