├── .editorconfig ├── .env.example ├── .github └── ISSUE_TEMPLATE │ ├── BUG.yml │ ├── FEATURE.yml │ └── config.yml ├── .gitignore ├── .phpdoc-md ├── LICENSE ├── README.md ├── SpacesAPI ├── Exceptions │ ├── AuthenticationException.php │ ├── FileDoesntExistException.php │ ├── SpaceDoesntExistException.php │ ├── SpaceExistsException.php │ └── SpacesException.php ├── File.php ├── Result.php ├── Space.php ├── Spaces.php └── StringFunctions.php ├── composer.json ├── composer.lock ├── docs ├── Examples.md ├── File.md ├── Space.md ├── Spaces.md └── Upgrade2-3.md └── tests ├── FileTest.php ├── SpaceTest.php └── SpacesTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | indent_size = 4 5 | indent_style = space 6 | insert_final_newline = true 7 | max_line_length = 600 8 | tab_width = 4 9 | trim_trailing_whitespace = true 10 | ij_continuation_indent_size = 8 11 | ij_formatter_off_tag = @formatter:off 12 | ij_formatter_on_tag = @formatter:on 13 | ij_formatter_tags_enabled = false 14 | ij_smart_tabs = false 15 | ij_visual_guides = none 16 | ij_wrap_on_typing = false 17 | 18 | [*.blade.php] 19 | ij_blade_keep_indents_on_empty_lines = false 20 | 21 | [*.css] 22 | ij_css_align_closing_brace_with_properties = false 23 | ij_css_blank_lines_around_nested_selector = 1 24 | ij_css_blank_lines_between_blocks = 1 25 | ij_css_brace_placement = end_of_line 26 | ij_css_enforce_quotes_on_format = false 27 | ij_css_hex_color_long_format = true 28 | ij_css_hex_color_lower_case = false 29 | ij_css_hex_color_short_format = false 30 | ij_css_hex_color_upper_case = true 31 | ij_css_keep_blank_lines_in_code = 2 32 | ij_css_keep_indents_on_empty_lines = false 33 | ij_css_keep_single_line_blocks = false 34 | ij_css_properties_order = position,display,visibility,float,clear,top,right,bottom,left,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,order,z-index,width,height,min-width,min-height,max-width,max-height,box-sizing,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,overflow,overflow-x,overflow-y,content,resize,opacity,outline,outline-width,outline-style,outline-color,outline-offset,box-decoration-break,box-shadow,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,background,background-color,background-image,background-position,background-position-x,background-position-y,background-size,background-repeat,background-origin,background-clip,background-attachment,scroll-behavior,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,letter-spacing,word-spacing,tab-size,align-content,align-items,align-self,text-align,text-align-last,text-indent,text-justify,justify-content,vertical-align,color,text-shadow,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,quotes,user-select,white-space,word-wrap,word-break,hyphens,list-style,list-style-position,list-style-type,list-style-image,table-layout,empty-cells,caption-side,border-spacing,border-collapse,nav-index,nav-left,nav-up,nav-right,nav-down,zoom,counter-reset,counter-increment,cursor,pointer-events 35 | ij_css_space_after_colon = true 36 | ij_css_space_before_opening_brace = true 37 | ij_css_use_double_quotes = true 38 | ij_css_value_alignment = do_not_align 39 | 40 | [*.feature] 41 | indent_size = 2 42 | ij_gherkin_keep_indents_on_empty_lines = false 43 | 44 | [*.haml] 45 | indent_size = 2 46 | ij_haml_keep_indents_on_empty_lines = false 47 | 48 | [*.less] 49 | indent_size = 2 50 | ij_less_align_closing_brace_with_properties = false 51 | ij_less_blank_lines_around_nested_selector = 1 52 | ij_less_blank_lines_between_blocks = 1 53 | ij_less_brace_placement = 0 54 | ij_less_enforce_quotes_on_format = false 55 | ij_less_hex_color_long_format = true 56 | ij_less_hex_color_lower_case = false 57 | ij_less_hex_color_short_format = false 58 | ij_less_hex_color_upper_case = true 59 | ij_less_keep_blank_lines_in_code = 2 60 | ij_less_keep_indents_on_empty_lines = false 61 | ij_less_keep_single_line_blocks = false 62 | ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow 63 | ij_less_space_after_colon = true 64 | ij_less_space_before_opening_brace = true 65 | ij_less_use_double_quotes = true 66 | ij_less_value_alignment = 0 67 | 68 | [*.sass] 69 | indent_size = 2 70 | ij_sass_align_closing_brace_with_properties = false 71 | ij_sass_blank_lines_around_nested_selector = 1 72 | ij_sass_blank_lines_between_blocks = 1 73 | ij_sass_brace_placement = 0 74 | ij_sass_enforce_quotes_on_format = false 75 | ij_sass_hex_color_long_format = false 76 | ij_sass_hex_color_lower_case = false 77 | ij_sass_hex_color_short_format = false 78 | ij_sass_hex_color_upper_case = false 79 | ij_sass_keep_blank_lines_in_code = 2 80 | ij_sass_keep_indents_on_empty_lines = false 81 | ij_sass_keep_single_line_blocks = false 82 | ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow 83 | ij_sass_space_after_colon = true 84 | ij_sass_space_before_opening_brace = true 85 | ij_sass_use_double_quotes = true 86 | ij_sass_value_alignment = 0 87 | 88 | [*.scss] 89 | ij_scss_align_closing_brace_with_properties = false 90 | ij_scss_blank_lines_around_nested_selector = 1 91 | ij_scss_blank_lines_between_blocks = 1 92 | ij_scss_brace_placement = 0 93 | ij_scss_enforce_quotes_on_format = false 94 | ij_scss_hex_color_long_format = true 95 | ij_scss_hex_color_lower_case = false 96 | ij_scss_hex_color_short_format = false 97 | ij_scss_hex_color_upper_case = true 98 | ij_scss_keep_blank_lines_in_code = 1 99 | ij_scss_keep_indents_on_empty_lines = false 100 | ij_scss_keep_single_line_blocks = false 101 | ij_scss_properties_order = position,display,visibility,float,clear,top,right,bottom,left,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,order,z-index,width,height,min-width,min-height,max-width,max-height,box-sizing,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,overflow,overflow-x,overflow-y,content,resize,opacity,outline,outline-width,outline-style,outline-color,outline-offset,box-decoration-break,box-shadow,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,background,background-color,background-image,background-position,background-position-x,background-position-y,background-size,background-repeat,background-origin,background-clip,background-attachment,scroll-behavior,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,letter-spacing,word-spacing,tab-size,align-content,align-items,align-self,text-align,text-align-last,text-indent,text-justify,justify-content,vertical-align,color,text-shadow,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,quotes,user-select,white-space,word-wrap,word-break,hyphens,list-style,list-style-position,list-style-type,list-style-image,table-layout,empty-cells,caption-side,border-spacing,border-collapse,nav-index,nav-left,nav-up,nav-right,nav-down,zoom,counter-reset,counter-increment,cursor,pointer-events 102 | ij_scss_space_after_colon = true 103 | ij_scss_space_before_opening_brace = true 104 | ij_scss_use_double_quotes = true 105 | ij_scss_value_alignment = 0 106 | 107 | [*.twig] 108 | ij_twig_keep_indents_on_empty_lines = false 109 | ij_twig_spaces_inside_comments_delimiters = true 110 | ij_twig_spaces_inside_delimiters = true 111 | ij_twig_spaces_inside_variable_delimiters = true 112 | 113 | [*.vue] 114 | ij_continuation_indent_size = 4 115 | ij_vue_indent_children_of_top_level = template 116 | ij_vue_interpolation_new_line_after_start_delimiter = true 117 | ij_vue_interpolation_new_line_before_end_delimiter = true 118 | ij_vue_interpolation_wrap = off 119 | ij_vue_keep_indents_on_empty_lines = false 120 | ij_vue_spaces_within_interpolation_expressions = true 121 | 122 | [.editorconfig] 123 | ij_editorconfig_align_group_field_declarations = false 124 | ij_editorconfig_space_after_colon = false 125 | ij_editorconfig_space_after_comma = true 126 | ij_editorconfig_space_before_colon = false 127 | ij_editorconfig_space_before_comma = false 128 | ij_editorconfig_spaces_around_assignment_operators = true 129 | 130 | [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}] 131 | ij_xml_align_attributes = true 132 | ij_xml_align_text = false 133 | ij_xml_attribute_wrap = normal 134 | ij_xml_block_comment_at_first_column = true 135 | ij_xml_keep_blank_lines = 2 136 | ij_xml_keep_indents_on_empty_lines = false 137 | ij_xml_keep_line_breaks = true 138 | ij_xml_keep_line_breaks_in_text = true 139 | ij_xml_keep_whitespaces = false 140 | ij_xml_keep_whitespaces_around_cdata = preserve 141 | ij_xml_keep_whitespaces_inside_cdata = false 142 | ij_xml_line_comment_at_first_column = true 143 | ij_xml_space_after_tag_name = false 144 | ij_xml_space_around_equals_in_attribute = false 145 | ij_xml_space_inside_empty_tag = false 146 | ij_xml_text_wrap = normal 147 | 148 | [{*.ats,*.ts}] 149 | ij_continuation_indent_size = 4 150 | ij_typescript_align_imports = false 151 | ij_typescript_align_multiline_array_initializer_expression = false 152 | ij_typescript_align_multiline_binary_operation = false 153 | ij_typescript_align_multiline_chained_methods = false 154 | ij_typescript_align_multiline_extends_list = false 155 | ij_typescript_align_multiline_for = true 156 | ij_typescript_align_multiline_parameters = true 157 | ij_typescript_align_multiline_parameters_in_calls = false 158 | ij_typescript_align_multiline_ternary_operation = false 159 | ij_typescript_align_object_properties = 0 160 | ij_typescript_align_union_types = false 161 | ij_typescript_align_var_statements = 0 162 | ij_typescript_array_initializer_new_line_after_left_brace = false 163 | ij_typescript_array_initializer_right_brace_on_new_line = false 164 | ij_typescript_array_initializer_wrap = off 165 | ij_typescript_assignment_wrap = off 166 | ij_typescript_binary_operation_sign_on_next_line = false 167 | ij_typescript_binary_operation_wrap = off 168 | ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** 169 | ij_typescript_blank_lines_after_imports = 1 170 | ij_typescript_blank_lines_around_class = 1 171 | ij_typescript_blank_lines_around_field = 0 172 | ij_typescript_blank_lines_around_field_in_interface = 0 173 | ij_typescript_blank_lines_around_function = 1 174 | ij_typescript_blank_lines_around_method = 1 175 | ij_typescript_blank_lines_around_method_in_interface = 1 176 | ij_typescript_block_brace_style = end_of_line 177 | ij_typescript_call_parameters_new_line_after_left_paren = false 178 | ij_typescript_call_parameters_right_paren_on_new_line = false 179 | ij_typescript_call_parameters_wrap = off 180 | ij_typescript_catch_on_new_line = false 181 | ij_typescript_chained_call_dot_on_new_line = true 182 | ij_typescript_class_brace_style = end_of_line 183 | ij_typescript_comma_on_new_line = false 184 | ij_typescript_do_while_brace_force = never 185 | ij_typescript_else_on_new_line = false 186 | ij_typescript_enforce_trailing_comma = keep 187 | ij_typescript_extends_keyword_wrap = off 188 | ij_typescript_extends_list_wrap = off 189 | ij_typescript_field_prefix = _ 190 | ij_typescript_file_name_style = relaxed 191 | ij_typescript_finally_on_new_line = false 192 | ij_typescript_for_brace_force = never 193 | ij_typescript_for_statement_new_line_after_left_paren = false 194 | ij_typescript_for_statement_right_paren_on_new_line = false 195 | ij_typescript_for_statement_wrap = off 196 | ij_typescript_force_quote_style = false 197 | ij_typescript_force_semicolon_style = false 198 | ij_typescript_function_expression_brace_style = end_of_line 199 | ij_typescript_if_brace_force = never 200 | ij_typescript_import_merge_members = global 201 | ij_typescript_import_prefer_absolute_path = global 202 | ij_typescript_import_sort_members = true 203 | ij_typescript_import_sort_module_name = false 204 | ij_typescript_import_use_node_resolution = true 205 | ij_typescript_imports_wrap = on_every_item 206 | ij_typescript_indent_case_from_switch = true 207 | ij_typescript_indent_chained_calls = true 208 | ij_typescript_indent_package_children = 0 209 | ij_typescript_jsdoc_include_types = false 210 | ij_typescript_jsx_attribute_value = braces 211 | ij_typescript_keep_blank_lines_in_code = 2 212 | ij_typescript_keep_first_column_comment = true 213 | ij_typescript_keep_indents_on_empty_lines = false 214 | ij_typescript_keep_line_breaks = true 215 | ij_typescript_keep_simple_blocks_in_one_line = false 216 | ij_typescript_keep_simple_methods_in_one_line = false 217 | ij_typescript_line_comment_add_space = true 218 | ij_typescript_line_comment_at_first_column = false 219 | ij_typescript_method_brace_style = end_of_line 220 | ij_typescript_method_call_chain_wrap = off 221 | ij_typescript_method_parameters_new_line_after_left_paren = false 222 | ij_typescript_method_parameters_right_paren_on_new_line = false 223 | ij_typescript_method_parameters_wrap = off 224 | ij_typescript_object_literal_wrap = on_every_item 225 | ij_typescript_parentheses_expression_new_line_after_left_paren = false 226 | ij_typescript_parentheses_expression_right_paren_on_new_line = false 227 | ij_typescript_place_assignment_sign_on_next_line = false 228 | ij_typescript_prefer_as_type_cast = false 229 | ij_typescript_prefer_explicit_types_function_expression_returns = false 230 | ij_typescript_prefer_explicit_types_function_returns = false 231 | ij_typescript_prefer_explicit_types_vars_fields = false 232 | ij_typescript_prefer_parameters_wrap = false 233 | ij_typescript_reformat_c_style_comments = false 234 | ij_typescript_space_after_colon = true 235 | ij_typescript_space_after_comma = true 236 | ij_typescript_space_after_dots_in_rest_parameter = false 237 | ij_typescript_space_after_generator_mult = true 238 | ij_typescript_space_after_property_colon = true 239 | ij_typescript_space_after_quest = true 240 | ij_typescript_space_after_type_colon = true 241 | ij_typescript_space_after_unary_not = false 242 | ij_typescript_space_before_async_arrow_lparen = true 243 | ij_typescript_space_before_catch_keyword = true 244 | ij_typescript_space_before_catch_left_brace = true 245 | ij_typescript_space_before_catch_parentheses = true 246 | ij_typescript_space_before_class_lbrace = true 247 | ij_typescript_space_before_class_left_brace = true 248 | ij_typescript_space_before_colon = true 249 | ij_typescript_space_before_comma = false 250 | ij_typescript_space_before_do_left_brace = true 251 | ij_typescript_space_before_else_keyword = true 252 | ij_typescript_space_before_else_left_brace = true 253 | ij_typescript_space_before_finally_keyword = true 254 | ij_typescript_space_before_finally_left_brace = true 255 | ij_typescript_space_before_for_left_brace = true 256 | ij_typescript_space_before_for_parentheses = true 257 | ij_typescript_space_before_for_semicolon = false 258 | ij_typescript_space_before_function_left_parenth = true 259 | ij_typescript_space_before_generator_mult = false 260 | ij_typescript_space_before_if_left_brace = true 261 | ij_typescript_space_before_if_parentheses = true 262 | ij_typescript_space_before_method_call_parentheses = false 263 | ij_typescript_space_before_method_left_brace = true 264 | ij_typescript_space_before_method_parentheses = false 265 | ij_typescript_space_before_property_colon = false 266 | ij_typescript_space_before_quest = true 267 | ij_typescript_space_before_switch_left_brace = true 268 | ij_typescript_space_before_switch_parentheses = true 269 | ij_typescript_space_before_try_left_brace = true 270 | ij_typescript_space_before_type_colon = false 271 | ij_typescript_space_before_unary_not = false 272 | ij_typescript_space_before_while_keyword = true 273 | ij_typescript_space_before_while_left_brace = true 274 | ij_typescript_space_before_while_parentheses = true 275 | ij_typescript_spaces_around_additive_operators = true 276 | ij_typescript_spaces_around_arrow_function_operator = true 277 | ij_typescript_spaces_around_assignment_operators = true 278 | ij_typescript_spaces_around_bitwise_operators = true 279 | ij_typescript_spaces_around_equality_operators = true 280 | ij_typescript_spaces_around_logical_operators = true 281 | ij_typescript_spaces_around_multiplicative_operators = true 282 | ij_typescript_spaces_around_relational_operators = true 283 | ij_typescript_spaces_around_shift_operators = true 284 | ij_typescript_spaces_around_unary_operator = false 285 | ij_typescript_spaces_within_array_initializer_brackets = false 286 | ij_typescript_spaces_within_brackets = false 287 | ij_typescript_spaces_within_catch_parentheses = false 288 | ij_typescript_spaces_within_for_parentheses = false 289 | ij_typescript_spaces_within_if_parentheses = false 290 | ij_typescript_spaces_within_imports = false 291 | ij_typescript_spaces_within_interpolation_expressions = false 292 | ij_typescript_spaces_within_method_call_parentheses = false 293 | ij_typescript_spaces_within_method_parentheses = false 294 | ij_typescript_spaces_within_object_literal_braces = false 295 | ij_typescript_spaces_within_object_type_braces = true 296 | ij_typescript_spaces_within_parentheses = false 297 | ij_typescript_spaces_within_switch_parentheses = false 298 | ij_typescript_spaces_within_type_assertion = false 299 | ij_typescript_spaces_within_union_types = true 300 | ij_typescript_spaces_within_while_parentheses = false 301 | ij_typescript_special_else_if_treatment = true 302 | ij_typescript_ternary_operation_signs_on_next_line = false 303 | ij_typescript_ternary_operation_wrap = off 304 | ij_typescript_union_types_wrap = on_every_item 305 | ij_typescript_use_chained_calls_group_indents = false 306 | ij_typescript_use_double_quotes = true 307 | ij_typescript_use_explicit_js_extension = global 308 | ij_typescript_use_path_mapping = always 309 | ij_typescript_use_public_modifier = false 310 | ij_typescript_use_semicolon_after_statement = true 311 | ij_typescript_var_declaration_wrap = normal 312 | ij_typescript_while_brace_force = never 313 | ij_typescript_while_on_new_line = false 314 | ij_typescript_wrap_comments = false 315 | 316 | [{*.bash,*.sh,*.zsh}] 317 | indent_size = 2 318 | tab_width = 2 319 | ij_shell_binary_ops_start_line = false 320 | ij_shell_keep_column_alignment_padding = false 321 | ij_shell_minify_program = false 322 | ij_shell_redirect_followed_by_space = false 323 | ij_shell_switch_cases_indented = false 324 | ij_shell_use_unix_line_separator = true 325 | 326 | [{*.cjs,*.js}] 327 | ij_continuation_indent_size = 4 328 | ij_javascript_align_imports = false 329 | ij_javascript_align_multiline_array_initializer_expression = false 330 | ij_javascript_align_multiline_binary_operation = false 331 | ij_javascript_align_multiline_chained_methods = false 332 | ij_javascript_align_multiline_extends_list = false 333 | ij_javascript_align_multiline_for = true 334 | ij_javascript_align_multiline_parameters = true 335 | ij_javascript_align_multiline_parameters_in_calls = false 336 | ij_javascript_align_multiline_ternary_operation = false 337 | ij_javascript_align_object_properties = 0 338 | ij_javascript_align_union_types = false 339 | ij_javascript_align_var_statements = 0 340 | ij_javascript_array_initializer_new_line_after_left_brace = true 341 | ij_javascript_array_initializer_right_brace_on_new_line = false 342 | ij_javascript_array_initializer_wrap = on_every_item 343 | ij_javascript_assignment_wrap = off 344 | ij_javascript_binary_operation_sign_on_next_line = false 345 | ij_javascript_binary_operation_wrap = normal 346 | ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** 347 | ij_javascript_blank_lines_after_imports = 1 348 | ij_javascript_blank_lines_around_class = 1 349 | ij_javascript_blank_lines_around_field = 0 350 | ij_javascript_blank_lines_around_function = 1 351 | ij_javascript_blank_lines_around_method = 1 352 | ij_javascript_block_brace_style = end_of_line 353 | ij_javascript_call_parameters_new_line_after_left_paren = false 354 | ij_javascript_call_parameters_right_paren_on_new_line = false 355 | ij_javascript_call_parameters_wrap = normal 356 | ij_javascript_catch_on_new_line = false 357 | ij_javascript_chained_call_dot_on_new_line = true 358 | ij_javascript_class_brace_style = end_of_line 359 | ij_javascript_comma_on_new_line = false 360 | ij_javascript_do_while_brace_force = never 361 | ij_javascript_else_on_new_line = false 362 | ij_javascript_enforce_trailing_comma = whenmultiline 363 | ij_javascript_extends_keyword_wrap = off 364 | ij_javascript_extends_list_wrap = off 365 | ij_javascript_field_prefix = _ 366 | ij_javascript_file_name_style = relaxed 367 | ij_javascript_finally_on_new_line = false 368 | ij_javascript_for_brace_force = never 369 | ij_javascript_for_statement_new_line_after_left_paren = false 370 | ij_javascript_for_statement_right_paren_on_new_line = false 371 | ij_javascript_for_statement_wrap = off 372 | ij_javascript_force_quote_style = true 373 | ij_javascript_force_semicolon_style = true 374 | ij_javascript_function_expression_brace_style = end_of_line 375 | ij_javascript_if_brace_force = never 376 | ij_javascript_import_merge_members = global 377 | ij_javascript_import_prefer_absolute_path = global 378 | ij_javascript_import_sort_members = true 379 | ij_javascript_import_sort_module_name = false 380 | ij_javascript_import_use_node_resolution = true 381 | ij_javascript_imports_wrap = on_every_item 382 | ij_javascript_indent_case_from_switch = true 383 | ij_javascript_indent_chained_calls = true 384 | ij_javascript_indent_package_children = 0 385 | ij_javascript_jsx_attribute_value = braces 386 | ij_javascript_keep_blank_lines_in_code = 1 387 | ij_javascript_keep_first_column_comment = true 388 | ij_javascript_keep_indents_on_empty_lines = false 389 | ij_javascript_keep_line_breaks = true 390 | ij_javascript_keep_simple_blocks_in_one_line = false 391 | ij_javascript_keep_simple_methods_in_one_line = false 392 | ij_javascript_line_comment_add_space = true 393 | ij_javascript_line_comment_at_first_column = false 394 | ij_javascript_method_brace_style = end_of_line 395 | ij_javascript_method_call_chain_wrap = on_every_item 396 | ij_javascript_method_parameters_new_line_after_left_paren = true 397 | ij_javascript_method_parameters_right_paren_on_new_line = false 398 | ij_javascript_method_parameters_wrap = normal 399 | ij_javascript_object_literal_wrap = on_every_item 400 | ij_javascript_parentheses_expression_new_line_after_left_paren = false 401 | ij_javascript_parentheses_expression_right_paren_on_new_line = false 402 | ij_javascript_place_assignment_sign_on_next_line = false 403 | ij_javascript_prefer_as_type_cast = false 404 | ij_javascript_prefer_explicit_types_function_expression_returns = false 405 | ij_javascript_prefer_explicit_types_function_returns = false 406 | ij_javascript_prefer_explicit_types_vars_fields = false 407 | ij_javascript_prefer_parameters_wrap = false 408 | ij_javascript_reformat_c_style_comments = false 409 | ij_javascript_space_after_colon = true 410 | ij_javascript_space_after_comma = true 411 | ij_javascript_space_after_dots_in_rest_parameter = false 412 | ij_javascript_space_after_generator_mult = true 413 | ij_javascript_space_after_property_colon = true 414 | ij_javascript_space_after_quest = true 415 | ij_javascript_space_after_type_colon = true 416 | ij_javascript_space_after_unary_not = false 417 | ij_javascript_space_before_async_arrow_lparen = true 418 | ij_javascript_space_before_catch_keyword = true 419 | ij_javascript_space_before_catch_left_brace = true 420 | ij_javascript_space_before_catch_parentheses = true 421 | ij_javascript_space_before_class_lbrace = true 422 | ij_javascript_space_before_class_left_brace = true 423 | ij_javascript_space_before_colon = true 424 | ij_javascript_space_before_comma = false 425 | ij_javascript_space_before_do_left_brace = true 426 | ij_javascript_space_before_else_keyword = true 427 | ij_javascript_space_before_else_left_brace = true 428 | ij_javascript_space_before_finally_keyword = true 429 | ij_javascript_space_before_finally_left_brace = true 430 | ij_javascript_space_before_for_left_brace = true 431 | ij_javascript_space_before_for_parentheses = true 432 | ij_javascript_space_before_for_semicolon = false 433 | ij_javascript_space_before_function_left_parenth = false 434 | ij_javascript_space_before_generator_mult = false 435 | ij_javascript_space_before_if_left_brace = true 436 | ij_javascript_space_before_if_parentheses = true 437 | ij_javascript_space_before_method_call_parentheses = false 438 | ij_javascript_space_before_method_left_brace = true 439 | ij_javascript_space_before_method_parentheses = false 440 | ij_javascript_space_before_property_colon = false 441 | ij_javascript_space_before_quest = true 442 | ij_javascript_space_before_switch_left_brace = true 443 | ij_javascript_space_before_switch_parentheses = true 444 | ij_javascript_space_before_try_left_brace = true 445 | ij_javascript_space_before_type_colon = false 446 | ij_javascript_space_before_unary_not = false 447 | ij_javascript_space_before_while_keyword = true 448 | ij_javascript_space_before_while_left_brace = true 449 | ij_javascript_space_before_while_parentheses = true 450 | ij_javascript_spaces_around_additive_operators = true 451 | ij_javascript_spaces_around_arrow_function_operator = true 452 | ij_javascript_spaces_around_assignment_operators = true 453 | ij_javascript_spaces_around_bitwise_operators = true 454 | ij_javascript_spaces_around_equality_operators = true 455 | ij_javascript_spaces_around_logical_operators = true 456 | ij_javascript_spaces_around_multiplicative_operators = true 457 | ij_javascript_spaces_around_relational_operators = true 458 | ij_javascript_spaces_around_shift_operators = true 459 | ij_javascript_spaces_around_unary_operator = false 460 | ij_javascript_spaces_within_array_initializer_brackets = false 461 | ij_javascript_spaces_within_brackets = false 462 | ij_javascript_spaces_within_catch_parentheses = false 463 | ij_javascript_spaces_within_for_parentheses = false 464 | ij_javascript_spaces_within_if_parentheses = false 465 | ij_javascript_spaces_within_imports = false 466 | ij_javascript_spaces_within_interpolation_expressions = false 467 | ij_javascript_spaces_within_method_call_parentheses = false 468 | ij_javascript_spaces_within_method_parentheses = false 469 | ij_javascript_spaces_within_object_literal_braces = true 470 | ij_javascript_spaces_within_object_type_braces = true 471 | ij_javascript_spaces_within_parentheses = false 472 | ij_javascript_spaces_within_switch_parentheses = false 473 | ij_javascript_spaces_within_type_assertion = false 474 | ij_javascript_spaces_within_union_types = true 475 | ij_javascript_spaces_within_while_parentheses = false 476 | ij_javascript_special_else_if_treatment = true 477 | ij_javascript_ternary_operation_signs_on_next_line = false 478 | ij_javascript_ternary_operation_wrap = on_every_item 479 | ij_javascript_union_types_wrap = on_every_item 480 | ij_javascript_use_chained_calls_group_indents = false 481 | ij_javascript_use_double_quotes = false 482 | ij_javascript_use_explicit_js_extension = global 483 | ij_javascript_use_path_mapping = always 484 | ij_javascript_use_public_modifier = false 485 | ij_javascript_use_semicolon_after_statement = true 486 | ij_javascript_var_declaration_wrap = normal 487 | ij_javascript_while_brace_force = never 488 | ij_javascript_while_on_new_line = false 489 | ij_javascript_wrap_comments = false 490 | 491 | [{*.cjsx,*.coffee}] 492 | indent_size = 2 493 | tab_width = 2 494 | ij_continuation_indent_size = 2 495 | ij_coffeescript_align_function_body = false 496 | ij_coffeescript_align_imports = false 497 | ij_coffeescript_align_multiline_array_initializer_expression = true 498 | ij_coffeescript_align_multiline_parameters = true 499 | ij_coffeescript_align_multiline_parameters_in_calls = false 500 | ij_coffeescript_align_object_properties = 0 501 | ij_coffeescript_align_union_types = false 502 | ij_coffeescript_align_var_statements = 0 503 | ij_coffeescript_array_initializer_new_line_after_left_brace = false 504 | ij_coffeescript_array_initializer_right_brace_on_new_line = false 505 | ij_coffeescript_array_initializer_wrap = normal 506 | ij_coffeescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** 507 | ij_coffeescript_blank_lines_around_function = 1 508 | ij_coffeescript_call_parameters_new_line_after_left_paren = false 509 | ij_coffeescript_call_parameters_right_paren_on_new_line = false 510 | ij_coffeescript_call_parameters_wrap = normal 511 | ij_coffeescript_chained_call_dot_on_new_line = true 512 | ij_coffeescript_comma_on_new_line = false 513 | ij_coffeescript_enforce_trailing_comma = keep 514 | ij_coffeescript_field_prefix = _ 515 | ij_coffeescript_file_name_style = relaxed 516 | ij_coffeescript_force_quote_style = false 517 | ij_coffeescript_force_semicolon_style = false 518 | ij_coffeescript_function_expression_brace_style = end_of_line 519 | ij_coffeescript_import_merge_members = global 520 | ij_coffeescript_import_prefer_absolute_path = global 521 | ij_coffeescript_import_sort_members = true 522 | ij_coffeescript_import_sort_module_name = false 523 | ij_coffeescript_import_use_node_resolution = true 524 | ij_coffeescript_imports_wrap = on_every_item 525 | ij_coffeescript_indent_chained_calls = true 526 | ij_coffeescript_indent_package_children = 0 527 | ij_coffeescript_jsx_attribute_value = braces 528 | ij_coffeescript_keep_blank_lines_in_code = 2 529 | ij_coffeescript_keep_first_column_comment = true 530 | ij_coffeescript_keep_indents_on_empty_lines = false 531 | ij_coffeescript_keep_line_breaks = true 532 | ij_coffeescript_keep_simple_methods_in_one_line = false 533 | ij_coffeescript_method_parameters_new_line_after_left_paren = false 534 | ij_coffeescript_method_parameters_right_paren_on_new_line = false 535 | ij_coffeescript_method_parameters_wrap = off 536 | ij_coffeescript_object_literal_wrap = on_every_item 537 | ij_coffeescript_prefer_as_type_cast = false 538 | ij_coffeescript_prefer_explicit_types_function_expression_returns = false 539 | ij_coffeescript_prefer_explicit_types_function_returns = false 540 | ij_coffeescript_prefer_explicit_types_vars_fields = false 541 | ij_coffeescript_reformat_c_style_comments = false 542 | ij_coffeescript_space_after_comma = true 543 | ij_coffeescript_space_after_dots_in_rest_parameter = false 544 | ij_coffeescript_space_after_generator_mult = true 545 | ij_coffeescript_space_after_property_colon = true 546 | ij_coffeescript_space_after_type_colon = true 547 | ij_coffeescript_space_after_unary_not = false 548 | ij_coffeescript_space_before_async_arrow_lparen = true 549 | ij_coffeescript_space_before_class_lbrace = true 550 | ij_coffeescript_space_before_comma = false 551 | ij_coffeescript_space_before_function_left_parenth = true 552 | ij_coffeescript_space_before_generator_mult = false 553 | ij_coffeescript_space_before_property_colon = false 554 | ij_coffeescript_space_before_type_colon = false 555 | ij_coffeescript_space_before_unary_not = false 556 | ij_coffeescript_spaces_around_additive_operators = true 557 | ij_coffeescript_spaces_around_arrow_function_operator = true 558 | ij_coffeescript_spaces_around_assignment_operators = true 559 | ij_coffeescript_spaces_around_bitwise_operators = true 560 | ij_coffeescript_spaces_around_equality_operators = true 561 | ij_coffeescript_spaces_around_logical_operators = true 562 | ij_coffeescript_spaces_around_multiplicative_operators = true 563 | ij_coffeescript_spaces_around_relational_operators = true 564 | ij_coffeescript_spaces_around_shift_operators = true 565 | ij_coffeescript_spaces_around_unary_operator = false 566 | ij_coffeescript_spaces_within_array_initializer_braces = false 567 | ij_coffeescript_spaces_within_array_initializer_brackets = false 568 | ij_coffeescript_spaces_within_imports = false 569 | ij_coffeescript_spaces_within_index_brackets = false 570 | ij_coffeescript_spaces_within_interpolation_expressions = false 571 | ij_coffeescript_spaces_within_method_call_parentheses = false 572 | ij_coffeescript_spaces_within_method_parentheses = false 573 | ij_coffeescript_spaces_within_object_braces = false 574 | ij_coffeescript_spaces_within_object_literal_braces = false 575 | ij_coffeescript_spaces_within_object_type_braces = true 576 | ij_coffeescript_spaces_within_range_brackets = false 577 | ij_coffeescript_spaces_within_type_assertion = false 578 | ij_coffeescript_spaces_within_union_types = true 579 | ij_coffeescript_union_types_wrap = on_every_item 580 | ij_coffeescript_use_chained_calls_group_indents = false 581 | ij_coffeescript_use_double_quotes = true 582 | ij_coffeescript_use_explicit_js_extension = global 583 | ij_coffeescript_use_path_mapping = always 584 | ij_coffeescript_use_public_modifier = false 585 | ij_coffeescript_use_semicolon_after_statement = false 586 | ij_coffeescript_var_declaration_wrap = normal 587 | 588 | [{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml,yii_te}] 589 | ij_continuation_indent_size = 4 590 | ij_php_align_assignments = false 591 | ij_php_align_class_constants = false 592 | ij_php_align_group_field_declarations = false 593 | ij_php_align_inline_comments = false 594 | ij_php_align_key_value_pairs = false 595 | ij_php_align_match_arm_bodies = false 596 | ij_php_align_multiline_array_initializer_expression = false 597 | ij_php_align_multiline_binary_operation = false 598 | ij_php_align_multiline_chained_methods = false 599 | ij_php_align_multiline_extends_list = true 600 | ij_php_align_multiline_for = true 601 | ij_php_align_multiline_parameters = false 602 | ij_php_align_multiline_parameters_in_calls = true 603 | ij_php_align_multiline_ternary_operation = false 604 | ij_php_align_named_arguments = false 605 | ij_php_align_phpdoc_comments = false 606 | ij_php_align_phpdoc_param_names = false 607 | ij_php_anonymous_brace_style = end_of_line 608 | ij_php_api_weight = 28 609 | ij_php_array_initializer_new_line_after_left_brace = true 610 | ij_php_array_initializer_right_brace_on_new_line = true 611 | ij_php_array_initializer_wrap = on_every_item 612 | ij_php_assignment_wrap = off 613 | ij_php_attributes_wrap = off 614 | ij_php_author_weight = 28 615 | ij_php_binary_operation_sign_on_next_line = false 616 | ij_php_binary_operation_wrap = off 617 | ij_php_blank_lines_after_class_header = 0 618 | ij_php_blank_lines_after_function = 1 619 | ij_php_blank_lines_after_imports = 1 620 | ij_php_blank_lines_after_opening_tag = 1 621 | ij_php_blank_lines_after_package = 1 622 | ij_php_blank_lines_around_class = 1 623 | ij_php_blank_lines_around_constants = 0 624 | ij_php_blank_lines_around_field = 0 625 | ij_php_blank_lines_around_method = 1 626 | ij_php_blank_lines_before_class_end = 0 627 | ij_php_blank_lines_before_imports = 1 628 | ij_php_blank_lines_before_method_body = 0 629 | ij_php_blank_lines_before_package = 1 630 | ij_php_blank_lines_before_return_statement = 0 631 | ij_php_blank_lines_between_imports = 1 632 | ij_php_block_brace_style = end_of_line 633 | ij_php_call_parameters_new_line_after_left_paren = true 634 | ij_php_call_parameters_right_paren_on_new_line = true 635 | ij_php_call_parameters_wrap = on_every_item 636 | ij_php_catch_on_new_line = false 637 | ij_php_category_weight = 28 638 | ij_php_class_brace_style = next_line 639 | ij_php_comma_after_last_array_element = true 640 | ij_php_concat_spaces = true 641 | ij_php_copyright_weight = 28 642 | ij_php_deprecated_weight = 28 643 | ij_php_do_while_brace_force = always 644 | ij_php_else_if_style = combine 645 | ij_php_else_on_new_line = false 646 | ij_php_example_weight = 28 647 | ij_php_extends_keyword_wrap = off 648 | ij_php_extends_list_wrap = on_every_item 649 | ij_php_fields_default_visibility = private 650 | ij_php_filesource_weight = 28 651 | ij_php_finally_on_new_line = false 652 | ij_php_for_brace_force = always 653 | ij_php_for_statement_new_line_after_left_paren = true 654 | ij_php_for_statement_right_paren_on_new_line = true 655 | ij_php_for_statement_wrap = off 656 | ij_php_force_short_declaration_array_style = false 657 | ij_php_getters_setters_naming_style = camel_case 658 | ij_php_getters_setters_order_style = getters_first 659 | ij_php_global_weight = 28 660 | ij_php_group_use_wrap = on_every_item 661 | ij_php_if_brace_force = always 662 | ij_php_if_lparen_on_next_line = false 663 | ij_php_if_rparen_on_next_line = false 664 | ij_php_ignore_weight = 28 665 | ij_php_import_sorting = alphabetic 666 | ij_php_indent_break_from_case = true 667 | ij_php_indent_case_from_switch = true 668 | ij_php_indent_code_in_php_tags = false 669 | ij_php_internal_weight = 28 670 | ij_php_keep_blank_lines_after_lbrace = 0 671 | ij_php_keep_blank_lines_before_right_brace = 0 672 | ij_php_keep_blank_lines_in_code = 2 673 | ij_php_keep_blank_lines_in_declarations = 2 674 | ij_php_keep_control_statement_in_one_line = true 675 | ij_php_keep_first_column_comment = true 676 | ij_php_keep_indents_on_empty_lines = false 677 | ij_php_keep_line_breaks = true 678 | ij_php_keep_rparen_and_lbrace_on_one_line = true 679 | ij_php_keep_simple_classes_in_one_line = false 680 | ij_php_keep_simple_methods_in_one_line = false 681 | ij_php_lambda_brace_style = end_of_line 682 | ij_php_license_weight = 28 683 | ij_php_line_comment_add_space = false 684 | ij_php_line_comment_at_first_column = true 685 | ij_php_link_weight = 28 686 | ij_php_lower_case_boolean_const = true 687 | ij_php_lower_case_keywords = true 688 | ij_php_lower_case_null_const = true 689 | ij_php_method_brace_style = next_line 690 | ij_php_method_call_chain_wrap = off 691 | ij_php_method_parameters_new_line_after_left_paren = true 692 | ij_php_method_parameters_right_paren_on_new_line = true 693 | ij_php_method_parameters_wrap = on_every_item 694 | ij_php_method_weight = 28 695 | ij_php_modifier_list_wrap = false 696 | ij_php_multiline_chained_calls_semicolon_on_new_line = false 697 | ij_php_namespace_brace_style = 1 698 | ij_php_new_line_after_php_opening_tag = true 699 | ij_php_null_type_position = in_the_end 700 | ij_php_package_weight = 28 701 | ij_php_param_weight = 0 702 | ij_php_parameters_attributes_wrap = off 703 | ij_php_parentheses_expression_new_line_after_left_paren = false 704 | ij_php_parentheses_expression_right_paren_on_new_line = false 705 | ij_php_phpdoc_blank_line_before_tags = true 706 | ij_php_phpdoc_blank_lines_around_parameters = true 707 | ij_php_phpdoc_keep_blank_lines = true 708 | ij_php_phpdoc_param_spaces_between_name_and_description = 1 709 | ij_php_phpdoc_param_spaces_between_tag_and_type = 1 710 | ij_php_phpdoc_param_spaces_between_type_and_name = 1 711 | ij_php_phpdoc_use_fqcn = true 712 | ij_php_phpdoc_wrap_long_lines = false 713 | ij_php_place_assignment_sign_on_next_line = false 714 | ij_php_place_parens_for_constructor = 0 715 | ij_php_property_read_weight = 28 716 | ij_php_property_weight = 28 717 | ij_php_property_write_weight = 28 718 | ij_php_return_type_on_new_line = false 719 | ij_php_return_weight = 1 720 | ij_php_see_weight = 28 721 | ij_php_since_weight = 28 722 | ij_php_sort_phpdoc_elements = true 723 | ij_php_space_after_colon = true 724 | ij_php_space_after_colon_in_enum_backed_type = true 725 | ij_php_space_after_colon_in_named_argument = true 726 | ij_php_space_after_colon_in_return_type = true 727 | ij_php_space_after_comma = true 728 | ij_php_space_after_for_semicolon = true 729 | ij_php_space_after_quest = true 730 | ij_php_space_after_type_cast = false 731 | ij_php_space_after_unary_not = false 732 | ij_php_space_before_array_initializer_left_brace = false 733 | ij_php_space_before_catch_keyword = true 734 | ij_php_space_before_catch_left_brace = true 735 | ij_php_space_before_catch_parentheses = true 736 | ij_php_space_before_class_left_brace = true 737 | ij_php_space_before_closure_left_parenthesis = true 738 | ij_php_space_before_colon = true 739 | ij_php_space_before_colon_in_enum_backed_type = false 740 | ij_php_space_before_colon_in_named_argument = false 741 | ij_php_space_before_colon_in_return_type = false 742 | ij_php_space_before_comma = false 743 | ij_php_space_before_do_left_brace = true 744 | ij_php_space_before_else_keyword = true 745 | ij_php_space_before_else_left_brace = true 746 | ij_php_space_before_finally_keyword = true 747 | ij_php_space_before_finally_left_brace = true 748 | ij_php_space_before_for_left_brace = true 749 | ij_php_space_before_for_parentheses = true 750 | ij_php_space_before_for_semicolon = false 751 | ij_php_space_before_if_left_brace = true 752 | ij_php_space_before_if_parentheses = true 753 | ij_php_space_before_method_call_parentheses = false 754 | ij_php_space_before_method_left_brace = true 755 | ij_php_space_before_method_parentheses = false 756 | ij_php_space_before_quest = true 757 | ij_php_space_before_short_closure_left_parenthesis = false 758 | ij_php_space_before_switch_left_brace = true 759 | ij_php_space_before_switch_parentheses = true 760 | ij_php_space_before_try_left_brace = true 761 | ij_php_space_before_unary_not = false 762 | ij_php_space_before_while_keyword = true 763 | ij_php_space_before_while_left_brace = true 764 | ij_php_space_before_while_parentheses = true 765 | ij_php_space_between_ternary_quest_and_colon = false 766 | ij_php_spaces_around_additive_operators = true 767 | ij_php_spaces_around_arrow = false 768 | ij_php_spaces_around_assignment_in_declare = false 769 | ij_php_spaces_around_assignment_operators = true 770 | ij_php_spaces_around_bitwise_operators = true 771 | ij_php_spaces_around_equality_operators = true 772 | ij_php_spaces_around_logical_operators = true 773 | ij_php_spaces_around_multiplicative_operators = true 774 | ij_php_spaces_around_null_coalesce_operator = true 775 | ij_php_spaces_around_pipe_in_union_type = false 776 | ij_php_spaces_around_relational_operators = true 777 | ij_php_spaces_around_shift_operators = true 778 | ij_php_spaces_around_unary_operator = false 779 | ij_php_spaces_around_var_within_brackets = false 780 | ij_php_spaces_within_array_initializer_braces = false 781 | ij_php_spaces_within_brackets = false 782 | ij_php_spaces_within_catch_parentheses = false 783 | ij_php_spaces_within_for_parentheses = false 784 | ij_php_spaces_within_if_parentheses = false 785 | ij_php_spaces_within_method_call_parentheses = false 786 | ij_php_spaces_within_method_parentheses = false 787 | ij_php_spaces_within_parentheses = false 788 | ij_php_spaces_within_short_echo_tags = true 789 | ij_php_spaces_within_switch_parentheses = false 790 | ij_php_spaces_within_while_parentheses = false 791 | ij_php_special_else_if_treatment = false 792 | ij_php_subpackage_weight = 28 793 | ij_php_ternary_operation_signs_on_next_line = false 794 | ij_php_ternary_operation_wrap = off 795 | ij_php_throws_weight = 2 796 | ij_php_todo_weight = 28 797 | ij_php_unknown_tag_weight = 28 798 | ij_php_upper_case_boolean_const = false 799 | ij_php_upper_case_null_const = false 800 | ij_php_uses_weight = 28 801 | ij_php_var_weight = 28 802 | ij_php_variable_naming_style = mixed 803 | ij_php_version_weight = 28 804 | ij_php_while_brace_force = always 805 | ij_php_while_on_new_line = false 806 | 807 | [{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}] 808 | indent_size = 2 809 | ij_json_keep_blank_lines_in_code = 0 810 | ij_json_keep_indents_on_empty_lines = false 811 | ij_json_keep_line_breaks = true 812 | ij_json_space_after_colon = true 813 | ij_json_space_after_comma = true 814 | ij_json_space_before_colon = true 815 | ij_json_space_before_comma = false 816 | ij_json_spaces_within_braces = false 817 | ij_json_spaces_within_brackets = false 818 | ij_json_wrap_long_lines = false 819 | 820 | [{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] 821 | ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 822 | ij_html_align_attributes = true 823 | ij_html_align_text = false 824 | ij_html_attribute_wrap = normal 825 | ij_html_block_comment_at_first_column = true 826 | ij_html_do_not_align_children_of_min_lines = 0 827 | ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p 828 | ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot 829 | ij_html_enforce_quotes = false 830 | ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var 831 | ij_html_keep_blank_lines = 2 832 | ij_html_keep_indents_on_empty_lines = false 833 | ij_html_keep_line_breaks = true 834 | ij_html_keep_line_breaks_in_text = true 835 | ij_html_keep_whitespaces = false 836 | ij_html_keep_whitespaces_inside = span,pre,textarea 837 | ij_html_line_comment_at_first_column = true 838 | ij_html_new_line_after_last_attribute = never 839 | ij_html_new_line_before_first_attribute = never 840 | ij_html_quote_style = double 841 | ij_html_remove_new_line_before_tags = br 842 | ij_html_space_after_tag_name = false 843 | ij_html_space_around_equality_in_attribute = false 844 | ij_html_space_inside_empty_tag = false 845 | ij_html_text_wrap = normal 846 | 847 | [{*.markdown,*.md}] 848 | ij_markdown_force_one_space_after_blockquote_symbol = true 849 | ij_markdown_force_one_space_after_header_symbol = true 850 | ij_markdown_force_one_space_after_list_bullet = true 851 | ij_markdown_force_one_space_between_words = true 852 | ij_markdown_keep_indents_on_empty_lines = false 853 | ij_markdown_max_lines_around_block_elements = 1 854 | ij_markdown_max_lines_around_header = 1 855 | ij_markdown_max_lines_between_paragraphs = 1 856 | ij_markdown_min_lines_around_block_elements = 1 857 | ij_markdown_min_lines_around_header = 1 858 | ij_markdown_min_lines_between_paragraphs = 1 859 | 860 | [{*.yaml,*.yml}] 861 | indent_size = 2 862 | ij_yaml_align_values_properties = do_not_align 863 | ij_yaml_autoinsert_sequence_marker = true 864 | ij_yaml_block_mapping_on_new_line = false 865 | ij_yaml_indent_sequence_value = true 866 | ij_yaml_keep_indents_on_empty_lines = false 867 | ij_yaml_keep_line_breaks = true 868 | ij_yaml_sequence_on_new_line = false 869 | ij_yaml_space_before_colon = false 870 | ij_yaml_spaces_within_braces = true 871 | ij_yaml_spaces_within_brackets = true 872 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | SPACES_KEY= 2 | SPACES_SECRET= 3 | 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: [ bug, triage ] 5 | assignees: 6 | - MacroMan 7 | body: 8 | - type: textarea 9 | id: what-happened 10 | attributes: 11 | label: What happened? 12 | description: Please provide all information required to reproduce the bug 13 | validations: 14 | required: true 15 | - type: dropdown 16 | id: version 17 | attributes: 18 | label: Version 19 | description: What version of Spaces-API is this occuring on? Versions below 3 will not be fixed. Please upgrade. 20 | options: 21 | - 3.5.0 22 | - 3.4.0 23 | - 3.3.0 24 | - 3.2.0 25 | - 3.1.0 26 | - 3.0.0 27 | validations: 28 | required: true 29 | - type: input 30 | id: php-version 31 | attributes: 32 | label: What version of PHP are you using? 33 | - type: textarea 34 | id: logs 35 | attributes: 36 | label: Relevant log output 37 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 38 | render: shell 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Request new functionality 3 | title: "[Feature]: " 4 | labels: [ new ] 5 | assignees: 6 | - MacroMan 7 | body: 8 | - type: textarea 9 | id: idea 10 | attributes: 11 | label: Description 12 | description: Please provide as much detail as you can about what you'd like to see. If you can, a pull request is the fastest way to add new features. 13 | validations: 14 | required: true 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | vendor/ 3 | .idea/ 4 | .env 5 | .phpunit.result.cache 6 | -------------------------------------------------------------------------------- /.phpdoc-md: -------------------------------------------------------------------------------- 1 | 'SpacesAPI', 5 | 'destDirectory' => 'docs', 6 | 'format' => 'github', 7 | 'classes' => [ 8 | '\SpacesAPI\Spaces', 9 | '\SpacesAPI\Space', 10 | '\SpacesAPI\File', 11 | ], 12 | ]; 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Devang Srivastava 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This library is deprecated 2 | We recommend using the [official SDK](https://github.com/DigitalOceanPHP/Client) or the [Laravel package](https://github.com/GrahamCampbell/Laravel-DigitalOcean) 3 | 4 | All issues will be closed and new PRs will not be accepted 5 | 6 | ## Installation 7 | Install via composer 8 | ``` 9 | composer require sociallydev/spaces-api 10 | ``` 11 | 12 | ## Quick start 13 | 14 | Obtain API keys from the [Digital Ocean Applications & API dashboard](https://cloud.digitalocean.com/account/api/tokens) 15 | 16 | ```php 17 | use SpacesAPI\Spaces; 18 | 19 | // Connect to a space 20 | $spaces = new Spaces('api-key', 'api-secret'); 21 | $space = $spaces->space('space-name'); 22 | 23 | // Download a file 24 | $file = $space->file('remote-file-1.txt'); 25 | $file->download('local/file/path/file.txt'); 26 | 27 | // Upload text to a file 28 | $file2 = $space->uploadText("Lorem ipsum","remote-file-2.txt"); 29 | 30 | // Get a signed public link, valid for 2 hours 31 | $file2url = $file2->getSignedURL("2 hours"); 32 | 33 | // Make a copy 34 | $file3 = $file2->copy('remote-file-3.txt'); 35 | 36 | // Move or rename a file 37 | $file2->move('new-filename.txt') 38 | 39 | // Make a file public and get the URL 40 | $file3->makePublic(); 41 | $file3url = $file3->getURL(); 42 | ``` 43 | 44 | See more examples in [docs/Examples.md](docs/Examples.md) 45 | 46 | ## Upgrading? 47 | Version 3 has many changes over version 2, so we have written a [migration guide](docs/Upgrade2-3.md) 48 | 49 | ## API reference 50 | * [\SpacesAPI\Spaces](docs/Spaces.md) 51 | * [\SpacesAPI\Space](docs/Space.md) 52 | * [\SpacesAPI\File](docs/File.md) 53 | -------------------------------------------------------------------------------- /SpacesAPI/Exceptions/AuthenticationException.php: -------------------------------------------------------------------------------- 1 | space = $space; 61 | $this->space_name = $space->getName(); 62 | $this->s3 = $space->getS3Client(); 63 | $this->_filename = $filename; 64 | 65 | if ($validate && !$this->s3->doesObjectExist($this->space_name, $filename)) { 66 | throw new FileDoesntExistException("File $filename doesn't exist"); 67 | } 68 | 69 | if (count($info) > 0) { 70 | $this->setFileInfo($info); 71 | } 72 | } 73 | 74 | /** 75 | * Magic getter to make the properties read-only 76 | * 77 | * @param string $name 78 | * 79 | * @return null 80 | */ 81 | public function __get(string $name) 82 | { 83 | if (!property_exists($this, "_$name")) { 84 | trigger_error("Undefined property: SpacesAPI\File::$name", E_USER_NOTICE); 85 | return null; 86 | } 87 | 88 | if (!$this->{"_$name"}) { 89 | $this->fetchFileInfo(); 90 | } 91 | 92 | return $this->{"_$name"}; 93 | } 94 | 95 | /** 96 | * @param array $info 97 | */ 98 | private function setFileInfo(array $info): void 99 | { 100 | foreach ($info as $_property => $value) { 101 | $property = "_" . $this->pascalCaseToCamelCase($_property); 102 | 103 | if ($property == 'size') { 104 | $property = 'content_length'; 105 | } 106 | 107 | if (property_exists($this, $property)) { 108 | $this->$property = $value; 109 | } 110 | } 111 | } 112 | 113 | /** 114 | * 115 | */ 116 | private function fetchFileInfo(): void 117 | { 118 | $this->setFileInfo( 119 | Result::parse( 120 | $this->s3->headObject([ 121 | "Bucket" => $this->space_name, 122 | "Key" => $this->_filename, 123 | ]) 124 | ) 125 | ); 126 | } 127 | 128 | /** 129 | * Is this file publicly accessible 130 | * 131 | * @return bool 132 | */ 133 | public function isPublic(): bool 134 | { 135 | $acl = Result::parse( 136 | $this->s3->getObjectAcl([ 137 | "Bucket" => $this->space_name, 138 | "Key" => $this->_filename, 139 | ]) 140 | ); 141 | 142 | return ( 143 | isset($acl['Grants'][0]['Grantee']['URI']) && 144 | $acl['Grants'][0]['Grantee']['URI'] == "http://acs.amazonaws.com/groups/global/AllUsers" && 145 | $acl['Grants'][0]['Permission'] == "READ" 146 | ); 147 | } 148 | 149 | /** 150 | * Make a file public or privately accessible 151 | * 152 | * @param bool $public 153 | */ 154 | private function updatePrivacy(bool $public): void 155 | { 156 | $this->s3->putObjectAcl([ 157 | "Bucket" => $this->space_name, 158 | "Key" => $this->_filename, 159 | "ACL" => ($public) ? "public-read" : "private", 160 | ]); 161 | } 162 | 163 | /** 164 | * Make file publicly accessible 165 | */ 166 | public function makePublic(): void 167 | { 168 | $this->updatePrivacy(true); 169 | } 170 | 171 | /** 172 | * Make file non-publicly accessible 173 | */ 174 | public function makePrivate(): void 175 | { 176 | $this->updatePrivacy(false); 177 | } 178 | 179 | /** 180 | * Get the file contents as a string 181 | * 182 | * @return string 183 | */ 184 | public function getContents(): string 185 | { 186 | return $this->s3->getObject([ 187 | "Bucket" => $this->space_name, 188 | "Key" => $this->_filename, 189 | ])["Body"]->getContents(); 190 | } 191 | 192 | /** 193 | * Download the file to a local location 194 | * 195 | * @param string $saveAs 196 | * 197 | * @return void 198 | */ 199 | public function download(string $saveAs): void 200 | { 201 | $this->s3->getObject([ 202 | "Bucket" => $this->space_name, 203 | "Key" => $this->_filename, 204 | "SaveAs" => $saveAs, 205 | ]); 206 | } 207 | 208 | /** 209 | * Copy the file on the space 210 | * 211 | * @param string $newFilename 212 | * @param false $public 213 | * 214 | * @return \SpacesAPI\File 215 | */ 216 | public function copy(string $newFilename): File 217 | { 218 | $this->s3->copy( 219 | $this->space_name, 220 | $this->_filename, 221 | $this->space_name, 222 | $newFilename, 223 | ($this->isPublic()) ? 'public-read' : 'private' 224 | ); 225 | 226 | return new self($this->space, $newFilename); 227 | } 228 | 229 | /** 230 | * @param string $newFilename 231 | * 232 | * @return \SpacesAPI\File 233 | */ 234 | public function move(string $newFilename): File 235 | { 236 | $this->copy($newFilename); 237 | $this->delete(); 238 | $this->_filename = $newFilename; 239 | $this->fetchFileInfo(); 240 | 241 | return $this; 242 | } 243 | 244 | /** 245 | * Get the public URL 246 | * This URL will not work if the file is private 247 | * 248 | * @return string 249 | * @see getSignedURL 250 | * 251 | */ 252 | public function getURL(): string 253 | { 254 | return $this->s3->getObjectUrl($this->space_name, $this->_filename); 255 | } 256 | 257 | /** 258 | * Get a signed URL, which will work for private files 259 | * 260 | * @param string|\DateTime|int $validFor Can be any string recognised by strtotime(), an instance of DateTime or a unix timestamp 261 | * 262 | * @return string 263 | */ 264 | public function getSignedURL($validFor = "15 minutes"): string 265 | { 266 | return (string)$this->s3->createPresignedRequest( 267 | $this->s3->getCommand("GetObject", [ 268 | "Bucket" => $this->space_name, 269 | "Key" => $this->_filename, 270 | ]), 271 | $validFor 272 | )->getUri(); 273 | } 274 | 275 | /** 276 | * Permanently delete this file 277 | */ 278 | public function delete(): void 279 | { 280 | $this->s3->deleteObject([ 281 | "Bucket" => $this->space_name, 282 | "Key" => $this->_filename, 283 | ]); 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /SpacesAPI/Result.php: -------------------------------------------------------------------------------- 1 | toArray(); 22 | } 23 | 24 | foreach ($data as $key => $value) { 25 | if (is_array($value)) { 26 | $data[$key] = self::parse($value); 27 | continue; 28 | } 29 | 30 | if (gettype($value) == "object" && get_class($value) == DateTimeResult::class) { 31 | $data[$key] = strtotime($value); 32 | } 33 | } 34 | 35 | return $data; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SpacesAPI/Space.php: -------------------------------------------------------------------------------- 1 | s3 = $s3; 46 | $this->name = $name; 47 | 48 | if ($validate && !$this->s3->doesBucketExist($name)) { 49 | throw new SpaceDoesntExistException("Space '$this->name' does not exist"); 50 | } 51 | } 52 | 53 | /** 54 | * Get the current AWS S3 client instance 55 | * 56 | * For internal library use 57 | * 58 | * @return \Aws\S3\S3Client 59 | */ 60 | public function getS3Client(): S3Client 61 | { 62 | return $this->s3; 63 | } 64 | 65 | /** 66 | * Get the name of this space 67 | * 68 | * @return string 69 | */ 70 | public function getName(): string 71 | { 72 | return $this->name; 73 | } 74 | 75 | /** 76 | * Update space privacy 77 | * 78 | * @param bool $public 79 | */ 80 | private function updatePrivacy(bool $public): void 81 | { 82 | $this->s3->putBucketAcl([ 83 | "Bucket" => $this->name, 84 | "ACL" => ($public) ? "public-read" : "private", 85 | ]); 86 | } 87 | 88 | /** 89 | * Enable file listing 90 | */ 91 | public function makePublic(): void 92 | { 93 | $this->updatePrivacy(true); 94 | } 95 | 96 | /** 97 | * Disable file listing 98 | */ 99 | public function makePrivate(): void 100 | { 101 | $this->updatePrivacy(false); 102 | } 103 | 104 | /** 105 | * Is file listing enabled? 106 | * 107 | * @return bool 108 | */ 109 | public function isPublic(): bool 110 | { 111 | $acl = Result::parse($this->s3->getBucketAcl(["Bucket" => $this->name])); 112 | 113 | return ( 114 | isset($acl['Grants'][0]['Grantee']['URI']) && 115 | $acl['Grants'][0]['Grantee']['URI'] == "http://acs.amazonaws.com/groups/global/AllUsers" && 116 | $acl['Grants'][0]['Permission'] == "READ" 117 | ); 118 | } 119 | 120 | /** 121 | * Destroy/Delete this space, along with all files 122 | */ 123 | public function destroy(): void 124 | { 125 | $this->s3->deleteMatchingObjects($this->name, "", "(.*?)"); 126 | $this->s3->deleteBucket(["Bucket" => $this->name]); 127 | } 128 | 129 | /** 130 | * Get the CORS configuration for the space 131 | * 132 | * @return array|null An array of CORS rules or null if no rules exist 133 | */ 134 | public function getCORS(): ?array 135 | { 136 | try { 137 | return Result::parse( 138 | $this->s3->getBucketCors([ 139 | "Bucket" => $this->name, 140 | ]) 141 | )['CORSRules']; 142 | } catch (S3Exception $e) { 143 | return null; 144 | } 145 | } 146 | 147 | /** 148 | * Get the CORS rules, removing the origin specified 149 | * 150 | * @param string $origin 151 | * 152 | * @return array 153 | */ 154 | private function getCORSRemovingOrigin(string $origin): array 155 | { 156 | if (!$CORSRules = $this->getCORS()) { 157 | return []; 158 | } 159 | 160 | foreach ($CORSRules as $i => $cors) { 161 | if ($cors['AllowedOrigins'][0] == $origin) { 162 | array_splice($CORSRules, $i, 1); 163 | } 164 | } 165 | 166 | return $CORSRules; 167 | } 168 | 169 | /** 170 | * Set the CORS rules 171 | * 172 | * @param array $rules 173 | */ 174 | private function putCORS(array $rules): void 175 | { 176 | $this->s3->putBucketCors([ 177 | "Bucket" => $this->name, 178 | "CORSConfiguration" => [ 179 | "CORSRules" => $rules, 180 | ], 181 | ]); 182 | } 183 | 184 | /** 185 | * Add an origin to the CORS settings on this space 186 | * 187 | * @param string $origin eg `http://example.com` 188 | * @param array $methods Array items must be one of `GET`, `PUT`, `DELETE`, `POST` and `HEAD` 189 | * @param int $maxAge Access Control Max Age 190 | * @param array $headers Allowed Headers 191 | */ 192 | public function addCORSOrigin(string $origin, array $methods, int $maxAge = 0, array $headers = []): void 193 | { 194 | $rules = $this->getCORSRemovingOrigin($origin); 195 | 196 | $this->putCORS( 197 | array_merge($rules, [ 198 | [ 199 | "AllowedHeaders" => $headers, 200 | "AllowedMethods" => $methods, 201 | "AllowedOrigins" => [$origin], 202 | "MaxAgeSeconds" => $maxAge, 203 | ], 204 | ]) 205 | ); 206 | } 207 | 208 | /** 209 | * Remove an origin from the CORS settings on this space 210 | * 211 | * @param string $origin eg `http://example.com` 212 | */ 213 | public function removeCORSOrigin(string $origin): void 214 | { 215 | $rules = $this->getCORSRemovingOrigin($origin); 216 | 217 | if (empty($rules)) { 218 | $this->removeAllCORSOrigins(); 219 | } else { 220 | $this->putCORS($rules); 221 | } 222 | } 223 | 224 | /** 225 | * Delete all CORS rules 226 | */ 227 | public function removeAllCORSOrigins(): void 228 | { 229 | $this->s3->deleteBucketCors([ 230 | 'Bucket' => $this->name, 231 | ]); 232 | } 233 | 234 | /** 235 | * List all files in the space (recursively) 236 | * 237 | * @param string $directory The directory to list files in. Empty string for root directory 238 | * 239 | * @return array 240 | */ 241 | public function listFiles(string $directory = ""): array 242 | { 243 | $rawFiles = $this->rawListFiles($directory); 244 | $files = []; 245 | 246 | foreach ($rawFiles as $fileInfo) { 247 | $files[$fileInfo['Key']] = new File($this, $fileInfo['Key'], $fileInfo, false); 248 | } 249 | 250 | return ['files' => $files]; 251 | } 252 | 253 | /** 254 | * @param string $directory The directory to list files in. Empty string for root directory 255 | * @param string|null $continuationToken Used internally to work around request limits (1000 files per request) 256 | * 257 | * @return array 258 | */ 259 | private function rawListFiles(string $directory = "", ?string $continuationToken = null): array 260 | { 261 | $data = Result::parse( 262 | $this->s3->listObjectsV2([ 263 | "Bucket" => $this->name, 264 | "Prefix" => $directory, 265 | "MaxKeys" => 1000, 266 | // "StartAfter" => 0, // For skipping files, maybe for future limit/skip ability 267 | "FetchOwner" => false, 268 | "ContinuationToken" => $continuationToken, 269 | ]) 270 | ); 271 | 272 | if (!isset($data['Contents'])) { 273 | return []; 274 | } 275 | 276 | $files = $data['Contents']; 277 | 278 | if (isset($data["NextContinuationToken"]) && $data["NextContinuationToken"] != "") { 279 | $files = array_merge($files, $this->rawListFiles($directory, $data["NextContinuationToken"])); 280 | } 281 | 282 | return $files; 283 | } 284 | 285 | /** 286 | * Upload a string of text to file 287 | * 288 | * @param string $text The text to upload 289 | * @param string $filename The filepath/name to save to 290 | * @param array $params Any extra parameters. [See here](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property) 291 | * @param bool $private True for the file to be private, false to allow public access 292 | * 293 | * @return \SpacesAPI\File 294 | */ 295 | public function uploadText(string $text, string $filename, array $params = [], bool $private = true): File 296 | { 297 | $this->s3->upload($this->name, $filename, $text, ($private) ? 'private' : 'public-read', $params); 298 | return new File($this, $filename, [], false); 299 | } 300 | 301 | /** 302 | * Upload a file 303 | * 304 | * @param string $filepath The path to the file, including the filename. Relative and absolute paths are accepted. 305 | * @param string|null $filename The remote filename. If `null`, the local filename will be used. 306 | * @param string|null $mimeType The file mime type to pass as ContentType for the file (e.g. 'image/jpeg'). 307 | * @param bool $private True for the file to be private, false to allow public access. 308 | * 309 | * @return \SpacesAPI\File 310 | */ 311 | public function uploadFile(string $filepath, ?string $filename = null, ?string $mimeType = null, bool $private = true): File 312 | { 313 | $this->s3->putObject([ 314 | 'Bucket' => $this->name, 315 | 'Key' => ($filename) ?: basename($filepath), 316 | 'SourceFile' => $filepath, 317 | 'ContentType' => $mimeType, 318 | 'ACL' => ($private) ? 'private' : 'public-read' 319 | ]); 320 | 321 | return new File($this, ($filename) ?: basename($filepath), [], false); 322 | } 323 | 324 | /** 325 | * Get an instance of \SpacesAPI\File for a given filename 326 | * 327 | * @param string $filename 328 | * @package bool $validate 329 | * 330 | * @return \SpacesAPI\File 331 | * @throws \SpacesAPI\Exceptions\FileDoesntExistException Thrown if the file doesn't exist 332 | */ 333 | public function file(string $filename, bool $validate = true): File 334 | { 335 | return new File($this, $filename, [], $validate); 336 | } 337 | 338 | /** 339 | * Recursively upload an entire directory 340 | * 341 | * @param string $local The local directory to upload 342 | * @param string|null $remote The remote directory to place the files in. `null` to place in the root 343 | */ 344 | public function uploadDirectory(string $local, ?string $remote = null): void 345 | { 346 | $this->s3->uploadDirectory($local, $this->name, $remote); 347 | } 348 | 349 | /** 350 | * Recursively download an entire directory. 351 | * 352 | * @param string $local The local directory to save the directories/files in 353 | * @param string|null $remote The remote directory to download. `null` to download the entire space 354 | */ 355 | public function downloadDirectory(string $local, ?string $remote = null): void 356 | { 357 | $this->s3->downloadBucket($local, $this->name, $remote); 358 | } 359 | 360 | /** 361 | * Delete an entire directory, including its contents 362 | * 363 | * @param string $path The directory to delete 364 | */ 365 | public function deleteDirectory(string $path): void 366 | { 367 | $this->s3->deleteMatchingObjects($this->name, $path); 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /SpacesAPI/Spaces.php: -------------------------------------------------------------------------------- 1 | s3 = new S3Client([ 38 | "version" => "latest", 39 | "region" => $region, 40 | "endpoint" => "https://$region.$host", 41 | "credentials" => ["key" => $accessKey, "secret" => $secretKey], 42 | "ua_append" => "SociallyDev-Spaces-API/2", 43 | ]); 44 | 45 | try { 46 | $this->s3->headBucket(["Bucket" => 'auth-check']); 47 | } catch (S3Exception $e) { 48 | if ($e->getStatusCode() == 403) { 49 | throw new AuthenticationException("Authentication failed"); 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * List all your spaces 56 | * 57 | * @return array An array of \SpacesAPI\Space instances 58 | */ 59 | public function list(): array 60 | { 61 | $spaces = []; 62 | 63 | foreach (Result::parse($this->s3->listBuckets()['Buckets']) as $bucket) { 64 | $spaces[$bucket['Name']] = new Space($this->s3, $bucket['Name'], false); 65 | } 66 | 67 | return $spaces; 68 | } 69 | 70 | /** 71 | * Create a new space 72 | * 73 | * @param string $name The name of the new space 74 | * @param bool $public Enable file listing. Default `false` 75 | * 76 | * @return \SpacesAPI\Space The newly created space 77 | * @throws \SpacesAPI\Exceptions\SpaceExistsException The named space already exists 78 | */ 79 | public function create(string $name, bool $public = false): Space 80 | { 81 | try { 82 | $this->s3->createBucket([ 83 | "ACL" => ($public) ? "public-read" : "private", 84 | "Bucket" => $name, 85 | ]); 86 | } catch (S3Exception $e) { 87 | throw new SpaceExistsException($e->getAwsErrorMessage()); 88 | } 89 | 90 | return new Space($this->s3, $name, false); 91 | } 92 | 93 | /** 94 | * Use an existing space 95 | * 96 | * @param string $name The name of the space 97 | * 98 | * @return \SpacesAPI\Space The loaded space 99 | * @throws \SpacesAPI\Exceptions\SpaceDoesntExistException The named space doesn't exist 100 | */ 101 | public function space(string $name): Space 102 | { 103 | return new Space($this->s3, $name); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /SpacesAPI/StringFunctions.php: -------------------------------------------------------------------------------- 1 | =7.3", 26 | "aws/aws-sdk-php": "^3.52" 27 | }, 28 | "require-dev": { 29 | "clean/phpdoc-md": "^0.19.1", 30 | "phpunit/phpunit": "^9.5.13", 31 | "vlucas/phpdotenv": "^v5.4.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/Examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | ## Connecting to Digital Ocean and selecting a space 4 | 5 | ```php 6 | use SpacesAPI\Spaces; 7 | 8 | $spaces = new Spaces('api-key', 'api-secret'); 9 | $space = $spaces->space('space-name'); 10 | ``` 11 | [API docs for \SpacesAPI\Spaces](Spaces.md) 12 | 13 | ## Creating a new space 14 | ```php 15 | $spaces = new Spaces('api-key', 'api-secret'); 16 | $space = $spaces->create('new-space-name'); 17 | ``` 18 | [API docs for creating a space](Spaces.md#spacescreate) 19 | 20 | ## Listing files 21 | 22 | ```php 23 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 24 | $files = $space->listFiles(); 25 | 26 | foreach ($files['files'] as $file) { 27 | echo "{$file->filename}\n"; 28 | } 29 | ``` 30 | [API docs for listing files](Space.md#spacelistfiles) 31 | 32 | ## Uploading a file 33 | 34 | ```php 35 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 36 | $file = $space->uploadFile('./localfile.txt', 'remote-filename.txt'); 37 | ``` 38 | [API docs for uploading files](Space.md#spaceuploadfile) 39 | 40 | ## Uploading text to a file 41 | ```php 42 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 43 | $file = $space->uploadText('Lorem ipsum', 'remote-filename.txt'); 44 | ``` 45 | 46 | [API docs for uploading text](Space.md#spaceuploadtext) 47 | 48 | ## Downloading a file 49 | ```php 50 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 51 | $space->file('filename.txt')->download('./localfile.txt'); 52 | ``` 53 | 54 | [API docs for downloading a file](File.md#filedownload) 55 | 56 | ## Get the contents of a file 57 | 58 | ```php 59 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 60 | echo $space->file('filename.txt')->getContents(); 61 | ``` 62 | 63 | [API docs for getting the contents of a file](File.md#filegetcontents) 64 | 65 | ## Deleting a file 66 | ```php 67 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 68 | $space->file('filename.txt')->delete(); 69 | ``` 70 | 71 | [API docs for deleting a file](File.md#filedelete) 72 | 73 | ## Get a public URL 74 | 75 | ```php 76 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 77 | $space->file('filename.txt')->getURL(); 78 | ``` 79 | 80 | [API docs for getting the public URL](File.md#filegeturl) 81 | 82 | ## Get a signed URL 83 | #### a time limited link to provide access to a private file 84 | 85 | ```php 86 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 87 | $space->file('filename.txt')->getSignedURL("1 day"); 88 | ``` 89 | 90 | [API docs for getting a signed URL](File.md#filegetsignedurl) 91 | 92 | ## Make a file publicly accessible 93 | ```php 94 | $space = new Spaces('api-key', 'api-secret')->space('my-space-name'); 95 | $space->file('filename.txt')->makePublic(); 96 | ``` 97 | 98 | [API docs for setting file privacy](File.md#spacemakeprivate) 99 | -------------------------------------------------------------------------------- /docs/File.md: -------------------------------------------------------------------------------- 1 | # SpacesAPI\File 2 | 3 | Represents a single file 4 | 5 | You wouldn't normally instantiate this class directly, 6 | Rather obtain an instance from `\SpacesAPI\Space::list()`, `\SpacesAPI\Spaces::file()`, `\SpacesAPI\Spaces::uploadText()` or `\SpacesAPI\Spaces::uploadFile()` 7 | 8 | 9 | ## Properties 10 | | name | Type | Description | 11 | | --- | --- | --- | 12 | | `expiration` | `string` | | 13 | | `e_tag` | `string` | | 14 | | `last_modified` | `int` | Last modified date as unix timestamp | 15 | | `content_type` | `string` | THe mime type of the file | 16 | | `content_length` | `int` | The size of the file in bytes | 17 | 18 | 19 | ## Methods 20 | 21 | | Name | Description | 22 | |------|-------------| 23 | |[__construct](#file__construct)|| 24 | |[copy](#filecopy)|Copy the file on the space| 25 | |[delete](#filedelete)|Permanently delete this file| 26 | |[download](#filedownload)|Download the file to a local location| 27 | |[getContents](#filegetcontents)|Get the file contents as a string| 28 | |[getSignedURL](#filegetsignedurl)|Get a signed URL, which will work for private files| 29 | |[getURL](#filegeturl)|Get the public URL. This URL will not work if the file is private| 30 | |[isPublic](#fileispublic)|Is this file publicly accessible| 31 | |[makePrivate](#filemakeprivate)|Make file non-publicly accessible| 32 | |[makePublic](#filemakepublic)|Make file publicly accessible| 33 | |[move](#filemove)|Move and/or rename file| 34 | 35 | 36 | 37 | 38 | ### File::__construct 39 | 40 | **Description** 41 | 42 | ```php 43 | __construct (\SpacesAPI\Space $space, string $filename, array $info = [], bool $validate = true) 44 | ``` 45 | 46 | **Parameters** 47 | 48 | * `(\SpacesAPI\Space) $space` : An instance of `\SpacesAPI\Space` 49 | * `(string) $filename` : The filename of a file 50 | * `(array) $info` : Any information already known about the file (eg content_length, content_type, etc). Default `[]` 51 | * `(bool) $validate` : Check that the file exists. Default `true` 52 | 53 | **Return Values** 54 | 55 | `void` 56 | 57 | **Throws Exceptions** 58 | 59 | `\SpacesAPI\Exceptions\FileDoesntExistException` : If validation is `true` and the file doesn't exist 60 | 61 | 62 |