Repository: SociallyDev/Spaces-API
Branch: master
Commit: 6b0f8f5e0344
Files: 27
Total size: 105.0 KB
Directory structure:
gitextract_zsmmkxin/
├── .editorconfig
├── .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
├── docs/
│ ├── Examples.md
│ ├── File.md
│ ├── Space.md
│ ├── Spaces.md
│ └── Upgrade2-3.md
└── tests/
├── FileTest.php
├── SpaceTest.php
└── SpacesTest.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 600
tab_width = 4
trim_trailing_whitespace = true
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false
ij_smart_tabs = false
ij_visual_guides = none
ij_wrap_on_typing = false
[*.blade.php]
ij_blade_keep_indents_on_empty_lines = false
[*.css]
ij_css_align_closing_brace_with_properties = false
ij_css_blank_lines_around_nested_selector = 1
ij_css_blank_lines_between_blocks = 1
ij_css_brace_placement = end_of_line
ij_css_enforce_quotes_on_format = false
ij_css_hex_color_long_format = true
ij_css_hex_color_lower_case = false
ij_css_hex_color_short_format = false
ij_css_hex_color_upper_case = true
ij_css_keep_blank_lines_in_code = 2
ij_css_keep_indents_on_empty_lines = false
ij_css_keep_single_line_blocks = false
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
ij_css_space_after_colon = true
ij_css_space_before_opening_brace = true
ij_css_use_double_quotes = true
ij_css_value_alignment = do_not_align
[*.feature]
indent_size = 2
ij_gherkin_keep_indents_on_empty_lines = false
[*.haml]
indent_size = 2
ij_haml_keep_indents_on_empty_lines = false
[*.less]
indent_size = 2
ij_less_align_closing_brace_with_properties = false
ij_less_blank_lines_around_nested_selector = 1
ij_less_blank_lines_between_blocks = 1
ij_less_brace_placement = 0
ij_less_enforce_quotes_on_format = false
ij_less_hex_color_long_format = true
ij_less_hex_color_lower_case = false
ij_less_hex_color_short_format = false
ij_less_hex_color_upper_case = true
ij_less_keep_blank_lines_in_code = 2
ij_less_keep_indents_on_empty_lines = false
ij_less_keep_single_line_blocks = false
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
ij_less_space_after_colon = true
ij_less_space_before_opening_brace = true
ij_less_use_double_quotes = true
ij_less_value_alignment = 0
[*.sass]
indent_size = 2
ij_sass_align_closing_brace_with_properties = false
ij_sass_blank_lines_around_nested_selector = 1
ij_sass_blank_lines_between_blocks = 1
ij_sass_brace_placement = 0
ij_sass_enforce_quotes_on_format = false
ij_sass_hex_color_long_format = false
ij_sass_hex_color_lower_case = false
ij_sass_hex_color_short_format = false
ij_sass_hex_color_upper_case = false
ij_sass_keep_blank_lines_in_code = 2
ij_sass_keep_indents_on_empty_lines = false
ij_sass_keep_single_line_blocks = false
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
ij_sass_space_after_colon = true
ij_sass_space_before_opening_brace = true
ij_sass_use_double_quotes = true
ij_sass_value_alignment = 0
[*.scss]
ij_scss_align_closing_brace_with_properties = false
ij_scss_blank_lines_around_nested_selector = 1
ij_scss_blank_lines_between_blocks = 1
ij_scss_brace_placement = 0
ij_scss_enforce_quotes_on_format = false
ij_scss_hex_color_long_format = true
ij_scss_hex_color_lower_case = false
ij_scss_hex_color_short_format = false
ij_scss_hex_color_upper_case = true
ij_scss_keep_blank_lines_in_code = 1
ij_scss_keep_indents_on_empty_lines = false
ij_scss_keep_single_line_blocks = false
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
ij_scss_space_after_colon = true
ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
ij_scss_value_alignment = 0
[*.twig]
ij_twig_keep_indents_on_empty_lines = false
ij_twig_spaces_inside_comments_delimiters = true
ij_twig_spaces_inside_delimiters = true
ij_twig_spaces_inside_variable_delimiters = true
[*.vue]
ij_continuation_indent_size = 4
ij_vue_indent_children_of_top_level = template
ij_vue_interpolation_new_line_after_start_delimiter = true
ij_vue_interpolation_new_line_before_end_delimiter = true
ij_vue_interpolation_wrap = off
ij_vue_keep_indents_on_empty_lines = false
ij_vue_spaces_within_interpolation_expressions = true
[.editorconfig]
ij_editorconfig_align_group_field_declarations = false
ij_editorconfig_space_after_colon = false
ij_editorconfig_space_after_comma = true
ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}]
ij_xml_align_attributes = true
ij_xml_align_text = false
ij_xml_attribute_wrap = normal
ij_xml_block_comment_at_first_column = true
ij_xml_keep_blank_lines = 2
ij_xml_keep_indents_on_empty_lines = false
ij_xml_keep_line_breaks = true
ij_xml_keep_line_breaks_in_text = true
ij_xml_keep_whitespaces = false
ij_xml_keep_whitespaces_around_cdata = preserve
ij_xml_keep_whitespaces_inside_cdata = false
ij_xml_line_comment_at_first_column = true
ij_xml_space_after_tag_name = false
ij_xml_space_around_equals_in_attribute = false
ij_xml_space_inside_empty_tag = false
ij_xml_text_wrap = normal
[{*.ats,*.ts}]
ij_continuation_indent_size = 4
ij_typescript_align_imports = false
ij_typescript_align_multiline_array_initializer_expression = false
ij_typescript_align_multiline_binary_operation = false
ij_typescript_align_multiline_chained_methods = false
ij_typescript_align_multiline_extends_list = false
ij_typescript_align_multiline_for = true
ij_typescript_align_multiline_parameters = true
ij_typescript_align_multiline_parameters_in_calls = false
ij_typescript_align_multiline_ternary_operation = false
ij_typescript_align_object_properties = 0
ij_typescript_align_union_types = false
ij_typescript_align_var_statements = 0
ij_typescript_array_initializer_new_line_after_left_brace = false
ij_typescript_array_initializer_right_brace_on_new_line = false
ij_typescript_array_initializer_wrap = off
ij_typescript_assignment_wrap = off
ij_typescript_binary_operation_sign_on_next_line = false
ij_typescript_binary_operation_wrap = off
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
ij_typescript_blank_lines_after_imports = 1
ij_typescript_blank_lines_around_class = 1
ij_typescript_blank_lines_around_field = 0
ij_typescript_blank_lines_around_field_in_interface = 0
ij_typescript_blank_lines_around_function = 1
ij_typescript_blank_lines_around_method = 1
ij_typescript_blank_lines_around_method_in_interface = 1
ij_typescript_block_brace_style = end_of_line
ij_typescript_call_parameters_new_line_after_left_paren = false
ij_typescript_call_parameters_right_paren_on_new_line = false
ij_typescript_call_parameters_wrap = off
ij_typescript_catch_on_new_line = false
ij_typescript_chained_call_dot_on_new_line = true
ij_typescript_class_brace_style = end_of_line
ij_typescript_comma_on_new_line = false
ij_typescript_do_while_brace_force = never
ij_typescript_else_on_new_line = false
ij_typescript_enforce_trailing_comma = keep
ij_typescript_extends_keyword_wrap = off
ij_typescript_extends_list_wrap = off
ij_typescript_field_prefix = _
ij_typescript_file_name_style = relaxed
ij_typescript_finally_on_new_line = false
ij_typescript_for_brace_force = never
ij_typescript_for_statement_new_line_after_left_paren = false
ij_typescript_for_statement_right_paren_on_new_line = false
ij_typescript_for_statement_wrap = off
ij_typescript_force_quote_style = false
ij_typescript_force_semicolon_style = false
ij_typescript_function_expression_brace_style = end_of_line
ij_typescript_if_brace_force = never
ij_typescript_import_merge_members = global
ij_typescript_import_prefer_absolute_path = global
ij_typescript_import_sort_members = true
ij_typescript_import_sort_module_name = false
ij_typescript_import_use_node_resolution = true
ij_typescript_imports_wrap = on_every_item
ij_typescript_indent_case_from_switch = true
ij_typescript_indent_chained_calls = true
ij_typescript_indent_package_children = 0
ij_typescript_jsdoc_include_types = false
ij_typescript_jsx_attribute_value = braces
ij_typescript_keep_blank_lines_in_code = 2
ij_typescript_keep_first_column_comment = true
ij_typescript_keep_indents_on_empty_lines = false
ij_typescript_keep_line_breaks = true
ij_typescript_keep_simple_blocks_in_one_line = false
ij_typescript_keep_simple_methods_in_one_line = false
ij_typescript_line_comment_add_space = true
ij_typescript_line_comment_at_first_column = false
ij_typescript_method_brace_style = end_of_line
ij_typescript_method_call_chain_wrap = off
ij_typescript_method_parameters_new_line_after_left_paren = false
ij_typescript_method_parameters_right_paren_on_new_line = false
ij_typescript_method_parameters_wrap = off
ij_typescript_object_literal_wrap = on_every_item
ij_typescript_parentheses_expression_new_line_after_left_paren = false
ij_typescript_parentheses_expression_right_paren_on_new_line = false
ij_typescript_place_assignment_sign_on_next_line = false
ij_typescript_prefer_as_type_cast = false
ij_typescript_prefer_explicit_types_function_expression_returns = false
ij_typescript_prefer_explicit_types_function_returns = false
ij_typescript_prefer_explicit_types_vars_fields = false
ij_typescript_prefer_parameters_wrap = false
ij_typescript_reformat_c_style_comments = false
ij_typescript_space_after_colon = true
ij_typescript_space_after_comma = true
ij_typescript_space_after_dots_in_rest_parameter = false
ij_typescript_space_after_generator_mult = true
ij_typescript_space_after_property_colon = true
ij_typescript_space_after_quest = true
ij_typescript_space_after_type_colon = true
ij_typescript_space_after_unary_not = false
ij_typescript_space_before_async_arrow_lparen = true
ij_typescript_space_before_catch_keyword = true
ij_typescript_space_before_catch_left_brace = true
ij_typescript_space_before_catch_parentheses = true
ij_typescript_space_before_class_lbrace = true
ij_typescript_space_before_class_left_brace = true
ij_typescript_space_before_colon = true
ij_typescript_space_before_comma = false
ij_typescript_space_before_do_left_brace = true
ij_typescript_space_before_else_keyword = true
ij_typescript_space_before_else_left_brace = true
ij_typescript_space_before_finally_keyword = true
ij_typescript_space_before_finally_left_brace = true
ij_typescript_space_before_for_left_brace = true
ij_typescript_space_before_for_parentheses = true
ij_typescript_space_before_for_semicolon = false
ij_typescript_space_before_function_left_parenth = true
ij_typescript_space_before_generator_mult = false
ij_typescript_space_before_if_left_brace = true
ij_typescript_space_before_if_parentheses = true
ij_typescript_space_before_method_call_parentheses = false
ij_typescript_space_before_method_left_brace = true
ij_typescript_space_before_method_parentheses = false
ij_typescript_space_before_property_colon = false
ij_typescript_space_before_quest = true
ij_typescript_space_before_switch_left_brace = true
ij_typescript_space_before_switch_parentheses = true
ij_typescript_space_before_try_left_brace = true
ij_typescript_space_before_type_colon = false
ij_typescript_space_before_unary_not = false
ij_typescript_space_before_while_keyword = true
ij_typescript_space_before_while_left_brace = true
ij_typescript_space_before_while_parentheses = true
ij_typescript_spaces_around_additive_operators = true
ij_typescript_spaces_around_arrow_function_operator = true
ij_typescript_spaces_around_assignment_operators = true
ij_typescript_spaces_around_bitwise_operators = true
ij_typescript_spaces_around_equality_operators = true
ij_typescript_spaces_around_logical_operators = true
ij_typescript_spaces_around_multiplicative_operators = true
ij_typescript_spaces_around_relational_operators = true
ij_typescript_spaces_around_shift_operators = true
ij_typescript_spaces_around_unary_operator = false
ij_typescript_spaces_within_array_initializer_brackets = false
ij_typescript_spaces_within_brackets = false
ij_typescript_spaces_within_catch_parentheses = false
ij_typescript_spaces_within_for_parentheses = false
ij_typescript_spaces_within_if_parentheses = false
ij_typescript_spaces_within_imports = false
ij_typescript_spaces_within_interpolation_expressions = false
ij_typescript_spaces_within_method_call_parentheses = false
ij_typescript_spaces_within_method_parentheses = false
ij_typescript_spaces_within_object_literal_braces = false
ij_typescript_spaces_within_object_type_braces = true
ij_typescript_spaces_within_parentheses = false
ij_typescript_spaces_within_switch_parentheses = false
ij_typescript_spaces_within_type_assertion = false
ij_typescript_spaces_within_union_types = true
ij_typescript_spaces_within_while_parentheses = false
ij_typescript_special_else_if_treatment = true
ij_typescript_ternary_operation_signs_on_next_line = false
ij_typescript_ternary_operation_wrap = off
ij_typescript_union_types_wrap = on_every_item
ij_typescript_use_chained_calls_group_indents = false
ij_typescript_use_double_quotes = true
ij_typescript_use_explicit_js_extension = global
ij_typescript_use_path_mapping = always
ij_typescript_use_public_modifier = false
ij_typescript_use_semicolon_after_statement = true
ij_typescript_var_declaration_wrap = normal
ij_typescript_while_brace_force = never
ij_typescript_while_on_new_line = false
ij_typescript_wrap_comments = false
[{*.bash,*.sh,*.zsh}]
indent_size = 2
tab_width = 2
ij_shell_binary_ops_start_line = false
ij_shell_keep_column_alignment_padding = false
ij_shell_minify_program = false
ij_shell_redirect_followed_by_space = false
ij_shell_switch_cases_indented = false
ij_shell_use_unix_line_separator = true
[{*.cjs,*.js}]
ij_continuation_indent_size = 4
ij_javascript_align_imports = false
ij_javascript_align_multiline_array_initializer_expression = false
ij_javascript_align_multiline_binary_operation = false
ij_javascript_align_multiline_chained_methods = false
ij_javascript_align_multiline_extends_list = false
ij_javascript_align_multiline_for = true
ij_javascript_align_multiline_parameters = true
ij_javascript_align_multiline_parameters_in_calls = false
ij_javascript_align_multiline_ternary_operation = false
ij_javascript_align_object_properties = 0
ij_javascript_align_union_types = false
ij_javascript_align_var_statements = 0
ij_javascript_array_initializer_new_line_after_left_brace = true
ij_javascript_array_initializer_right_brace_on_new_line = false
ij_javascript_array_initializer_wrap = on_every_item
ij_javascript_assignment_wrap = off
ij_javascript_binary_operation_sign_on_next_line = false
ij_javascript_binary_operation_wrap = normal
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
ij_javascript_blank_lines_after_imports = 1
ij_javascript_blank_lines_around_class = 1
ij_javascript_blank_lines_around_field = 0
ij_javascript_blank_lines_around_function = 1
ij_javascript_blank_lines_around_method = 1
ij_javascript_block_brace_style = end_of_line
ij_javascript_call_parameters_new_line_after_left_paren = false
ij_javascript_call_parameters_right_paren_on_new_line = false
ij_javascript_call_parameters_wrap = normal
ij_javascript_catch_on_new_line = false
ij_javascript_chained_call_dot_on_new_line = true
ij_javascript_class_brace_style = end_of_line
ij_javascript_comma_on_new_line = false
ij_javascript_do_while_brace_force = never
ij_javascript_else_on_new_line = false
ij_javascript_enforce_trailing_comma = whenmultiline
ij_javascript_extends_keyword_wrap = off
ij_javascript_extends_list_wrap = off
ij_javascript_field_prefix = _
ij_javascript_file_name_style = relaxed
ij_javascript_finally_on_new_line = false
ij_javascript_for_brace_force = never
ij_javascript_for_statement_new_line_after_left_paren = false
ij_javascript_for_statement_right_paren_on_new_line = false
ij_javascript_for_statement_wrap = off
ij_javascript_force_quote_style = true
ij_javascript_force_semicolon_style = true
ij_javascript_function_expression_brace_style = end_of_line
ij_javascript_if_brace_force = never
ij_javascript_import_merge_members = global
ij_javascript_import_prefer_absolute_path = global
ij_javascript_import_sort_members = true
ij_javascript_import_sort_module_name = false
ij_javascript_import_use_node_resolution = true
ij_javascript_imports_wrap = on_every_item
ij_javascript_indent_case_from_switch = true
ij_javascript_indent_chained_calls = true
ij_javascript_indent_package_children = 0
ij_javascript_jsx_attribute_value = braces
ij_javascript_keep_blank_lines_in_code = 1
ij_javascript_keep_first_column_comment = true
ij_javascript_keep_indents_on_empty_lines = false
ij_javascript_keep_line_breaks = true
ij_javascript_keep_simple_blocks_in_one_line = false
ij_javascript_keep_simple_methods_in_one_line = false
ij_javascript_line_comment_add_space = true
ij_javascript_line_comment_at_first_column = false
ij_javascript_method_brace_style = end_of_line
ij_javascript_method_call_chain_wrap = on_every_item
ij_javascript_method_parameters_new_line_after_left_paren = true
ij_javascript_method_parameters_right_paren_on_new_line = false
ij_javascript_method_parameters_wrap = normal
ij_javascript_object_literal_wrap = on_every_item
ij_javascript_parentheses_expression_new_line_after_left_paren = false
ij_javascript_parentheses_expression_right_paren_on_new_line = false
ij_javascript_place_assignment_sign_on_next_line = false
ij_javascript_prefer_as_type_cast = false
ij_javascript_prefer_explicit_types_function_expression_returns = false
ij_javascript_prefer_explicit_types_function_returns = false
ij_javascript_prefer_explicit_types_vars_fields = false
ij_javascript_prefer_parameters_wrap = false
ij_javascript_reformat_c_style_comments = false
ij_javascript_space_after_colon = true
ij_javascript_space_after_comma = true
ij_javascript_space_after_dots_in_rest_parameter = false
ij_javascript_space_after_generator_mult = true
ij_javascript_space_after_property_colon = true
ij_javascript_space_after_quest = true
ij_javascript_space_after_type_colon = true
ij_javascript_space_after_unary_not = false
ij_javascript_space_before_async_arrow_lparen = true
ij_javascript_space_before_catch_keyword = true
ij_javascript_space_before_catch_left_brace = true
ij_javascript_space_before_catch_parentheses = true
ij_javascript_space_before_class_lbrace = true
ij_javascript_space_before_class_left_brace = true
ij_javascript_space_before_colon = true
ij_javascript_space_before_comma = false
ij_javascript_space_before_do_left_brace = true
ij_javascript_space_before_else_keyword = true
ij_javascript_space_before_else_left_brace = true
ij_javascript_space_before_finally_keyword = true
ij_javascript_space_before_finally_left_brace = true
ij_javascript_space_before_for_left_brace = true
ij_javascript_space_before_for_parentheses = true
ij_javascript_space_before_for_semicolon = false
ij_javascript_space_before_function_left_parenth = false
ij_javascript_space_before_generator_mult = false
ij_javascript_space_before_if_left_brace = true
ij_javascript_space_before_if_parentheses = true
ij_javascript_space_before_method_call_parentheses = false
ij_javascript_space_before_method_left_brace = true
ij_javascript_space_before_method_parentheses = false
ij_javascript_space_before_property_colon = false
ij_javascript_space_before_quest = true
ij_javascript_space_before_switch_left_brace = true
ij_javascript_space_before_switch_parentheses = true
ij_javascript_space_before_try_left_brace = true
ij_javascript_space_before_type_colon = false
ij_javascript_space_before_unary_not = false
ij_javascript_space_before_while_keyword = true
ij_javascript_space_before_while_left_brace = true
ij_javascript_space_before_while_parentheses = true
ij_javascript_spaces_around_additive_operators = true
ij_javascript_spaces_around_arrow_function_operator = true
ij_javascript_spaces_around_assignment_operators = true
ij_javascript_spaces_around_bitwise_operators = true
ij_javascript_spaces_around_equality_operators = true
ij_javascript_spaces_around_logical_operators = true
ij_javascript_spaces_around_multiplicative_operators = true
ij_javascript_spaces_around_relational_operators = true
ij_javascript_spaces_around_shift_operators = true
ij_javascript_spaces_around_unary_operator = false
ij_javascript_spaces_within_array_initializer_brackets = false
ij_javascript_spaces_within_brackets = false
ij_javascript_spaces_within_catch_parentheses = false
ij_javascript_spaces_within_for_parentheses = false
ij_javascript_spaces_within_if_parentheses = false
ij_javascript_spaces_within_imports = false
ij_javascript_spaces_within_interpolation_expressions = false
ij_javascript_spaces_within_method_call_parentheses = false
ij_javascript_spaces_within_method_parentheses = false
ij_javascript_spaces_within_object_literal_braces = true
ij_javascript_spaces_within_object_type_braces = true
ij_javascript_spaces_within_parentheses = false
ij_javascript_spaces_within_switch_parentheses = false
ij_javascript_spaces_within_type_assertion = false
ij_javascript_spaces_within_union_types = true
ij_javascript_spaces_within_while_parentheses = false
ij_javascript_special_else_if_treatment = true
ij_javascript_ternary_operation_signs_on_next_line = false
ij_javascript_ternary_operation_wrap = on_every_item
ij_javascript_union_types_wrap = on_every_item
ij_javascript_use_chained_calls_group_indents = false
ij_javascript_use_double_quotes = false
ij_javascript_use_explicit_js_extension = global
ij_javascript_use_path_mapping = always
ij_javascript_use_public_modifier = false
ij_javascript_use_semicolon_after_statement = true
ij_javascript_var_declaration_wrap = normal
ij_javascript_while_brace_force = never
ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false
[{*.cjsx,*.coffee}]
indent_size = 2
tab_width = 2
ij_continuation_indent_size = 2
ij_coffeescript_align_function_body = false
ij_coffeescript_align_imports = false
ij_coffeescript_align_multiline_array_initializer_expression = true
ij_coffeescript_align_multiline_parameters = true
ij_coffeescript_align_multiline_parameters_in_calls = false
ij_coffeescript_align_object_properties = 0
ij_coffeescript_align_union_types = false
ij_coffeescript_align_var_statements = 0
ij_coffeescript_array_initializer_new_line_after_left_brace = false
ij_coffeescript_array_initializer_right_brace_on_new_line = false
ij_coffeescript_array_initializer_wrap = normal
ij_coffeescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
ij_coffeescript_blank_lines_around_function = 1
ij_coffeescript_call_parameters_new_line_after_left_paren = false
ij_coffeescript_call_parameters_right_paren_on_new_line = false
ij_coffeescript_call_parameters_wrap = normal
ij_coffeescript_chained_call_dot_on_new_line = true
ij_coffeescript_comma_on_new_line = false
ij_coffeescript_enforce_trailing_comma = keep
ij_coffeescript_field_prefix = _
ij_coffeescript_file_name_style = relaxed
ij_coffeescript_force_quote_style = false
ij_coffeescript_force_semicolon_style = false
ij_coffeescript_function_expression_brace_style = end_of_line
ij_coffeescript_import_merge_members = global
ij_coffeescript_import_prefer_absolute_path = global
ij_coffeescript_import_sort_members = true
ij_coffeescript_import_sort_module_name = false
ij_coffeescript_import_use_node_resolution = true
ij_coffeescript_imports_wrap = on_every_item
ij_coffeescript_indent_chained_calls = true
ij_coffeescript_indent_package_children = 0
ij_coffeescript_jsx_attribute_value = braces
ij_coffeescript_keep_blank_lines_in_code = 2
ij_coffeescript_keep_first_column_comment = true
ij_coffeescript_keep_indents_on_empty_lines = false
ij_coffeescript_keep_line_breaks = true
ij_coffeescript_keep_simple_methods_in_one_line = false
ij_coffeescript_method_parameters_new_line_after_left_paren = false
ij_coffeescript_method_parameters_right_paren_on_new_line = false
ij_coffeescript_method_parameters_wrap = off
ij_coffeescript_object_literal_wrap = on_every_item
ij_coffeescript_prefer_as_type_cast = false
ij_coffeescript_prefer_explicit_types_function_expression_returns = false
ij_coffeescript_prefer_explicit_types_function_returns = false
ij_coffeescript_prefer_explicit_types_vars_fields = false
ij_coffeescript_reformat_c_style_comments = false
ij_coffeescript_space_after_comma = true
ij_coffeescript_space_after_dots_in_rest_parameter = false
ij_coffeescript_space_after_generator_mult = true
ij_coffeescript_space_after_property_colon = true
ij_coffeescript_space_after_type_colon = true
ij_coffeescript_space_after_unary_not = false
ij_coffeescript_space_before_async_arrow_lparen = true
ij_coffeescript_space_before_class_lbrace = true
ij_coffeescript_space_before_comma = false
ij_coffeescript_space_before_function_left_parenth = true
ij_coffeescript_space_before_generator_mult = false
ij_coffeescript_space_before_property_colon = false
ij_coffeescript_space_before_type_colon = false
ij_coffeescript_space_before_unary_not = false
ij_coffeescript_spaces_around_additive_operators = true
ij_coffeescript_spaces_around_arrow_function_operator = true
ij_coffeescript_spaces_around_assignment_operators = true
ij_coffeescript_spaces_around_bitwise_operators = true
ij_coffeescript_spaces_around_equality_operators = true
ij_coffeescript_spaces_around_logical_operators = true
ij_coffeescript_spaces_around_multiplicative_operators = true
ij_coffeescript_spaces_around_relational_operators = true
ij_coffeescript_spaces_around_shift_operators = true
ij_coffeescript_spaces_around_unary_operator = false
ij_coffeescript_spaces_within_array_initializer_braces = false
ij_coffeescript_spaces_within_array_initializer_brackets = false
ij_coffeescript_spaces_within_imports = false
ij_coffeescript_spaces_within_index_brackets = false
ij_coffeescript_spaces_within_interpolation_expressions = false
ij_coffeescript_spaces_within_method_call_parentheses = false
ij_coffeescript_spaces_within_method_parentheses = false
ij_coffeescript_spaces_within_object_braces = false
ij_coffeescript_spaces_within_object_literal_braces = false
ij_coffeescript_spaces_within_object_type_braces = true
ij_coffeescript_spaces_within_range_brackets = false
ij_coffeescript_spaces_within_type_assertion = false
ij_coffeescript_spaces_within_union_types = true
ij_coffeescript_union_types_wrap = on_every_item
ij_coffeescript_use_chained_calls_group_indents = false
ij_coffeescript_use_double_quotes = true
ij_coffeescript_use_explicit_js_extension = global
ij_coffeescript_use_path_mapping = always
ij_coffeescript_use_public_modifier = false
ij_coffeescript_use_semicolon_after_statement = false
ij_coffeescript_var_declaration_wrap = normal
[{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml,yii_te}]
ij_continuation_indent_size = 4
ij_php_align_assignments = false
ij_php_align_class_constants = false
ij_php_align_group_field_declarations = false
ij_php_align_inline_comments = false
ij_php_align_key_value_pairs = false
ij_php_align_match_arm_bodies = false
ij_php_align_multiline_array_initializer_expression = false
ij_php_align_multiline_binary_operation = false
ij_php_align_multiline_chained_methods = false
ij_php_align_multiline_extends_list = true
ij_php_align_multiline_for = true
ij_php_align_multiline_parameters = false
ij_php_align_multiline_parameters_in_calls = true
ij_php_align_multiline_ternary_operation = false
ij_php_align_named_arguments = false
ij_php_align_phpdoc_comments = false
ij_php_align_phpdoc_param_names = false
ij_php_anonymous_brace_style = end_of_line
ij_php_api_weight = 28
ij_php_array_initializer_new_line_after_left_brace = true
ij_php_array_initializer_right_brace_on_new_line = true
ij_php_array_initializer_wrap = on_every_item
ij_php_assignment_wrap = off
ij_php_attributes_wrap = off
ij_php_author_weight = 28
ij_php_binary_operation_sign_on_next_line = false
ij_php_binary_operation_wrap = off
ij_php_blank_lines_after_class_header = 0
ij_php_blank_lines_after_function = 1
ij_php_blank_lines_after_imports = 1
ij_php_blank_lines_after_opening_tag = 1
ij_php_blank_lines_after_package = 1
ij_php_blank_lines_around_class = 1
ij_php_blank_lines_around_constants = 0
ij_php_blank_lines_around_field = 0
ij_php_blank_lines_around_method = 1
ij_php_blank_lines_before_class_end = 0
ij_php_blank_lines_before_imports = 1
ij_php_blank_lines_before_method_body = 0
ij_php_blank_lines_before_package = 1
ij_php_blank_lines_before_return_statement = 0
ij_php_blank_lines_between_imports = 1
ij_php_block_brace_style = end_of_line
ij_php_call_parameters_new_line_after_left_paren = true
ij_php_call_parameters_right_paren_on_new_line = true
ij_php_call_parameters_wrap = on_every_item
ij_php_catch_on_new_line = false
ij_php_category_weight = 28
ij_php_class_brace_style = next_line
ij_php_comma_after_last_array_element = true
ij_php_concat_spaces = true
ij_php_copyright_weight = 28
ij_php_deprecated_weight = 28
ij_php_do_while_brace_force = always
ij_php_else_if_style = combine
ij_php_else_on_new_line = false
ij_php_example_weight = 28
ij_php_extends_keyword_wrap = off
ij_php_extends_list_wrap = on_every_item
ij_php_fields_default_visibility = private
ij_php_filesource_weight = 28
ij_php_finally_on_new_line = false
ij_php_for_brace_force = always
ij_php_for_statement_new_line_after_left_paren = true
ij_php_for_statement_right_paren_on_new_line = true
ij_php_for_statement_wrap = off
ij_php_force_short_declaration_array_style = false
ij_php_getters_setters_naming_style = camel_case
ij_php_getters_setters_order_style = getters_first
ij_php_global_weight = 28
ij_php_group_use_wrap = on_every_item
ij_php_if_brace_force = always
ij_php_if_lparen_on_next_line = false
ij_php_if_rparen_on_next_line = false
ij_php_ignore_weight = 28
ij_php_import_sorting = alphabetic
ij_php_indent_break_from_case = true
ij_php_indent_case_from_switch = true
ij_php_indent_code_in_php_tags = false
ij_php_internal_weight = 28
ij_php_keep_blank_lines_after_lbrace = 0
ij_php_keep_blank_lines_before_right_brace = 0
ij_php_keep_blank_lines_in_code = 2
ij_php_keep_blank_lines_in_declarations = 2
ij_php_keep_control_statement_in_one_line = true
ij_php_keep_first_column_comment = true
ij_php_keep_indents_on_empty_lines = false
ij_php_keep_line_breaks = true
ij_php_keep_rparen_and_lbrace_on_one_line = true
ij_php_keep_simple_classes_in_one_line = false
ij_php_keep_simple_methods_in_one_line = false
ij_php_lambda_brace_style = end_of_line
ij_php_license_weight = 28
ij_php_line_comment_add_space = false
ij_php_line_comment_at_first_column = true
ij_php_link_weight = 28
ij_php_lower_case_boolean_const = true
ij_php_lower_case_keywords = true
ij_php_lower_case_null_const = true
ij_php_method_brace_style = next_line
ij_php_method_call_chain_wrap = off
ij_php_method_parameters_new_line_after_left_paren = true
ij_php_method_parameters_right_paren_on_new_line = true
ij_php_method_parameters_wrap = on_every_item
ij_php_method_weight = 28
ij_php_modifier_list_wrap = false
ij_php_multiline_chained_calls_semicolon_on_new_line = false
ij_php_namespace_brace_style = 1
ij_php_new_line_after_php_opening_tag = true
ij_php_null_type_position = in_the_end
ij_php_package_weight = 28
ij_php_param_weight = 0
ij_php_parameters_attributes_wrap = off
ij_php_parentheses_expression_new_line_after_left_paren = false
ij_php_parentheses_expression_right_paren_on_new_line = false
ij_php_phpdoc_blank_line_before_tags = true
ij_php_phpdoc_blank_lines_around_parameters = true
ij_php_phpdoc_keep_blank_lines = true
ij_php_phpdoc_param_spaces_between_name_and_description = 1
ij_php_phpdoc_param_spaces_between_tag_and_type = 1
ij_php_phpdoc_param_spaces_between_type_and_name = 1
ij_php_phpdoc_use_fqcn = true
ij_php_phpdoc_wrap_long_lines = false
ij_php_place_assignment_sign_on_next_line = false
ij_php_place_parens_for_constructor = 0
ij_php_property_read_weight = 28
ij_php_property_weight = 28
ij_php_property_write_weight = 28
ij_php_return_type_on_new_line = false
ij_php_return_weight = 1
ij_php_see_weight = 28
ij_php_since_weight = 28
ij_php_sort_phpdoc_elements = true
ij_php_space_after_colon = true
ij_php_space_after_colon_in_enum_backed_type = true
ij_php_space_after_colon_in_named_argument = true
ij_php_space_after_colon_in_return_type = true
ij_php_space_after_comma = true
ij_php_space_after_for_semicolon = true
ij_php_space_after_quest = true
ij_php_space_after_type_cast = false
ij_php_space_after_unary_not = false
ij_php_space_before_array_initializer_left_brace = false
ij_php_space_before_catch_keyword = true
ij_php_space_before_catch_left_brace = true
ij_php_space_before_catch_parentheses = true
ij_php_space_before_class_left_brace = true
ij_php_space_before_closure_left_parenthesis = true
ij_php_space_before_colon = true
ij_php_space_before_colon_in_enum_backed_type = false
ij_php_space_before_colon_in_named_argument = false
ij_php_space_before_colon_in_return_type = false
ij_php_space_before_comma = false
ij_php_space_before_do_left_brace = true
ij_php_space_before_else_keyword = true
ij_php_space_before_else_left_brace = true
ij_php_space_before_finally_keyword = true
ij_php_space_before_finally_left_brace = true
ij_php_space_before_for_left_brace = true
ij_php_space_before_for_parentheses = true
ij_php_space_before_for_semicolon = false
ij_php_space_before_if_left_brace = true
ij_php_space_before_if_parentheses = true
ij_php_space_before_method_call_parentheses = false
ij_php_space_before_method_left_brace = true
ij_php_space_before_method_parentheses = false
ij_php_space_before_quest = true
ij_php_space_before_short_closure_left_parenthesis = false
ij_php_space_before_switch_left_brace = true
ij_php_space_before_switch_parentheses = true
ij_php_space_before_try_left_brace = true
ij_php_space_before_unary_not = false
ij_php_space_before_while_keyword = true
ij_php_space_before_while_left_brace = true
ij_php_space_before_while_parentheses = true
ij_php_space_between_ternary_quest_and_colon = false
ij_php_spaces_around_additive_operators = true
ij_php_spaces_around_arrow = false
ij_php_spaces_around_assignment_in_declare = false
ij_php_spaces_around_assignment_operators = true
ij_php_spaces_around_bitwise_operators = true
ij_php_spaces_around_equality_operators = true
ij_php_spaces_around_logical_operators = true
ij_php_spaces_around_multiplicative_operators = true
ij_php_spaces_around_null_coalesce_operator = true
ij_php_spaces_around_pipe_in_union_type = false
ij_php_spaces_around_relational_operators = true
ij_php_spaces_around_shift_operators = true
ij_php_spaces_around_unary_operator = false
ij_php_spaces_around_var_within_brackets = false
ij_php_spaces_within_array_initializer_braces = false
ij_php_spaces_within_brackets = false
ij_php_spaces_within_catch_parentheses = false
ij_php_spaces_within_for_parentheses = false
ij_php_spaces_within_if_parentheses = false
ij_php_spaces_within_method_call_parentheses = false
ij_php_spaces_within_method_parentheses = false
ij_php_spaces_within_parentheses = false
ij_php_spaces_within_short_echo_tags = true
ij_php_spaces_within_switch_parentheses = false
ij_php_spaces_within_while_parentheses = false
ij_php_special_else_if_treatment = false
ij_php_subpackage_weight = 28
ij_php_ternary_operation_signs_on_next_line = false
ij_php_ternary_operation_wrap = off
ij_php_throws_weight = 2
ij_php_todo_weight = 28
ij_php_unknown_tag_weight = 28
ij_php_upper_case_boolean_const = false
ij_php_upper_case_null_const = false
ij_php_uses_weight = 28
ij_php_var_weight = 28
ij_php_variable_naming_style = mixed
ij_php_version_weight = 28
ij_php_while_brace_force = always
ij_php_while_on_new_line = false
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
indent_size = 2
ij_json_keep_blank_lines_in_code = 0
ij_json_keep_indents_on_empty_lines = false
ij_json_keep_line_breaks = true
ij_json_space_after_colon = true
ij_json_space_after_comma = true
ij_json_space_before_colon = true
ij_json_space_before_comma = false
ij_json_spaces_within_braces = false
ij_json_spaces_within_brackets = false
ij_json_wrap_long_lines = false
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
ij_html_align_attributes = true
ij_html_align_text = false
ij_html_attribute_wrap = normal
ij_html_block_comment_at_first_column = true
ij_html_do_not_align_children_of_min_lines = 0
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
ij_html_enforce_quotes = false
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
ij_html_keep_blank_lines = 2
ij_html_keep_indents_on_empty_lines = false
ij_html_keep_line_breaks = true
ij_html_keep_line_breaks_in_text = true
ij_html_keep_whitespaces = false
ij_html_keep_whitespaces_inside = span,pre,textarea
ij_html_line_comment_at_first_column = true
ij_html_new_line_after_last_attribute = never
ij_html_new_line_before_first_attribute = never
ij_html_quote_style = double
ij_html_remove_new_line_before_tags = br
ij_html_space_after_tag_name = false
ij_html_space_around_equality_in_attribute = false
ij_html_space_inside_empty_tag = false
ij_html_text_wrap = normal
[{*.markdown,*.md}]
ij_markdown_force_one_space_after_blockquote_symbol = true
ij_markdown_force_one_space_after_header_symbol = true
ij_markdown_force_one_space_after_list_bullet = true
ij_markdown_force_one_space_between_words = true
ij_markdown_keep_indents_on_empty_lines = false
ij_markdown_max_lines_around_block_elements = 1
ij_markdown_max_lines_around_header = 1
ij_markdown_max_lines_between_paragraphs = 1
ij_markdown_min_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
[{*.yaml,*.yml}]
indent_size = 2
ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false
ij_yaml_indent_sequence_value = true
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
ij_yaml_sequence_on_new_line = false
ij_yaml_space_before_colon = false
ij_yaml_spaces_within_braces = true
ij_yaml_spaces_within_brackets = true
================================================
FILE: .github/ISSUE_TEMPLATE/BUG.yml
================================================
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: [ bug, triage ]
assignees:
- MacroMan
body:
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Please provide all information required to reproduce the bug
validations:
required: true
- type: dropdown
id: version
attributes:
label: Version
description: What version of Spaces-API is this occuring on? Versions below 3 will not be fixed. Please upgrade.
options:
- 3.5.0
- 3.4.0
- 3.3.0
- 3.2.0
- 3.1.0
- 3.0.0
validations:
required: true
- type: input
id: php-version
attributes:
label: What version of PHP are you using?
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE.yml
================================================
name: Feature request
description: Request new functionality
title: "[Feature]: "
labels: [ new ]
assignees:
- MacroMan
body:
- type: textarea
id: idea
attributes:
label: Description
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.
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .gitignore
================================================
.DS_Store
vendor/
.idea/
.env
.phpunit.result.cache
================================================
FILE: .phpdoc-md
================================================
<?php
return (object)[
'rootNamespace' => 'SpacesAPI',
'destDirectory' => 'docs',
'format' => 'github',
'classes' => [
'\SpacesAPI\Spaces',
'\SpacesAPI\Space',
'\SpacesAPI\File',
],
];
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Devang Srivastava
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# This library is deprecated
We recommend using the [official SDK](https://github.com/DigitalOceanPHP/Client) or the [Laravel package](https://github.com/GrahamCampbell/Laravel-DigitalOcean)
All issues will be closed and new PRs will not be accepted
## Installation
Install via composer
```
composer require sociallydev/spaces-api
```
## Quick start
Obtain API keys from the [Digital Ocean Applications & API dashboard](https://cloud.digitalocean.com/account/api/tokens)
```php
use SpacesAPI\Spaces;
// Connect to a space
$spaces = new Spaces('api-key', 'api-secret');
$space = $spaces->space('space-name');
// Download a file
$file = $space->file('remote-file-1.txt');
$file->download('local/file/path/file.txt');
// Upload text to a file
$file2 = $space->uploadText("Lorem ipsum","remote-file-2.txt");
// Get a signed public link, valid for 2 hours
$file2url = $file2->getSignedURL("2 hours");
// Make a copy
$file3 = $file2->copy('remote-file-3.txt');
// Move or rename a file
$file2->move('new-filename.txt')
// Make a file public and get the URL
$file3->makePublic();
$file3url = $file3->getURL();
```
See more examples in [docs/Examples.md](docs/Examples.md)
## Upgrading?
Version 3 has many changes over version 2, so we have written a [migration guide](docs/Upgrade2-3.md)
## API reference
* [\SpacesAPI\Spaces](docs/Spaces.md)
* [\SpacesAPI\Space](docs/Space.md)
* [\SpacesAPI\File](docs/File.md)
================================================
FILE: SpacesAPI/Exceptions/AuthenticationException.php
================================================
<?php
namespace SpacesAPI\Exceptions;
use Exception;
class AuthenticationException extends Exception {}
================================================
FILE: SpacesAPI/Exceptions/FileDoesntExistException.php
================================================
<?php
namespace SpacesAPI\Exceptions;
use Exception;
class FileDoesntExistException extends Exception
{
}
================================================
FILE: SpacesAPI/Exceptions/SpaceDoesntExistException.php
================================================
<?php
namespace SpacesAPI\Exceptions;
use Exception;
class SpaceDoesntExistException extends Exception
{
}
================================================
FILE: SpacesAPI/Exceptions/SpaceExistsException.php
================================================
<?php
namespace SpacesAPI\Exceptions;
use Exception;
class SpaceExistsException extends Exception {}
================================================
FILE: SpacesAPI/Exceptions/SpacesException.php
================================================
<?php
namespace SpacesAPI\Exceptions;
use Exception;
class SpacesException extends Exception
{
}
================================================
FILE: SpacesAPI/File.php
================================================
<?php
namespace SpacesAPI;
use SpacesAPI\Exceptions\FileDoesntExistException;
use function PHPUnit\Framework\isNull;
/**
* Represents a single file
*
* You wouldn't normally instantiate this class directly,
* Rather obtain an instance from `\SpacesAPI\Space::list()`, `\SpacesAPI\Spaces::file()`, `\SpacesAPI\Spaces::uploadText()` or `\SpacesAPI\Spaces::uploadFile()`
*
* @property string $filename
* @property string $expiration
* @property string $e_tag
* @property int $last_modified
* @property string $content_type
* @property int $content_length
*/
class File
{
use StringFunctions;
/**
* @var \SpacesAPI\Space
*/
private $space;
/**
* The name of the current space
*
* @var string
*/
private $space_name;
/**
* @var \Aws\S3\S3Client
*/
private $s3;
private $_expiration;
private $_e_tag;
private $_filename;
private $_last_modified;
private $_content_type;
private $_content_length;
/**
* @param \SpacesAPI\Space $space An instance of `\SpacesAPI\Space`
* @param string $filename The filename of a file
* @param array $info Any information already known about the file (eg content_length, content_type, etc). Default `[]`
* @param bool $validate Check that the file exists
*
* @throws \SpacesAPI\Exceptions\FileDoesntExistException If validation is `true` and the file doesn't exist
*/
public function __construct(Space $space, string $filename, array $info = [], bool $validate = true)
{
$this->space = $space;
$this->space_name = $space->getName();
$this->s3 = $space->getS3Client();
$this->_filename = $filename;
if ($validate && !$this->s3->doesObjectExist($this->space_name, $filename)) {
throw new FileDoesntExistException("File $filename doesn't exist");
}
if (count($info) > 0) {
$this->setFileInfo($info);
}
}
/**
* Magic getter to make the properties read-only
*
* @param string $name
*
* @return null
*/
public function __get(string $name)
{
if (!property_exists($this, "_$name")) {
trigger_error("Undefined property: SpacesAPI\File::$name", E_USER_NOTICE);
return null;
}
if (!$this->{"_$name"}) {
$this->fetchFileInfo();
}
return $this->{"_$name"};
}
/**
* @param array $info
*/
private function setFileInfo(array $info): void
{
foreach ($info as $_property => $value) {
$property = "_" . $this->pascalCaseToCamelCase($_property);
if ($property == 'size') {
$property = 'content_length';
}
if (property_exists($this, $property)) {
$this->$property = $value;
}
}
}
/**
*
*/
private function fetchFileInfo(): void
{
$this->setFileInfo(
Result::parse(
$this->s3->headObject([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
])
)
);
}
/**
* Is this file publicly accessible
*
* @return bool
*/
public function isPublic(): bool
{
$acl = Result::parse(
$this->s3->getObjectAcl([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
])
);
return (
isset($acl['Grants'][0]['Grantee']['URI']) &&
$acl['Grants'][0]['Grantee']['URI'] == "http://acs.amazonaws.com/groups/global/AllUsers" &&
$acl['Grants'][0]['Permission'] == "READ"
);
}
/**
* Make a file public or privately accessible
*
* @param bool $public
*/
private function updatePrivacy(bool $public): void
{
$this->s3->putObjectAcl([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
"ACL" => ($public) ? "public-read" : "private",
]);
}
/**
* Make file publicly accessible
*/
public function makePublic(): void
{
$this->updatePrivacy(true);
}
/**
* Make file non-publicly accessible
*/
public function makePrivate(): void
{
$this->updatePrivacy(false);
}
/**
* Get the file contents as a string
*
* @return string
*/
public function getContents(): string
{
return $this->s3->getObject([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
])["Body"]->getContents();
}
/**
* Download the file to a local location
*
* @param string $saveAs
*
* @return void
*/
public function download(string $saveAs): void
{
$this->s3->getObject([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
"SaveAs" => $saveAs,
]);
}
/**
* Copy the file on the space
*
* @param string $newFilename
* @param false $public
*
* @return \SpacesAPI\File
*/
public function copy(string $newFilename): File
{
$this->s3->copy(
$this->space_name,
$this->_filename,
$this->space_name,
$newFilename,
($this->isPublic()) ? 'public-read' : 'private'
);
return new self($this->space, $newFilename);
}
/**
* @param string $newFilename
*
* @return \SpacesAPI\File
*/
public function move(string $newFilename): File
{
$this->copy($newFilename);
$this->delete();
$this->_filename = $newFilename;
$this->fetchFileInfo();
return $this;
}
/**
* Get the public URL
* This URL will not work if the file is private
*
* @return string
* @see getSignedURL
*
*/
public function getURL(): string
{
return $this->s3->getObjectUrl($this->space_name, $this->_filename);
}
/**
* Get a signed URL, which will work for private files
*
* @param string|\DateTime|int $validFor Can be any string recognised by strtotime(), an instance of DateTime or a unix timestamp
*
* @return string
*/
public function getSignedURL($validFor = "15 minutes"): string
{
return (string)$this->s3->createPresignedRequest(
$this->s3->getCommand("GetObject", [
"Bucket" => $this->space_name,
"Key" => $this->_filename,
]),
$validFor
)->getUri();
}
/**
* Permanently delete this file
*/
public function delete(): void
{
$this->s3->deleteObject([
"Bucket" => $this->space_name,
"Key" => $this->_filename,
]);
}
}
================================================
FILE: SpacesAPI/Result.php
================================================
<?php
namespace SpacesAPI;
use Aws\Api\DateTimeResult;
/**
* AWS Results parser
*/
class Result
{
/**
* Convert AWS result object into plain, multidimensional array
*
* @param $data
*
* @return array|mixed
*/
public static function parse($data) {
if (gettype($data) == "object" && get_class($data) == \Aws\Result::class) {
$data = $data->toArray();
}
foreach ($data as $key => $value) {
if (is_array($value)) {
$data[$key] = self::parse($value);
continue;
}
if (gettype($value) == "object" && get_class($value) == DateTimeResult::class) {
$data[$key] = strtotime($value);
}
}
return $data;
}
}
================================================
FILE: SpacesAPI/Space.php
================================================
<?php
namespace SpacesAPI;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use SpacesAPI\Exceptions\SpaceDoesntExistException;
/**
* Represents a space once connected/created
*
* You wouldn't normally instantiate this class directly,
* Rather obtain an instance from `\SpacesAPI\Spaces::space()` or `\SpacesAPI\Spaces::create()`
*/
class Space
{
/**
* AWS S3 client
*
* @var \Aws\S3\S3Client
*/
private $s3;
/**
* The name of the current space
*
* @var string
*/
private $name;
/**
* Load a space
*
* You wouldn't normally call this directly,
* rather obtain an instance from `\SpacesAPI\Spaces::space()` or `\SpacesAPI\Spaces::create()`
*
* @param \Aws\S3\S3Client $s3 An authenticated S3Client instance
* @param string $name Space name
* @param bool $validate Check that the space exists
*
* @throws \SpacesAPI\Exceptions\SpaceDoesntExistException If validation is `true` and the space doesn't exist
*/
public function __construct(S3Client $s3, string $name, bool $validate = true)
{
$this->s3 = $s3;
$this->name = $name;
if ($validate && !$this->s3->doesBucketExist($name)) {
throw new SpaceDoesntExistException("Space '$this->name' does not exist");
}
}
/**
* Get the current AWS S3 client instance
*
* For internal library use
*
* @return \Aws\S3\S3Client
*/
public function getS3Client(): S3Client
{
return $this->s3;
}
/**
* Get the name of this space
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Update space privacy
*
* @param bool $public
*/
private function updatePrivacy(bool $public): void
{
$this->s3->putBucketAcl([
"Bucket" => $this->name,
"ACL" => ($public) ? "public-read" : "private",
]);
}
/**
* Enable file listing
*/
public function makePublic(): void
{
$this->updatePrivacy(true);
}
/**
* Disable file listing
*/
public function makePrivate(): void
{
$this->updatePrivacy(false);
}
/**
* Is file listing enabled?
*
* @return bool
*/
public function isPublic(): bool
{
$acl = Result::parse($this->s3->getBucketAcl(["Bucket" => $this->name]));
return (
isset($acl['Grants'][0]['Grantee']['URI']) &&
$acl['Grants'][0]['Grantee']['URI'] == "http://acs.amazonaws.com/groups/global/AllUsers" &&
$acl['Grants'][0]['Permission'] == "READ"
);
}
/**
* Destroy/Delete this space, along with all files
*/
public function destroy(): void
{
$this->s3->deleteMatchingObjects($this->name, "", "(.*?)");
$this->s3->deleteBucket(["Bucket" => $this->name]);
}
/**
* Get the CORS configuration for the space
*
* @return array|null An array of CORS rules or null if no rules exist
*/
public function getCORS(): ?array
{
try {
return Result::parse(
$this->s3->getBucketCors([
"Bucket" => $this->name,
])
)['CORSRules'];
} catch (S3Exception $e) {
return null;
}
}
/**
* Get the CORS rules, removing the origin specified
*
* @param string $origin
*
* @return array
*/
private function getCORSRemovingOrigin(string $origin): array
{
if (!$CORSRules = $this->getCORS()) {
return [];
}
foreach ($CORSRules as $i => $cors) {
if ($cors['AllowedOrigins'][0] == $origin) {
array_splice($CORSRules, $i, 1);
}
}
return $CORSRules;
}
/**
* Set the CORS rules
*
* @param array $rules
*/
private function putCORS(array $rules): void
{
$this->s3->putBucketCors([
"Bucket" => $this->name,
"CORSConfiguration" => [
"CORSRules" => $rules,
],
]);
}
/**
* Add an origin to the CORS settings on this space
*
* @param string $origin eg `http://example.com`
* @param array $methods Array items must be one of `GET`, `PUT`, `DELETE`, `POST` and `HEAD`
* @param int $maxAge Access Control Max Age
* @param array $headers Allowed Headers
*/
public function addCORSOrigin(string $origin, array $methods, int $maxAge = 0, array $headers = []): void
{
$rules = $this->getCORSRemovingOrigin($origin);
$this->putCORS(
array_merge($rules, [
[
"AllowedHeaders" => $headers,
"AllowedMethods" => $methods,
"AllowedOrigins" => [$origin],
"MaxAgeSeconds" => $maxAge,
],
])
);
}
/**
* Remove an origin from the CORS settings on this space
*
* @param string $origin eg `http://example.com`
*/
public function removeCORSOrigin(string $origin): void
{
$rules = $this->getCORSRemovingOrigin($origin);
if (empty($rules)) {
$this->removeAllCORSOrigins();
} else {
$this->putCORS($rules);
}
}
/**
* Delete all CORS rules
*/
public function removeAllCORSOrigins(): void
{
$this->s3->deleteBucketCors([
'Bucket' => $this->name,
]);
}
/**
* List all files in the space (recursively)
*
* @param string $directory The directory to list files in. Empty string for root directory
*
* @return array
*/
public function listFiles(string $directory = ""): array
{
$rawFiles = $this->rawListFiles($directory);
$files = [];
foreach ($rawFiles as $fileInfo) {
$files[$fileInfo['Key']] = new File($this, $fileInfo['Key'], $fileInfo, false);
}
return ['files' => $files];
}
/**
* @param string $directory The directory to list files in. Empty string for root directory
* @param string|null $continuationToken Used internally to work around request limits (1000 files per request)
*
* @return array
*/
private function rawListFiles(string $directory = "", ?string $continuationToken = null): array
{
$data = Result::parse(
$this->s3->listObjectsV2([
"Bucket" => $this->name,
"Prefix" => $directory,
"MaxKeys" => 1000,
// "StartAfter" => 0, // For skipping files, maybe for future limit/skip ability
"FetchOwner" => false,
"ContinuationToken" => $continuationToken,
])
);
if (!isset($data['Contents'])) {
return [];
}
$files = $data['Contents'];
if (isset($data["NextContinuationToken"]) && $data["NextContinuationToken"] != "") {
$files = array_merge($files, $this->rawListFiles($directory, $data["NextContinuationToken"]));
}
return $files;
}
/**
* Upload a string of text to file
*
* @param string $text The text to upload
* @param string $filename The filepath/name to save to
* @param array $params Any extra parameters. [See here](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property)
* @param bool $private True for the file to be private, false to allow public access
*
* @return \SpacesAPI\File
*/
public function uploadText(string $text, string $filename, array $params = [], bool $private = true): File
{
$this->s3->upload($this->name, $filename, $text, ($private) ? 'private' : 'public-read', $params);
return new File($this, $filename, [], false);
}
/**
* Upload a file
*
* @param string $filepath The path to the file, including the filename. Relative and absolute paths are accepted.
* @param string|null $filename The remote filename. If `null`, the local filename will be used.
* @param string|null $mimeType The file mime type to pass as ContentType for the file (e.g. 'image/jpeg').
* @param bool $private True for the file to be private, false to allow public access.
*
* @return \SpacesAPI\File
*/
public function uploadFile(string $filepath, ?string $filename = null, ?string $mimeType = null, bool $private = true): File
{
$this->s3->putObject([
'Bucket' => $this->name,
'Key' => ($filename) ?: basename($filepath),
'SourceFile' => $filepath,
'ContentType' => $mimeType,
'ACL' => ($private) ? 'private' : 'public-read'
]);
return new File($this, ($filename) ?: basename($filepath), [], false);
}
/**
* Get an instance of \SpacesAPI\File for a given filename
*
* @param string $filename
* @package bool $validate
*
* @return \SpacesAPI\File
* @throws \SpacesAPI\Exceptions\FileDoesntExistException Thrown if the file doesn't exist
*/
public function file(string $filename, bool $validate = true): File
{
return new File($this, $filename, [], $validate);
}
/**
* Recursively upload an entire directory
*
* @param string $local The local directory to upload
* @param string|null $remote The remote directory to place the files in. `null` to place in the root
*/
public function uploadDirectory(string $local, ?string $remote = null): void
{
$this->s3->uploadDirectory($local, $this->name, $remote);
}
/**
* Recursively download an entire directory.
*
* @param string $local The local directory to save the directories/files in
* @param string|null $remote The remote directory to download. `null` to download the entire space
*/
public function downloadDirectory(string $local, ?string $remote = null): void
{
$this->s3->downloadBucket($local, $this->name, $remote);
}
/**
* Delete an entire directory, including its contents
*
* @param string $path The directory to delete
*/
public function deleteDirectory(string $path): void
{
$this->s3->deleteMatchingObjects($this->name, $path);
}
}
================================================
FILE: SpacesAPI/Spaces.php
================================================
<?php
namespace SpacesAPI;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use SpacesAPI\Exceptions\AuthenticationException;
use SpacesAPI\Exceptions\SpaceExistsException;
/**
* Represents the connection to Digital Ocean spaces.
* The entry point for managing spaces.
*
* Instantiate your connection with `new \SpacesAPI\Spaces("access-key", "secret-key", "region")`
*
* Obtain your access and secret keys from the [DigitalOcean Applications & API dashboard](https://cloud.digitalocean.com/account/api/tokens)
*/
class Spaces
{
/**
* @var \Aws\S3\S3Client
*/
private $s3;
/**
* Initialise the API
*
* @param string $accessKey Digital Ocean API access key
* @param string $secretKey Digital Ocean API secret key
* @param string $region Region, defaults to ams3
* @param string $host API endpoint, defaults to digitaloceanspaces.com
*
* @throws \SpacesAPI\Exceptions\AuthenticationException Authentication failed
*/
public function __construct(string $accessKey, string $secretKey, string $region = "ams3", string $host = "digitaloceanspaces.com")
{
$this->s3 = new S3Client([
"version" => "latest",
"region" => $region,
"endpoint" => "https://$region.$host",
"credentials" => ["key" => $accessKey, "secret" => $secretKey],
"ua_append" => "SociallyDev-Spaces-API/2",
]);
try {
$this->s3->headBucket(["Bucket" => 'auth-check']);
} catch (S3Exception $e) {
if ($e->getStatusCode() == 403) {
throw new AuthenticationException("Authentication failed");
}
}
}
/**
* List all your spaces
*
* @return array An array of \SpacesAPI\Space instances
*/
public function list(): array
{
$spaces = [];
foreach (Result::parse($this->s3->listBuckets()['Buckets']) as $bucket) {
$spaces[$bucket['Name']] = new Space($this->s3, $bucket['Name'], false);
}
return $spaces;
}
/**
* Create a new space
*
* @param string $name The name of the new space
* @param bool $public Enable file listing. Default `false`
*
* @return \SpacesAPI\Space The newly created space
* @throws \SpacesAPI\Exceptions\SpaceExistsException The named space already exists
*/
public function create(string $name, bool $public = false): Space
{
try {
$this->s3->createBucket([
"ACL" => ($public) ? "public-read" : "private",
"Bucket" => $name,
]);
} catch (S3Exception $e) {
throw new SpaceExistsException($e->getAwsErrorMessage());
}
return new Space($this->s3, $name, false);
}
/**
* Use an existing space
*
* @param string $name The name of the space
*
* @return \SpacesAPI\Space The loaded space
* @throws \SpacesAPI\Exceptions\SpaceDoesntExistException The named space doesn't exist
*/
public function space(string $name): Space
{
return new Space($this->s3, $name);
}
}
================================================
FILE: SpacesAPI/StringFunctions.php
================================================
<?php
namespace SpacesAPI;
trait StringFunctions
{
public function pascalCaseToCamelCase(string $name): string
{
return strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));
}
}
================================================
FILE: composer.json
================================================
{
"name": "sociallydev/spaces-api",
"description": "Library for accessing Digital Ocean spaces",
"version":"3.6.1",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Devang Srivastava",
"email": "hey@devang.dev",
"homepage": "https://devang.dev"
},
{
"name": "David Wakelin",
"email": "helllo@davidwakelin.co.uk",
"homepage": "https://davidwakelin.co.uk"
}
],
"autoload": {
"psr-4": {
"SpacesAPI\\": "SpacesAPI"
}
},
"require": {
"php": ">=7.3",
"aws/aws-sdk-php": "^3.52"
},
"require-dev": {
"clean/phpdoc-md": "^0.19.1",
"phpunit/phpunit": "^9.5.13",
"vlucas/phpdotenv": "^v5.4.1"
}
}
================================================
FILE: docs/Examples.md
================================================
# Examples
## Connecting to Digital Ocean and selecting a space
```php
use SpacesAPI\Spaces;
$spaces = new Spaces('api-key', 'api-secret');
$space = $spaces->space('space-name');
```
[API docs for \SpacesAPI\Spaces](Spaces.md)
## Creating a new space
```php
$spaces = new Spaces('api-key', 'api-secret');
$space = $spaces->create('new-space-name');
```
[API docs for creating a space](Spaces.md#spacescreate)
## Listing files
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$files = $space->listFiles();
foreach ($files['files'] as $file) {
echo "{$file->filename}\n";
}
```
[API docs for listing files](Space.md#spacelistfiles)
## Uploading a file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$file = $space->uploadFile('./localfile.txt', 'remote-filename.txt');
```
[API docs for uploading files](Space.md#spaceuploadfile)
## Uploading text to a file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$file = $space->uploadText('Lorem ipsum', 'remote-filename.txt');
```
[API docs for uploading text](Space.md#spaceuploadtext)
## Downloading a file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$space->file('filename.txt')->download('./localfile.txt');
```
[API docs for downloading a file](File.md#filedownload)
## Get the contents of a file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
echo $space->file('filename.txt')->getContents();
```
[API docs for getting the contents of a file](File.md#filegetcontents)
## Deleting a file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$space->file('filename.txt')->delete();
```
[API docs for deleting a file](File.md#filedelete)
## Get a public URL
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$space->file('filename.txt')->getURL();
```
[API docs for getting the public URL](File.md#filegeturl)
## Get a signed URL
#### a time limited link to provide access to a private file
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$space->file('filename.txt')->getSignedURL("1 day");
```
[API docs for getting a signed URL](File.md#filegetsignedurl)
## Make a file publicly accessible
```php
$space = new Spaces('api-key', 'api-secret')->space('my-space-name');
$space->file('filename.txt')->makePublic();
```
[API docs for setting file privacy](File.md#spacemakeprivate)
================================================
FILE: docs/File.md
================================================
# SpacesAPI\File
Represents a single file
You wouldn't normally instantiate this class directly,
Rather obtain an instance from `\SpacesAPI\Space::list()`, `\SpacesAPI\Spaces::file()`, `\SpacesAPI\Spaces::uploadText()` or `\SpacesAPI\Spaces::uploadFile()`
## Properties
| name | Type | Description |
| --- | --- | --- |
| `expiration` | `string` | |
| `e_tag` | `string` | |
| `last_modified` | `int` | Last modified date as unix timestamp |
| `content_type` | `string` | THe mime type of the file |
| `content_length` | `int` | The size of the file in bytes |
## Methods
| Name | Description |
|------|-------------|
|[__construct](#file__construct)||
|[copy](#filecopy)|Copy the file on the space|
|[delete](#filedelete)|Permanently delete this file|
|[download](#filedownload)|Download the file to a local location|
|[getContents](#filegetcontents)|Get the file contents as a string|
|[getSignedURL](#filegetsignedurl)|Get a signed URL, which will work for private files|
|[getURL](#filegeturl)|Get the public URL. This URL will not work if the file is private|
|[isPublic](#fileispublic)|Is this file publicly accessible|
|[makePrivate](#filemakeprivate)|Make file non-publicly accessible|
|[makePublic](#filemakepublic)|Make file publicly accessible|
|[move](#filemove)|Move and/or rename file|
### File::__construct
**Description**
```php
__construct (\SpacesAPI\Space $space, string $filename, array $info = [], bool $validate = true)
```
**Parameters**
* `(\SpacesAPI\Space) $space` : An instance of `\SpacesAPI\Space`
* `(string) $filename` : The filename of a file
* `(array) $info` : Any information already known about the file (eg content_length, content_type, etc). Default `[]`
* `(bool) $validate` : Check that the file exists. Default `true`
**Return Values**
`void`
**Throws Exceptions**
`\SpacesAPI\Exceptions\FileDoesntExistException` : If validation is `true` and the file doesn't exist
<hr />
### File::copy
**Description**
```php
public copy (string $newFilename, bool $public = false)
```
Copy the file on the space
**Parameters**
* `(string) $newFilename`
* `(bool) $public`
**Return Values**
`\SpacesAPI\File` : An instance for the new file
<hr />
### File::delete
**Description**
```php
public delete (void)
```
Permanently delete this file
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### File::download
**Description**
```php
public download (string $saveAs)
```
Download the file to a local location
**Parameters**
* `(string) $saveAs` Then filepath including the filename. This can be a relative or absolute path.
**Return Values**
`void`
<hr />
### File::getContents
**Description**
```php
public getContents (void)
```
Get the file contents as a string
**Parameters**
`This function has no parameters.`
**Return Values**
`string`
<hr />
### File::getSignedURL
**Description**
```php
public getSignedURL (string|\DateTime|int $validFor)
```
Get a signed URL, which will work for private files
**Parameters**
* `(string|\DateTime|int) $validFor`
: Can be any string recognised by strtotime(), an instance of `\DateTime` or a unix timestamp
**Return Values**
`string`
<hr />
### File::getURL
**Description**
```php
public getURL (void)
```
Get the public URL. This URL will not work if the file is private
**Parameters**
`This function has no parameters.`
**Return Values**
`string`
<hr />
### File::isPublic
**Description**
```php
public isPublic (void)
```
Is this file publicly accessible?
**Parameters**
`This function has no parameters.`
**Return Values**
`bool`
<hr />
### File::makePrivate
**Description**
```php
public makePrivate (void)
```
Make file non-publicly accessible
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### File::makePublic
**Description**
```php
public makePublic (void)
```
Make file publicly accessible
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### File::move
**Description**
```php
public move (string $newFilename)
```
Move or rename a file
The instance of `File` is now the moved object
**Parameters**
* `(string) $newFilename`
**Return Values**
`\SpacesAPI\File` : An instance for the new file
<hr />
================================================
FILE: docs/Space.md
================================================
# SpacesAPI\Space
Represents a space once connected/created
You wouldn't normally instantiate this class directly,
Rather obtain an instance from `\SpacesAPI\Spaces::space()` or `\SpacesAPI\Spaces::create()`
## Methods
| Name | Description |
|------|-------------|
|[__construct](#space__construct)|Load a space|
|[addCORSOrigin](#spaceaddcorsorigin)|Add an origin to the CORS settings on this space|
|[deleteDirectory](#spacedeletedirectory)|Delete an entire directory, including its contents|
|[destroy](#spacedestroy)|Destroy/Delete this space|
|[downloadDirectory](#spacedownloaddirectory)|Recursively download an entire directory.|
|[file](#spacefile)|Get an instance of \SpacesAPI\File for a given filename|
|[getCORS](#spacegetcors)|Get the CORS configuration for the space|
|[getName](#spacegetname)|Get the name of this space|
|[getS3Client](#spacegets3client)|Get the current AWS S3 client instance (internal use)|
|[isPublic](#spaceispublic)|Is file listing enabled?|
|[listFiles](#spacelistfiles)|List all files in the space (recursively)|
|[makePrivate](#spacemakeprivate)|Disable file listing|
|[makePublic](#spacemakepublic)|Enable file listing|
|[removeCORSOrigin](#spaceremovecorsorigin)|Remove an origin from the CORS settings on this space|
|[removeAllCORSOrigins](#spacedeleteallcorsorigins)|Delete all CORS rules|
|[uploadDirectory](#spaceuploaddirectory)|Recursively upload an entire directory|
|[uploadFile](#spaceuploadfile)|Upload a file|
|[uploadText](#spaceuploadtext)|Upload a string of text to file|
### Space::__construct
**Description**
```php
public __construct (\Aws\S3\S3Client $s3, string $name, bool $validate = true)
```
Load a space
You wouldn't normally call this directly,
rather obtain an instance from `\SpacesAPI\Spaces::space()` or `\SpacesAPI\Spaces::create()`
**Parameters**
* `(\Aws\S3\S3Client) $s3`
: An authenticated S3Client instance
* `(string) $name`
: Space name
* `(bool) $validate`
: Check that the space exists. Default `true`
**Return Values**
`void`
**Throws Exceptions**
`\SpacesAPI\Exceptions\SpaceDoesntExistException` : If validation is `true` and the space doesn't exist
<hr />
### Space::addCORSOrigin
**Description**
```php
public addCORSOrigin (string $origin, array $methods, int $maxAge = 0, array $headers => [])
```
Add an origin to the CORS settings on this space
**Parameters**
* `(string) $origin`
: eg `http://example.com`
* `(array) $methods`
: Array items must be one of `GET`, `PUT`, `DELETE`, `POST` and `HEAD`
* `(int) $maxAge`
: Access Control Max Age. Default `0`
* `(array) $headers`
: Allowed Headers. Default `[]`
**Return Values**
`void`
<hr />
### Space::deleteDirectory
**Description**
```php
public deleteDirectory (string $path)
```
Delete an entire directory, including its contents
**Parameters**
* `(string) $path`
: The directory to delete
**Return Values**
`void`
<hr />
### Space::destroy
**Description**
```php
public destroy (void)
```
Destroy/Delete this space, along with all files.
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### Space::downloadDirectory
**Description**
```php
public downloadDirectory (string $local, string|null $remote = null)
```
Recursively download an entire directory.
**Parameters**
* `(string) $local`
: The local directory to save the directories/files in
* `(string|null) $remote`
: The remote directory to download. `null` to download the entire space. Default `null`
**Return Values**
`void`
<hr />
### Space::file
**Description**
```php
public file (string $filename, bool $validate = true)
```
Get an instance of \SpacesAPI\File for a given filename
**Parameters**
* `(string) $filename`
* `(bool) $validate`
: Whether to validate the file exits. Defaults to `true`
**Return Values**
`\SpacesAPI\File`
**Throws Exceptions**
`\SpacesAPI\Exceptions\FileDoesntExistException`
> Thrown if the file doesn't exist
<hr />
### Space::getCORS
**Description**
```php
public getCORS (void)
```
Get the CORS configuration for the space
**Parameters**
`This function has no parameters.`
**Return Values**
`array|null`
> An array of CORS rules or `null` if no rules exist
<hr />
### Space::getName
**Description**
```php
public getName (void)
```
Get the name of this space
**Parameters**
`This function has no parameters.`
**Return Values**
`string`
<hr />
### Space::getS3Client
**Description**
```php
public getS3Client (void)
```
Get the current AWS S3 client instance
For internal library use. It is unlikely you will need to access this object, but can do so to gain access to the underlying S3Client for andvanced usage.
**Parameters**
`This function has no parameters.`
**Return Values**
`\Aws\S3\S3Client`
<hr />
### Space::isPublic
**Description**
```php
public isPublic (void)
```
Is file listing enabled?
**Parameters**
`This function has no parameters.`
**Return Values**
`bool`
<hr />
### Space::listFiles
**Description**
```php
public listFiles (string $directory = "")
```
List all files in the space (recursively)
**Parameters**
* `(string) $directory`
: The directory to list files in. Empty string for root directory
**Return Values**
`array`
> An array of `\SpacesAPI\File` instances indexed by the file name
<hr />
### Space::makePrivate
**Description**
```php
public makePrivate (void)
```
Disable file listing
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### Space::makePublic
**Description**
```php
public makePublic (void)
```
Enable file listing
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### Space::removeCORSOrigin
**Description**
```php
public removeCORSOrigin (string $origin)
```
Remove an origin from the CORS settings on this space
**Parameters**
* `(string) $origin`
: eg `http://example.com`
**Return Values**
`void`
<hr />
### Space::removeAllCORSOrigins
**Description**
```php
public deleteAllCORSOrigins (void)
```
Delete all CORS rules
**Parameters**
`This function has no parameters.`
**Return Values**
`void`
<hr />
### Space::uploadDirectory
**Description**
```php
public uploadDirectory (string $local, string|null $remote = null)
```
Recursively upload an entire directory
**Parameters**
* `(string) $local`
: The local directory to upload
* `(string|null) $remote`
: The remote directory to place the files in. `null` to place in the root. Default `null`
**Return Values**
`void`
<hr />
### Space::uploadFile
**Description**
```php
public uploadFile (string $filepath, string|null $filename = null, string|null $mimeType = null, bool $private = true)
```
Upload a file
**Parameters**
* `(string) $filepath`
: The path to the file, including the filename. Relative and absolute paths are accepted.
* `(string|null) $filename`
: The remote filename. If `null`, the local filename will be used. Default `null`
* `(string|null) $mimeType`
: The files mimeType. If `null` the mimeType is inferred from the file by DigitalOcean Spaces. Default `null`
* `(bool)` $private
: If `true` then the file is private, if `false` the file is publicly available. Default `true`
**Return Values**
`\SpacesAPI\File`
<hr />
### Space::uploadText
**Description**
```php
public uploadText (string $text, string $filename, array $params = [], bool $private = true)
```
Upload a string of text to file
**Parameters**
* `(string) $text`
: The text to upload
* `(string) $filename`
: The filepath/name to save to
* `(array) $params`
: Any extra parameters. [See here](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property)
* `(bool) $private`
: True for the file to be private, false to allow public access
**Return Values**
`\SpacesAPI\File`
<hr />
================================================
FILE: docs/Spaces.md
================================================
# SpacesAPI\Spaces
Represents the connection to Digital Ocean spaces.
The entry point for managing spaces.
Instantiate your connection with `new \SpacesAPI\Spaces("access-key", "secret-key", "region")`
Obtain your access and secret keys from the [DigitalOcean Applications & API dashboard](https://cloud.digitalocean.com/account/api/tokens)
## Methods
| Name | Description |
|------|-------------|
|[__construct](#spaces__construct)|Initialise the API|
|[create](#spacescreate)|Create a new space|
|[list](#spaceslist)|List all your spaces|
|[space](#spacesspace)|Use an existing space|
### Spaces::__construct
**Description**
```php
public __construct (string $accessKey, string $secretKey, string $region = "ams3", string $host = "digitaloceanspaces.com)
```
Initialise the API
**Parameters**
* `(string) $accessKey`
: Digital Ocean API access key
* `(string) $secretKey`
: Digital Ocean API secret key
* `(string) $region`
: Region, defaults to `ams3`
* `(string) $host`
: API endpoint, defaults to `digitaloceanspaces.com`
**Return Values**
`void`
**Throws Exceptions**
`\SpacesAPI\Exceptions\AuthenticationException`
> Authentication failed
<hr />
### Spaces::create
**Description**
```php
public create (string $name, bool $public = false)
```
Create a new space
**Parameters**
* `(string) $name`
: The name of the new space
* `(bool) $public`
: Enable file listing. Default `false`
**Return Values**
`\SpacesAPI\Space`
> The newly created space
**Throws Exceptions**
`\SpacesAPI\Exceptions\SpaceExistsException`
> The named space already exists
<hr />
### Spaces::list
**Description**
```php
public list (void)
```
List all your spaces
**Parameters**
`This function has no parameters.`
**Return Values**
`array`
> An array of `\SpacesAPI\Space` instances indexed by the space name
<hr />
### Spaces::space
**Description**
```php
public space (string $name)
```
Use an existing space
**Parameters**
* `(string) $name`
: The name of the space
**Return Values**
`\SpacesAPI\Space`
> The loaded space
**Throws Exceptions**
`\SpacesAPI\Exceptions\SpaceDoesntExistException`
> The named space doesn't exist
<hr />
================================================
FILE: docs/Upgrade2-3.md
================================================
# Upgrade guide for v2 to v3
A lot has changed in this version release, so please read carefully to ensure you make all necessary changes.
## Namespace
Spaces-API is now namespaced, so you will need to add `use SpacesAPI\Spaces;` to the top of your files.
## Method changes
### `Spaces::__construct()`
Region is now passed into the Spaces constructor instead of the Space.
Old signature:
```
Spaces::__construct($accessKey, $secretKey, $host = "digitaloceanspaces.com")
```
New signature
```
Spaces::__construct(string $accessKey, string $secretKey, string $region = "ams3", string $host = "digitaloceanspaces.com")
```
***
### `Spaces::listSpaces()`
Method name has changed to `Spaces::list()`
***
### `Spaces::space()`
Signature has changed as the region is now passed into the `Spaces` constructor
Old signature:
```
Spaces::space($name, $region = "ams3")
```
New signature
```
Spaces::space(string $name)
```
***
### `Space::__contruct()`
Signature has changed as S3 credentials are no longer passed in, nor the region or host.
Old signature:
```
Space::__construct($name, $region, $accessKey, $secretKey, $host)
```
New signature
```
Space::__construct(S3Client $s3, string $name)
```
***
### `Space::create()`
This method has moved to the `Spaces` class and the signature has changed
Old signature:
```
Space::create($privacy = "private")
```
New signature
```
Spaces::create(string $name, bool $public = false)
```
***
### `Space::downloadToDirectory()`
Method name has changed. Parameter names have changed, but function the same way.
Old signature:
```
Space::downloadToDirectory($directory, $filesStartingAs = "")
```
New signature
```
Spaces::downloadDirectory(string $local, ?string $remote = null)
```
***
### `Space::upload()`
Method name and signature has changed
Old signature:
```
Space::upload($text, $saveAs, $privacy = "private", $params = array())
```
New signature
```
Spaces::uploadText(string $text, string $filename, array $params = [])
```
***
### `Space::uploadFile()`
`$privacy` parameter removed from signature. Parameter names have changed, but function the same way.
Old signature:
```
Space::uploadFile($filePath, $saveAs = "", $privacy = "private")
```
New signature
```
Spaces::uploadFile(string $filepath, ?string $filename = null)
```
***
### `Spaces::downloadFile()`
Method has moved to `File`, changed name and changed signature
Old signature:
```
Space::downloadFile($file, $saveTo = false)
```
New signature
```
File::download(string $saveAs)
```
***
### `Space::copyFile()`
Method has moved to `File`, changed name and changed signature
Old signature:
```
Space::copyFile($filePath, $saveAs, $toSpace = "", $privacy = "private")
```
New signature
```
File::copy(string $newFilename, bool $public = false)
```
***
### `Space::listFiles()`
Method signature has changed. This shouldn't have much impact as almost no-one should be using the second/third argument.
Old signature:
```
Space::listFiles($ofFolder = "", $autoIterate = true, $continueAfter = null)
```
New signature
```
Space::listFiles(string $directory = "", ?string $continuationToken = null)
```
***
### `Space::fileExists()`
Method removed.
If you need to check for file existence, instantiate a `File` object from the space, and catch the `FileDoesntExistException`
```php
try {
$space->file("filename.txt");
} catch (FileDoesntExistException $e) {
// Uh oh, the file doesn't exist
}
```
***
### `Space::fileInfo()`
Method removed
File information is now stored in properties on the `File` object
```php
$file = $space->file('filename.txt');
$file->content_type;
$file->content_length;
$file->expiration;
$file->e_tag;
$file->last_modified;
```
***
### `Space::url()`
Method moved to `File` and signature has changed
Old signature:
```
Space::url($path)
```
New signature
```
File::getURL()
```
***
### `Space::signedURL()`
Method moved to `File` and signature has changes
Old signature:
```
Space::signedURL($path, $validFor = "15 minutes")
```
New signature
```
File::getSignedURL($validFor = "15 minutes")
```
***
### `Space::deleteFolder()`
Method name has changed. Parameter name has changed, but meaning remains the same.
Old signature:
```
Space::deleteFolder($prefixOrPath)
```
New signature
```
File::deleteDirectory(string $path)
```
***
### `Space::deleteFile()`
Method has moved to `File` and signature has changed.
Old signature:
```
Space::deleteFile($path)
```
New signature
```
File::delete()
```
***
### `Space::filePrivacy()`
Method removed. Use `File::makePublic()` or `File::makePrivate()` instead.
***
### `Space::setCORS()`
Method removed. Use `Space::addCORSOrigin()`, `Space::removeCORSOrigin()` or `Space::removeAllCORSOrigins()` instead
### `Space::getLifecycleRules()`
Removed with no replacement.
### `Space::setLifecycleRules()`
Removed with no replacement.
================================================
FILE: tests/FileTest.php
================================================
<?php
use Dotenv\Dotenv;
use PHPUnit\Framework\TestCase;
use SpacesAPI\Exceptions\FileDoesntExistException;
use SpacesAPI\Exceptions\SpaceDoesntExistException;
use SpacesAPI\Spaces;
class FileTest extends TestCase
{
private static $tempSpaceName;
private static $space;
private static $file;
public static function setUpBeforeClass(): void
{
$dotenv = Dotenv::createImmutable(__DIR__ . "/..");
$dotenv->load();
$dotenv->required(['SPACES_KEY', 'SPACES_SECRET']);
$spaces = new Spaces($_ENV['SPACES_KEY'], $_ENV['SPACES_SECRET']);
self::$tempSpaceName = md5(time());
self::$space = $spaces->create(self::$tempSpaceName);
self::$file = self::$space->uploadText('Lorem ipsum', 'lorem-ipsum.txt');
}
public static function tearDownAfterClass(): void
{
self::$space->destroy();
}
public function testCanUpdatePrivacy()
{
$this->assertFalse(self::$file->isPublic());
self::$file->makePublic();
$this->assertTrue(self::$file->isPublic());
self::$file->makePrivate();
$this->assertFalse(self::$file->isPublic());
}
public function testCanGetContents()
{
$this->assertEquals("Lorem ipsum", self::$file->getContents());
}
public function testCanDownloadFile()
{
$filename = sys_get_temp_dir() . "/lorem.txt";
self::$file->download($filename);
$this->assertEquals("Lorem ipsum", file_get_contents($filename));
}
public function testCanCopyFile()
{
$this->expectNotToPerformAssertions();
self::$file->copy('lorem-ipsum-2.txt');
self::$space->file('lorem-ipsum-2.txt');
}
public function testCanMoveRenameFile()
{
$file = self::$file->copy('test.txt');
$file->move('renamed-file.txt');
$this->assertEquals("renamed-file.txt", $file->filename);
$this->expectException(FileDoesntExistException::class);
self::$space->file('test.txt');
}
public function testCanGetURL()
{
$this->assertStringContainsString('lorem-ipsum.txt', self::$file->getURL());
$this->assertStringContainsString('lorem-ipsum.txt', self::$file->getSignedURL());
}
public function testCanDeleteFile()
{
self::$file->delete();
$this->expectException(FileDoesntExistException::class);
self::$space->file('lorem-ipsum.txt');
}
}
================================================
FILE: tests/SpaceTest.php
================================================
<?php
use Dotenv\Dotenv;
use PHPUnit\Framework\TestCase;
use SpacesAPI\Exceptions\FileDoesntExistException;
use SpacesAPI\Exceptions\SpaceDoesntExistException;
use SpacesAPI\File;
use SpacesAPI\Spaces;
class SpaceTest extends TestCase
{
private static $tempSpaceName;
private static $space;
public static function setUpBeforeClass(): void
{
$dotenv = Dotenv::createImmutable(__DIR__ . "/..");
$dotenv->load();
$dotenv->required(['SPACES_KEY', 'SPACES_SECRET']);
$spaces = new Spaces($_ENV['SPACES_KEY'], $_ENV['SPACES_SECRET']);
self::$tempSpaceName = md5(time());
self::$space = $spaces->create(self::$tempSpaceName);
}
public static function tearDownAfterClass(): void
{
self::$space->destroy();
}
public function testCanUpdateSpacePrivacy()
{
$this->assertFalse(self::$space->isPublic());
self::$space->makePublic();
$this->assertTrue(self::$space->isPublic());
self::$space->makePrivate();
$this->assertFalse(self::$space->isPublic());
}
public function testCanAddCORSRule()
{
$this->assertNull(self::$space->getCORS());
self::$space->addCORSOrigin("http://example.com", ['GET', 'PUT'], 3200, ['custom-header']);
$cors = self::$space->getCORS();
$this->assertIsArray($cors);
$this->assertEquals('custom-header', $cors[0]['AllowedHeaders'][0]);
$this->assertEquals('GET', $cors[0]['AllowedMethods'][0]);
$this->assertEquals('PUT', $cors[0]['AllowedMethods'][1]);
$this->assertEquals('http://example.com', $cors[0]['AllowedOrigins'][0]);
$this->assertEquals(3200, $cors[0]['MaxAgeSeconds']);
self::$space->removeCORSOrigin('http://example.com');
$this->assertNull(self::$space->getCORS());
}
public function testFileDoesntExistException()
{
$this->expectException(FileDoesntExistException::class);
self::$space->file("non-existent.txt");
}
public function testCanUploadText()
{
$file = self::$space->uploadText("Lorem ipsum", "lorem-ipsum.txt");
$this->assertInstanceOf(File::class, $file);
$this->assertFalse($file->isPublic());
}
public function testCanPublicUploadText()
{
$file = self::$space->uploadText("Lorem ipsum", "lorem-ipsum.txt", [], false);
$this->assertInstanceOf(File::class, $file);
$this->assertTrue($file->isPublic());
}
public function testCanUploadFile()
{
$tmpFile = tempnam(sys_get_temp_dir(), 'spaces-test');
$file = self::$space->uploadFile($tmpFile, 'upload-test.txt');
$this->assertInstanceOf(File::class, $file);
}
public function testCanUploadFileWithMimeType()
{
$tmpFile = tempnam(sys_get_temp_dir(), 'spaces-test');
$file = self::$space->uploadFile($tmpFile, 'upload-test.txt', 'text/plain');
$this->assertInstanceOf(File::class, $file);
$this->assertEquals('text/plain', $file->content_type);
}
/**
* @depends testCanUploadText
* @depends testCanUploadFile
*/
public function testFileExists()
{
$file = self::$space->file('lorem-ipsum.txt');
$this->assertInstanceOf(File::class, $file);
$file = self::$space->file('upload-test.txt');
$this->assertInstanceOf(File::class, $file);
}
/**
* @depends testCanUploadText
* @depends testCanUploadFile
*/
public function testCanListFiles()
{
$files = self::$space->listFiles()['files'];
$this->assertIsArray($files);
$this->assertCount(2, $files);
$this->assertInstanceOf(File::class, $files[array_key_first($files)]);
foreach ($files as $filename => $file) {
$this->assertEquals($file->filename, $filename);
}
foreach ($files as $file) {
$file->delete();
}
}
public function testCanUploadDirectory()
{
$localDirectory = sys_get_temp_dir() . "/spaces-upload-test";
@mkdir($localDirectory);
for($i=1; $i<=10; $i++) {
file_put_contents("$localDirectory/test-$i.txt", "Lorem ipsum $i");
}
self::$space->uploadDirectory($localDirectory, 'remote-dir');
$list = self::$space->listFiles()['files'];
$this->assertIsArray($list);
$this->assertCount(10, $list);
for ($i = 1; $i <= 10; $i++) {
unlink("$localDirectory/test-$i.txt");
}
$this->assertCount(2, scandir($localDirectory));
}
/**
* @depends testCanUploadDirectory
*/
public function testCanDownloadDirectory()
{
$localDirectory = sys_get_temp_dir() . "/spaces-upload-test";
$this->assertCount(2, scandir($localDirectory));
self::$space->downloadDirectory($localDirectory, 'remote-dir');
$this->assertCount(12, scandir($localDirectory));
for ($i = 1; $i <= 10; $i++) {
unlink("$localDirectory/test-$i.txt");
}
$this->assertCount(2, scandir($localDirectory));
}
public function testCanDeleteDirectory()
{
$list = self::$space->listFiles()['files'];
$this->assertIsArray($list);
$this->assertCount(10, $list);
self::$space->deleteDirectory('remote-dir');
$list = self::$space->listFiles()['files'];
$this->assertIsArray($list);
$this->assertCount(0, $list);
}
}
================================================
FILE: tests/SpacesTest.php
================================================
<?php
use Dotenv\Dotenv;
use PHPUnit\Framework\TestCase;
use SpacesAPI\Exceptions\AuthenticationException;
use SpacesAPI\Exceptions\SpaceDoesntExistException;
use SpacesAPI\Exceptions\SpaceExistsException;
use SpacesAPI\Space;
use SpacesAPI\Spaces;
class SpacesTest extends TestCase
{
private static $tempSpaceName;
public static function setUpBeforeClass(): void
{
$dotenv = Dotenv::createImmutable(__DIR__ . "/..");
$dotenv->load();
$dotenv->required(['SPACES_KEY', 'SPACES_SECRET']);
// This should hopefully always be unique amongst all DO spaces
self::$tempSpaceName = md5(time());
}
public static function tearDownAfterClass(): void
{
(new Spaces($_ENV['SPACES_KEY'], $_ENV['SPACES_SECRET']))->space(self::$tempSpaceName)->destroy();
}
public function testAuthenticationCanFail()
{
$this->expectException(AuthenticationException::class);
new Spaces("fake", "fake");
}
public function testCanAuthenticate()
{
$this->expectNotToPerformAssertions();
return new Spaces($_ENV['SPACES_KEY'], $_ENV['SPACES_SECRET']);
}
/**
* @depends testCanAuthenticate
*/
public function testCreateSpaceFailsWithExistingSpace(Spaces $spaces)
{
$this->expectException(SpaceExistsException::class);
$spaces->create('test');
}
/**
* @depends testCanAuthenticate
*/
public function testCanCreateSpace(Spaces $spaces)
{
$space = $spaces->create(self::$tempSpaceName);
$this->assertInstanceOf(Space::class, $space);
return $space;
}
/**
* @depends testCanAuthenticate
*/
public function testCanListSpaces(Spaces $spaces)
{
$list = $spaces->list();
$this->assertIsArray($list);
$spaceFound = false;
foreach ($list as $name => $space) {
if ($name == self::$tempSpaceName && $space->getName() == self::$tempSpaceName) {
$spaceFound = true;
}
}
$this->assertTrue($spaceFound);
}
/**
* @depends testCanAuthenticate
*/
public function testUseSpaceFailsWithNonExistentSpace(Spaces $spaces)
{
$this->expectException(SpaceDoesntExistException::class);
$spaces->space(md5(time()));
}
}
gitextract_zsmmkxin/
├── .editorconfig
├── .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
├── docs/
│ ├── Examples.md
│ ├── File.md
│ ├── Space.md
│ ├── Spaces.md
│ └── Upgrade2-3.md
└── tests/
├── FileTest.php
├── SpaceTest.php
└── SpacesTest.php
SYMBOL INDEX (87 symbols across 13 files)
FILE: SpacesAPI/Exceptions/AuthenticationException.php
class AuthenticationException (line 7) | class AuthenticationException extends Exception {}
FILE: SpacesAPI/Exceptions/FileDoesntExistException.php
class FileDoesntExistException (line 7) | class FileDoesntExistException extends Exception
FILE: SpacesAPI/Exceptions/SpaceDoesntExistException.php
class SpaceDoesntExistException (line 7) | class SpaceDoesntExistException extends Exception
FILE: SpacesAPI/Exceptions/SpaceExistsException.php
class SpaceExistsException (line 7) | class SpaceExistsException extends Exception {}
FILE: SpacesAPI/Exceptions/SpacesException.php
class SpacesException (line 7) | class SpacesException extends Exception
FILE: SpacesAPI/File.php
class File (line 22) | class File
method __construct (line 58) | public function __construct(Space $space, string $filename, array $inf...
method __get (line 81) | public function __get(string $name)
method setFileInfo (line 98) | private function setFileInfo(array $info): void
method fetchFileInfo (line 116) | private function fetchFileInfo(): void
method isPublic (line 133) | public function isPublic(): bool
method updatePrivacy (line 154) | private function updatePrivacy(bool $public): void
method makePublic (line 166) | public function makePublic(): void
method makePrivate (line 174) | public function makePrivate(): void
method getContents (line 184) | public function getContents(): string
method download (line 199) | public function download(string $saveAs): void
method copy (line 216) | public function copy(string $newFilename): File
method move (line 234) | public function move(string $newFilename): File
method getURL (line 252) | public function getURL(): string
method getSignedURL (line 264) | public function getSignedURL($validFor = "15 minutes"): string
method delete (line 278) | public function delete(): void
FILE: SpacesAPI/Result.php
class Result (line 10) | class Result
method parse (line 19) | public static function parse($data) {
FILE: SpacesAPI/Space.php
class Space (line 15) | class Space
method __construct (line 43) | public function __construct(S3Client $s3, string $name, bool $validate...
method getS3Client (line 60) | public function getS3Client(): S3Client
method getName (line 70) | public function getName(): string
method updatePrivacy (line 80) | private function updatePrivacy(bool $public): void
method makePublic (line 91) | public function makePublic(): void
method makePrivate (line 99) | public function makePrivate(): void
method isPublic (line 109) | public function isPublic(): bool
method destroy (line 123) | public function destroy(): void
method getCORS (line 134) | public function getCORS(): ?array
method getCORSRemovingOrigin (line 154) | private function getCORSRemovingOrigin(string $origin): array
method putCORS (line 174) | private function putCORS(array $rules): void
method addCORSOrigin (line 192) | public function addCORSOrigin(string $origin, array $methods, int $max...
method removeCORSOrigin (line 213) | public function removeCORSOrigin(string $origin): void
method removeAllCORSOrigins (line 227) | public function removeAllCORSOrigins(): void
method listFiles (line 241) | public function listFiles(string $directory = ""): array
method rawListFiles (line 259) | private function rawListFiles(string $directory = "", ?string $continu...
method uploadText (line 295) | public function uploadText(string $text, string $filename, array $para...
method uploadFile (line 311) | public function uploadFile(string $filepath, ?string $filename = null,...
method file (line 333) | public function file(string $filename, bool $validate = true): File
method uploadDirectory (line 344) | public function uploadDirectory(string $local, ?string $remote = null)...
method downloadDirectory (line 355) | public function downloadDirectory(string $local, ?string $remote = nul...
method deleteDirectory (line 365) | public function deleteDirectory(string $path): void
FILE: SpacesAPI/Spaces.php
class Spaces (line 18) | class Spaces
method __construct (line 35) | public function __construct(string $accessKey, string $secretKey, stri...
method list (line 59) | public function list(): array
method create (line 79) | public function create(string $name, bool $public = false): Space
method space (line 101) | public function space(string $name): Space
FILE: SpacesAPI/StringFunctions.php
type StringFunctions (line 5) | trait StringFunctions
method pascalCaseToCamelCase (line 7) | public function pascalCaseToCamelCase(string $name): string
FILE: tests/FileTest.php
class FileTest (line 9) | class FileTest extends TestCase
method setUpBeforeClass (line 15) | public static function setUpBeforeClass(): void
method tearDownAfterClass (line 29) | public static function tearDownAfterClass(): void
method testCanUpdatePrivacy (line 34) | public function testCanUpdatePrivacy()
method testCanGetContents (line 45) | public function testCanGetContents()
method testCanDownloadFile (line 50) | public function testCanDownloadFile()
method testCanCopyFile (line 58) | public function testCanCopyFile()
method testCanMoveRenameFile (line 65) | public function testCanMoveRenameFile()
method testCanGetURL (line 76) | public function testCanGetURL()
method testCanDeleteFile (line 82) | public function testCanDeleteFile()
FILE: tests/SpaceTest.php
class SpaceTest (line 10) | class SpaceTest extends TestCase
method setUpBeforeClass (line 15) | public static function setUpBeforeClass(): void
method tearDownAfterClass (line 28) | public static function tearDownAfterClass(): void
method testCanUpdateSpacePrivacy (line 33) | public function testCanUpdateSpacePrivacy()
method testCanAddCORSRule (line 44) | public function testCanAddCORSRule()
method testFileDoesntExistException (line 62) | public function testFileDoesntExistException()
method testCanUploadText (line 68) | public function testCanUploadText()
method testCanPublicUploadText (line 75) | public function testCanPublicUploadText()
method testCanUploadFile (line 82) | public function testCanUploadFile()
method testCanUploadFileWithMimeType (line 89) | public function testCanUploadFileWithMimeType()
method testFileExists (line 101) | public function testFileExists()
method testCanListFiles (line 114) | public function testCanListFiles()
method testCanUploadDirectory (line 130) | public function testCanUploadDirectory()
method testCanDownloadDirectory (line 154) | public function testCanDownloadDirectory()
method testCanDeleteDirectory (line 170) | public function testCanDeleteDirectory()
FILE: tests/SpacesTest.php
class SpacesTest (line 11) | class SpacesTest extends TestCase
method setUpBeforeClass (line 15) | public static function setUpBeforeClass(): void
method tearDownAfterClass (line 25) | public static function tearDownAfterClass(): void
method testAuthenticationCanFail (line 30) | public function testAuthenticationCanFail()
method testCanAuthenticate (line 36) | public function testCanAuthenticate()
method testCreateSpaceFailsWithExistingSpace (line 45) | public function testCreateSpaceFailsWithExistingSpace(Spaces $spaces)
method testCanCreateSpace (line 54) | public function testCanCreateSpace(Spaces $spaces)
method testCanListSpaces (line 65) | public function testCanListSpaces(Spaces $spaces)
method testUseSpaceFailsWithNonExistentSpace (line 83) | public function testUseSpaceFailsWithNonExistentSpace(Spaces $spaces)
Condensed preview — 27 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (113K chars).
[
{
"path": ".editorconfig",
"chars": 46951,
"preview": "[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\nmax_line_length = "
},
{
"path": ".github/ISSUE_TEMPLATE/BUG.yml",
"chars": 1003,
"preview": "name: Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\nlabels: [ bug, triage ]\nassignees:\n - MacroMan\nbody:\n "
},
{
"path": ".github/ISSUE_TEMPLATE/FEATURE.yml",
"chars": 396,
"preview": "name: Feature request\ndescription: Request new functionality\ntitle: \"[Feature]: \"\nlabels: [ new ]\nassignees:\n - MacroMa"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 28,
"preview": "blank_issues_enabled: false\n"
},
{
"path": ".gitignore",
"chars": 52,
"preview": ".DS_Store\nvendor/\n.idea/\n.env\n.phpunit.result.cache\n"
},
{
"path": ".phpdoc-md",
"chars": 230,
"preview": "<?php\n\nreturn (object)[\n 'rootNamespace' => 'SpacesAPI',\n 'destDirectory' => 'docs',\n 'format' => 'github',\n "
},
{
"path": "LICENSE",
"chars": 1074,
"preview": "MIT License\n\nCopyright (c) 2020 Devang Srivastava\n\nPermission is hereby granted, free of charge, to any person obtaining"
},
{
"path": "README.md",
"chars": 1421,
"preview": "# This library is deprecated\nWe recommend using the [official SDK](https://github.com/DigitalOceanPHP/Client) or the [La"
},
{
"path": "SpacesAPI/Exceptions/AuthenticationException.php",
"chars": 107,
"preview": "<?php\n\nnamespace SpacesAPI\\Exceptions;\n\nuse Exception;\n\nclass AuthenticationException extends Exception {}\n"
},
{
"path": "SpacesAPI/Exceptions/FileDoesntExistException.php",
"chars": 109,
"preview": "<?php\n\nnamespace SpacesAPI\\Exceptions;\n\nuse Exception;\n\nclass FileDoesntExistException extends Exception\n{\n}\n"
},
{
"path": "SpacesAPI/Exceptions/SpaceDoesntExistException.php",
"chars": 110,
"preview": "<?php\n\nnamespace SpacesAPI\\Exceptions;\n\nuse Exception;\n\nclass SpaceDoesntExistException extends Exception\n{\n}\n"
},
{
"path": "SpacesAPI/Exceptions/SpaceExistsException.php",
"chars": 104,
"preview": "<?php\n\nnamespace SpacesAPI\\Exceptions;\n\nuse Exception;\n\nclass SpaceExistsException extends Exception {}\n"
},
{
"path": "SpacesAPI/Exceptions/SpacesException.php",
"chars": 100,
"preview": "<?php\n\nnamespace SpacesAPI\\Exceptions;\n\nuse Exception;\n\nclass SpacesException extends Exception\n{\n}\n"
},
{
"path": "SpacesAPI/File.php",
"chars": 7431,
"preview": "<?php\n\nnamespace SpacesAPI;\n\nuse SpacesAPI\\Exceptions\\FileDoesntExistException;\n\nuse function PHPUnit\\Framework\\isNull;\n"
},
{
"path": "SpacesAPI/Result.php",
"chars": 792,
"preview": "<?php\n\nnamespace SpacesAPI;\n\nuse Aws\\Api\\DateTimeResult;\n\n/**\n * AWS Results parser\n */\nclass Result\n{\n /**\n * Co"
},
{
"path": "SpacesAPI/Space.php",
"chars": 11143,
"preview": "<?php\n\nnamespace SpacesAPI;\n\nuse Aws\\S3\\Exception\\S3Exception;\nuse Aws\\S3\\S3Client;\nuse SpacesAPI\\Exceptions\\SpaceDoesnt"
},
{
"path": "SpacesAPI/Spaces.php",
"chars": 3399,
"preview": "<?php\n\nnamespace SpacesAPI;\n\nuse Aws\\S3\\Exception\\S3Exception;\nuse Aws\\S3\\S3Client;\nuse SpacesAPI\\Exceptions\\Authenticat"
},
{
"path": "SpacesAPI/StringFunctions.php",
"chars": 208,
"preview": "<?php\n\nnamespace SpacesAPI;\n\ntrait StringFunctions\n{\n public function pascalCaseToCamelCase(string $name): string\n "
},
{
"path": "composer.json",
"chars": 710,
"preview": "{\n \"name\": \"sociallydev/spaces-api\",\n \"description\": \"Library for accessing Digital Ocean spaces\",\n \"version\":\"3.6.1\""
},
{
"path": "docs/Examples.md",
"chars": 2486,
"preview": "# Examples\n\n## Connecting to Digital Ocean and selecting a space\n\n```php\nuse SpacesAPI\\Spaces;\n\n$spaces = new Spaces('ap"
},
{
"path": "docs/File.md",
"chars": 4340,
"preview": "# SpacesAPI\\File\n\nRepresents a single file\n\nYou wouldn't normally instantiate this class directly,\nRather obtain an inst"
},
{
"path": "docs/Space.md",
"chars": 7885,
"preview": "# SpacesAPI\\Space\n\nRepresents a space once connected/created\n\nYou wouldn't normally instantiate this class directly,\nRat"
},
{
"path": "docs/Spaces.md",
"chars": 2192,
"preview": "# SpacesAPI\\Spaces\n\nRepresents the connection to Digital Ocean spaces.\n\nThe entry point for managing spaces.\n\nInstantiat"
},
{
"path": "docs/Upgrade2-3.md",
"chars": 4900,
"preview": "# Upgrade guide for v2 to v3\n\nA lot has changed in this version release, so please read carefully to ensure you make all"
},
{
"path": "tests/FileTest.php",
"chars": 2459,
"preview": "<?php\n\nuse Dotenv\\Dotenv;\nuse PHPUnit\\Framework\\TestCase;\nuse SpacesAPI\\Exceptions\\FileDoesntExistException;\nuse SpacesA"
},
{
"path": "tests/SpaceTest.php",
"chars": 5509,
"preview": "<?php\n\nuse Dotenv\\Dotenv;\nuse PHPUnit\\Framework\\TestCase;\nuse SpacesAPI\\Exceptions\\FileDoesntExistException;\nuse SpacesA"
},
{
"path": "tests/SpacesTest.php",
"chars": 2349,
"preview": "<?php\n\nuse Dotenv\\Dotenv;\nuse PHPUnit\\Framework\\TestCase;\nuse SpacesAPI\\Exceptions\\AuthenticationException;\nuse SpacesAP"
}
]
About this extraction
This page contains the full source code of the SociallyDev/Spaces-API GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 27 files (105.0 KB), approximately 27.0k tokens, and a symbol index with 87 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.