├── .editorconfig
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── lint-check.yml
│ └── lint-fixer.yml
├── LICENSE
├── README.md
├── composer.json
├── config
└── notifex.php
├── migrations
├── 2018_07_11_140701_create_error_notifications_table.php
└── 2019_03_12_140701_delete_error_notifications_table.php
├── resources
└── views
│ ├── body.blade.php
│ ├── raw.blade.php
│ └── subject.blade.php
└── src
├── Abstracts
└── JobAbstract.php
├── Console
└── TestException.php
├── Exceptions
└── NotifexTestException.php
├── Facades
├── App.php
└── Http.php
├── Interfaces
└── JobInterface.php
├── Jobs
├── ExampleJob.php
├── JiraJob.php
└── SlackJob.php
├── Mail
└── ExceptionEmail.php
├── Notifications
└── SlackNotify.php
├── ServiceProvider.php
├── Services
├── Email.php
├── ExceptionHandler.php
└── NotifyException.php
├── Support
├── App.php
└── Http.php
└── Traits
└── JobsConfiguration.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | charset = utf-8
3 | end_of_line = lf
4 | indent_size = 4
5 | indent_style = space
6 | insert_final_newline = true
7 | max_line_length = 180
8 | tab_width = 4
9 | trim_trailing_whitespace = false
10 | ij_continuation_indent_size = 8
11 | ij_formatter_off_tag = @formatter:off
12 | ij_formatter_on_tag = @formatter:on
13 | ij_formatter_tags_enabled = true
14 | ij_smart_tabs = false
15 | ij_visual_guides = none
16 | ij_wrap_on_typing = false
17 |
18 | [*.blade.php]
19 | ij_continuation_indent_size = 4
20 | ij_blade_keep_indents_on_empty_lines = false
21 |
22 | [*.css]
23 | ij_css_align_closing_brace_with_properties = false
24 | ij_css_blank_lines_around_nested_selector = 1
25 | ij_css_blank_lines_between_blocks = 1
26 | ij_css_block_comment_add_space = true
27 | ij_css_brace_placement = end_of_line
28 | ij_css_enforce_quotes_on_format = true
29 | ij_css_hex_color_long_format = true
30 | ij_css_hex_color_lower_case = false
31 | ij_css_hex_color_short_format = false
32 | ij_css_hex_color_upper_case = true
33 | ij_css_keep_blank_lines_in_code = 1
34 | ij_css_keep_indents_on_empty_lines = false
35 | ij_css_keep_single_line_blocks = false
36 | ij_css_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
37 | ij_css_space_after_colon = true
38 | ij_css_space_before_opening_brace = true
39 | ij_css_use_double_quotes = true
40 | ij_css_value_alignment = do_not_align
41 |
42 | [*.haml]
43 | indent_size = 2
44 | ij_haml_keep_indents_on_empty_lines = false
45 |
46 | [*.less]
47 | indent_size = 2
48 | ij_less_align_closing_brace_with_properties = false
49 | ij_less_blank_lines_around_nested_selector = 1
50 | ij_less_blank_lines_between_blocks = 1
51 | ij_less_block_comment_add_space = false
52 | ij_less_brace_placement = 0
53 | ij_less_enforce_quotes_on_format = false
54 | ij_less_hex_color_long_format = true
55 | ij_less_hex_color_lower_case = false
56 | ij_less_hex_color_short_format = false
57 | ij_less_hex_color_upper_case = true
58 | ij_less_keep_blank_lines_in_code = 2
59 | ij_less_keep_indents_on_empty_lines = false
60 | ij_less_keep_single_line_blocks = false
61 | ij_less_line_comment_add_space = false
62 | ij_less_line_comment_at_first_column = false
63 | 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
64 | ij_less_space_after_colon = true
65 | ij_less_space_before_opening_brace = true
66 | ij_less_use_double_quotes = true
67 | ij_less_value_alignment = 0
68 |
69 | [*.sass]
70 | indent_size = 2
71 | ij_sass_align_closing_brace_with_properties = false
72 | ij_sass_blank_lines_around_nested_selector = 1
73 | ij_sass_blank_lines_between_blocks = 1
74 | ij_sass_brace_placement = 0
75 | ij_sass_enforce_quotes_on_format = false
76 | ij_sass_hex_color_long_format = false
77 | ij_sass_hex_color_lower_case = false
78 | ij_sass_hex_color_short_format = false
79 | ij_sass_hex_color_upper_case = false
80 | ij_sass_keep_blank_lines_in_code = 2
81 | ij_sass_keep_indents_on_empty_lines = false
82 | ij_sass_keep_single_line_blocks = false
83 | ij_sass_line_comment_add_space = false
84 | ij_sass_line_comment_at_first_column = false
85 | 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
86 | ij_sass_space_after_colon = true
87 | ij_sass_space_before_opening_brace = true
88 | ij_sass_use_double_quotes = true
89 | ij_sass_value_alignment = 0
90 |
91 | [*.scss]
92 | ij_scss_align_closing_brace_with_properties = false
93 | ij_scss_blank_lines_around_nested_selector = 1
94 | ij_scss_blank_lines_between_blocks = 1
95 | ij_scss_block_comment_add_space = true
96 | ij_scss_brace_placement = 0
97 | ij_scss_enforce_quotes_on_format = true
98 | ij_scss_hex_color_long_format = true
99 | ij_scss_hex_color_lower_case = false
100 | ij_scss_hex_color_short_format = false
101 | ij_scss_hex_color_upper_case = true
102 | ij_scss_keep_blank_lines_in_code = 1
103 | ij_scss_keep_indents_on_empty_lines = false
104 | ij_scss_keep_single_line_blocks = false
105 | ij_scss_line_comment_add_space = false
106 | ij_scss_line_comment_at_first_column = false
107 | ij_scss_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
108 | ij_scss_space_after_colon = true
109 | ij_scss_space_before_opening_brace = true
110 | ij_scss_use_double_quotes = true
111 | ij_scss_value_alignment = 0
112 |
113 | [*.twig]
114 | ij_twig_keep_indents_on_empty_lines = false
115 | ij_twig_spaces_inside_comments_delimiters = true
116 | ij_twig_spaces_inside_delimiters = true
117 | ij_twig_spaces_inside_variable_delimiters = true
118 |
119 | [*.vue]
120 | ij_continuation_indent_size = 4
121 | ij_vue_indent_children_of_top_level = template
122 | ij_vue_interpolation_new_line_after_start_delimiter = true
123 | ij_vue_interpolation_new_line_before_end_delimiter = true
124 | ij_vue_interpolation_wrap = off
125 | ij_vue_keep_indents_on_empty_lines = false
126 | ij_vue_spaces_within_interpolation_expressions = true
127 |
128 | [.editorconfig]
129 | ij_editorconfig_align_group_field_declarations = false
130 | ij_editorconfig_space_after_colon = false
131 | ij_editorconfig_space_after_comma = true
132 | ij_editorconfig_space_before_colon = false
133 | ij_editorconfig_space_before_comma = false
134 | ij_editorconfig_spaces_around_assignment_operators = true
135 |
136 | [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}]
137 | ij_xml_align_attributes = true
138 | ij_xml_align_text = false
139 | ij_xml_attribute_wrap = normal
140 | ij_xml_block_comment_add_space = true
141 | ij_xml_block_comment_at_first_column = true
142 | ij_xml_keep_blank_lines = 2
143 | ij_xml_keep_indents_on_empty_lines = false
144 | ij_xml_keep_line_breaks = true
145 | ij_xml_keep_line_breaks_in_text = true
146 | ij_xml_keep_whitespaces = false
147 | ij_xml_keep_whitespaces_around_cdata = preserve
148 | ij_xml_keep_whitespaces_inside_cdata = false
149 | ij_xml_line_comment_at_first_column = true
150 | ij_xml_space_after_tag_name = false
151 | ij_xml_space_around_equals_in_attribute = false
152 | ij_xml_space_inside_empty_tag = true
153 | ij_xml_text_wrap = normal
154 |
155 | [{*.ats,*.cts,*.mts,*.ts}]
156 | ij_continuation_indent_size = 4
157 | ij_typescript_align_imports = false
158 | ij_typescript_align_multiline_array_initializer_expression = false
159 | ij_typescript_align_multiline_binary_operation = false
160 | ij_typescript_align_multiline_chained_methods = false
161 | ij_typescript_align_multiline_extends_list = false
162 | ij_typescript_align_multiline_for = true
163 | ij_typescript_align_multiline_parameters = true
164 | ij_typescript_align_multiline_parameters_in_calls = false
165 | ij_typescript_align_multiline_ternary_operation = false
166 | ij_typescript_align_object_properties = 0
167 | ij_typescript_align_union_types = false
168 | ij_typescript_align_var_statements = 0
169 | ij_typescript_array_initializer_new_line_after_left_brace = false
170 | ij_typescript_array_initializer_right_brace_on_new_line = false
171 | ij_typescript_array_initializer_wrap = off
172 | ij_typescript_assignment_wrap = off
173 | ij_typescript_binary_operation_sign_on_next_line = false
174 | ij_typescript_binary_operation_wrap = off
175 | ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
176 | ij_typescript_blank_lines_after_imports = 1
177 | ij_typescript_blank_lines_around_class = 1
178 | ij_typescript_blank_lines_around_field = 0
179 | ij_typescript_blank_lines_around_field_in_interface = 0
180 | ij_typescript_blank_lines_around_function = 1
181 | ij_typescript_blank_lines_around_method = 1
182 | ij_typescript_blank_lines_around_method_in_interface = 1
183 | ij_typescript_block_brace_style = end_of_line
184 | ij_typescript_block_comment_add_space = false
185 | ij_typescript_block_comment_at_first_column = true
186 | ij_typescript_call_parameters_new_line_after_left_paren = false
187 | ij_typescript_call_parameters_right_paren_on_new_line = false
188 | ij_typescript_call_parameters_wrap = off
189 | ij_typescript_catch_on_new_line = false
190 | ij_typescript_chained_call_dot_on_new_line = true
191 | ij_typescript_class_brace_style = next_line
192 | ij_typescript_comma_on_new_line = false
193 | ij_typescript_do_while_brace_force = never
194 | ij_typescript_else_on_new_line = false
195 | ij_typescript_enforce_trailing_comma = remove
196 | ij_typescript_enum_constants_wrap = on_every_item
197 | ij_typescript_extends_keyword_wrap = off
198 | ij_typescript_extends_list_wrap = off
199 | ij_typescript_field_prefix = _
200 | ij_typescript_file_name_style = relaxed
201 | ij_typescript_finally_on_new_line = false
202 | ij_typescript_for_brace_force = never
203 | ij_typescript_for_statement_new_line_after_left_paren = false
204 | ij_typescript_for_statement_right_paren_on_new_line = false
205 | ij_typescript_for_statement_wrap = off
206 | ij_typescript_force_quote_style = true
207 | ij_typescript_force_semicolon_style = true
208 | ij_typescript_function_expression_brace_style = end_of_line
209 | ij_typescript_if_brace_force = never
210 | ij_typescript_import_merge_members = global
211 | ij_typescript_import_prefer_absolute_path = global
212 | ij_typescript_import_sort_members = true
213 | ij_typescript_import_sort_module_name = false
214 | ij_typescript_import_use_node_resolution = true
215 | ij_typescript_imports_wrap = on_every_item
216 | ij_typescript_indent_case_from_switch = true
217 | ij_typescript_indent_chained_calls = true
218 | ij_typescript_indent_package_children = 0
219 | ij_typescript_jsdoc_include_types = false
220 | ij_typescript_jsx_attribute_value = braces
221 | ij_typescript_keep_blank_lines_in_code = 1
222 | ij_typescript_keep_first_column_comment = true
223 | ij_typescript_keep_indents_on_empty_lines = false
224 | ij_typescript_keep_line_breaks = true
225 | ij_typescript_keep_simple_blocks_in_one_line = false
226 | ij_typescript_keep_simple_methods_in_one_line = false
227 | ij_typescript_line_comment_add_space = true
228 | ij_typescript_line_comment_at_first_column = false
229 | ij_typescript_method_brace_style = next_line
230 | ij_typescript_method_call_chain_wrap = off
231 | ij_typescript_method_parameters_new_line_after_left_paren = false
232 | ij_typescript_method_parameters_right_paren_on_new_line = false
233 | ij_typescript_method_parameters_wrap = off
234 | ij_typescript_object_literal_wrap = on_every_item
235 | ij_typescript_parentheses_expression_new_line_after_left_paren = false
236 | ij_typescript_parentheses_expression_right_paren_on_new_line = false
237 | ij_typescript_place_assignment_sign_on_next_line = false
238 | ij_typescript_prefer_as_type_cast = false
239 | ij_typescript_prefer_explicit_types_function_expression_returns = false
240 | ij_typescript_prefer_explicit_types_function_returns = false
241 | ij_typescript_prefer_explicit_types_vars_fields = false
242 | ij_typescript_prefer_parameters_wrap = false
243 | ij_typescript_reformat_c_style_comments = false
244 | ij_typescript_space_after_colon = true
245 | ij_typescript_space_after_comma = true
246 | ij_typescript_space_after_dots_in_rest_parameter = false
247 | ij_typescript_space_after_generator_mult = true
248 | ij_typescript_space_after_property_colon = true
249 | ij_typescript_space_after_quest = true
250 | ij_typescript_space_after_type_colon = true
251 | ij_typescript_space_after_unary_not = true
252 | ij_typescript_space_before_async_arrow_lparen = true
253 | ij_typescript_space_before_catch_keyword = true
254 | ij_typescript_space_before_catch_left_brace = true
255 | ij_typescript_space_before_catch_parentheses = true
256 | ij_typescript_space_before_class_lbrace = true
257 | ij_typescript_space_before_class_left_brace = true
258 | ij_typescript_space_before_colon = true
259 | ij_typescript_space_before_comma = false
260 | ij_typescript_space_before_do_left_brace = true
261 | ij_typescript_space_before_else_keyword = true
262 | ij_typescript_space_before_else_left_brace = true
263 | ij_typescript_space_before_finally_keyword = true
264 | ij_typescript_space_before_finally_left_brace = true
265 | ij_typescript_space_before_for_left_brace = true
266 | ij_typescript_space_before_for_parentheses = true
267 | ij_typescript_space_before_for_semicolon = false
268 | ij_typescript_space_before_function_left_parenth = true
269 | ij_typescript_space_before_generator_mult = false
270 | ij_typescript_space_before_if_left_brace = true
271 | ij_typescript_space_before_if_parentheses = true
272 | ij_typescript_space_before_method_call_parentheses = false
273 | ij_typescript_space_before_method_left_brace = true
274 | ij_typescript_space_before_method_parentheses = false
275 | ij_typescript_space_before_property_colon = false
276 | ij_typescript_space_before_quest = true
277 | ij_typescript_space_before_switch_left_brace = true
278 | ij_typescript_space_before_switch_parentheses = true
279 | ij_typescript_space_before_try_left_brace = true
280 | ij_typescript_space_before_type_colon = false
281 | ij_typescript_space_before_unary_not = false
282 | ij_typescript_space_before_while_keyword = true
283 | ij_typescript_space_before_while_left_brace = true
284 | ij_typescript_space_before_while_parentheses = true
285 | ij_typescript_spaces_around_additive_operators = true
286 | ij_typescript_spaces_around_arrow_function_operator = true
287 | ij_typescript_spaces_around_assignment_operators = true
288 | ij_typescript_spaces_around_bitwise_operators = true
289 | ij_typescript_spaces_around_equality_operators = true
290 | ij_typescript_spaces_around_logical_operators = true
291 | ij_typescript_spaces_around_multiplicative_operators = true
292 | ij_typescript_spaces_around_relational_operators = true
293 | ij_typescript_spaces_around_shift_operators = true
294 | ij_typescript_spaces_around_unary_operator = false
295 | ij_typescript_spaces_within_array_initializer_brackets = false
296 | ij_typescript_spaces_within_brackets = false
297 | ij_typescript_spaces_within_catch_parentheses = false
298 | ij_typescript_spaces_within_for_parentheses = false
299 | ij_typescript_spaces_within_if_parentheses = false
300 | ij_typescript_spaces_within_imports = true
301 | ij_typescript_spaces_within_interpolation_expressions = true
302 | ij_typescript_spaces_within_method_call_parentheses = false
303 | ij_typescript_spaces_within_method_parentheses = false
304 | ij_typescript_spaces_within_object_literal_braces = true
305 | ij_typescript_spaces_within_object_type_braces = true
306 | ij_typescript_spaces_within_parentheses = false
307 | ij_typescript_spaces_within_switch_parentheses = false
308 | ij_typescript_spaces_within_type_assertion = false
309 | ij_typescript_spaces_within_union_types = true
310 | ij_typescript_spaces_within_while_parentheses = false
311 | ij_typescript_special_else_if_treatment = true
312 | ij_typescript_ternary_operation_signs_on_next_line = false
313 | ij_typescript_ternary_operation_wrap = off
314 | ij_typescript_union_types_wrap = on_every_item
315 | ij_typescript_use_chained_calls_group_indents = false
316 | ij_typescript_use_double_quotes = false
317 | ij_typescript_use_explicit_js_extension = auto
318 | ij_typescript_use_path_mapping = always
319 | ij_typescript_use_public_modifier = false
320 | ij_typescript_use_semicolon_after_statement = false
321 | ij_typescript_var_declaration_wrap = normal
322 | ij_typescript_while_brace_force = never
323 | ij_typescript_while_on_new_line = false
324 | ij_typescript_wrap_comments = false
325 |
326 | [{*.bash,*.sh,*.zsh}]
327 | ij_shell_binary_ops_start_line = false
328 | ij_shell_keep_column_alignment_padding = false
329 | ij_shell_minify_program = false
330 | ij_shell_redirect_followed_by_space = false
331 | ij_shell_switch_cases_indented = false
332 | ij_shell_use_unix_line_separator = true
333 |
334 | [{*.cjs,*.js}]
335 | ij_continuation_indent_size = 4
336 | ij_javascript_align_imports = false
337 | ij_javascript_align_multiline_array_initializer_expression = false
338 | ij_javascript_align_multiline_binary_operation = false
339 | ij_javascript_align_multiline_chained_methods = false
340 | ij_javascript_align_multiline_extends_list = false
341 | ij_javascript_align_multiline_for = true
342 | ij_javascript_align_multiline_parameters = true
343 | ij_javascript_align_multiline_parameters_in_calls = false
344 | ij_javascript_align_multiline_ternary_operation = false
345 | ij_javascript_align_object_properties = 0
346 | ij_javascript_align_union_types = false
347 | ij_javascript_align_var_statements = 1
348 | ij_javascript_array_initializer_new_line_after_left_brace = true
349 | ij_javascript_array_initializer_right_brace_on_new_line = true
350 | ij_javascript_array_initializer_wrap = on_every_item
351 | ij_javascript_assignment_wrap = off
352 | ij_javascript_binary_operation_sign_on_next_line = false
353 | ij_javascript_binary_operation_wrap = off
354 | ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
355 | ij_javascript_blank_lines_after_imports = 1
356 | ij_javascript_blank_lines_around_class = 1
357 | ij_javascript_blank_lines_around_field = 0
358 | ij_javascript_blank_lines_around_function = 1
359 | ij_javascript_blank_lines_around_method = 1
360 | ij_javascript_block_brace_style = end_of_line
361 | ij_javascript_block_comment_add_space = false
362 | ij_javascript_block_comment_at_first_column = true
363 | ij_javascript_call_parameters_new_line_after_left_paren = false
364 | ij_javascript_call_parameters_right_paren_on_new_line = false
365 | ij_javascript_call_parameters_wrap = off
366 | ij_javascript_catch_on_new_line = false
367 | ij_javascript_chained_call_dot_on_new_line = true
368 | ij_javascript_class_brace_style = next_line
369 | ij_javascript_comma_on_new_line = false
370 | ij_javascript_do_while_brace_force = never
371 | ij_javascript_else_on_new_line = false
372 | ij_javascript_enforce_trailing_comma = remove
373 | ij_javascript_extends_keyword_wrap = off
374 | ij_javascript_extends_list_wrap = off
375 | ij_javascript_field_prefix = _
376 | ij_javascript_file_name_style = lisp_case
377 | ij_javascript_finally_on_new_line = false
378 | ij_javascript_for_brace_force = never
379 | ij_javascript_for_statement_new_line_after_left_paren = false
380 | ij_javascript_for_statement_right_paren_on_new_line = false
381 | ij_javascript_for_statement_wrap = off
382 | ij_javascript_force_quote_style = true
383 | ij_javascript_force_semicolon_style = true
384 | ij_javascript_function_expression_brace_style = end_of_line
385 | ij_javascript_if_brace_force = never
386 | ij_javascript_import_merge_members = global
387 | ij_javascript_import_prefer_absolute_path = true
388 | ij_javascript_import_sort_members = true
389 | ij_javascript_import_sort_module_name = false
390 | ij_javascript_import_use_node_resolution = true
391 | ij_javascript_imports_wrap = on_every_item
392 | ij_javascript_indent_case_from_switch = true
393 | ij_javascript_indent_chained_calls = true
394 | ij_javascript_indent_package_children = 0
395 | ij_javascript_jsx_attribute_value = braces
396 | ij_javascript_keep_blank_lines_in_code = 1
397 | ij_javascript_keep_first_column_comment = true
398 | ij_javascript_keep_indents_on_empty_lines = false
399 | ij_javascript_keep_line_breaks = true
400 | ij_javascript_keep_simple_blocks_in_one_line = false
401 | ij_javascript_keep_simple_methods_in_one_line = false
402 | ij_javascript_line_comment_add_space = false
403 | ij_javascript_line_comment_at_first_column = false
404 | ij_javascript_method_brace_style = end_of_line
405 | ij_javascript_method_call_chain_wrap = off
406 | ij_javascript_method_parameters_new_line_after_left_paren = false
407 | ij_javascript_method_parameters_right_paren_on_new_line = false
408 | ij_javascript_method_parameters_wrap = off
409 | ij_javascript_object_literal_wrap = on_every_item
410 | ij_javascript_parentheses_expression_new_line_after_left_paren = false
411 | ij_javascript_parentheses_expression_right_paren_on_new_line = false
412 | ij_javascript_place_assignment_sign_on_next_line = false
413 | ij_javascript_prefer_as_type_cast = false
414 | ij_javascript_prefer_explicit_types_function_expression_returns = false
415 | ij_javascript_prefer_explicit_types_function_returns = false
416 | ij_javascript_prefer_explicit_types_vars_fields = false
417 | ij_javascript_prefer_parameters_wrap = false
418 | ij_javascript_reformat_c_style_comments = false
419 | ij_javascript_space_after_colon = true
420 | ij_javascript_space_after_comma = true
421 | ij_javascript_space_after_dots_in_rest_parameter = false
422 | ij_javascript_space_after_generator_mult = true
423 | ij_javascript_space_after_property_colon = true
424 | ij_javascript_space_after_quest = true
425 | ij_javascript_space_after_type_colon = true
426 | ij_javascript_space_after_unary_not = true
427 | ij_javascript_space_before_async_arrow_lparen = true
428 | ij_javascript_space_before_catch_keyword = true
429 | ij_javascript_space_before_catch_left_brace = true
430 | ij_javascript_space_before_catch_parentheses = true
431 | ij_javascript_space_before_class_lbrace = true
432 | ij_javascript_space_before_class_left_brace = true
433 | ij_javascript_space_before_colon = true
434 | ij_javascript_space_before_comma = false
435 | ij_javascript_space_before_do_left_brace = true
436 | ij_javascript_space_before_else_keyword = true
437 | ij_javascript_space_before_else_left_brace = true
438 | ij_javascript_space_before_finally_keyword = true
439 | ij_javascript_space_before_finally_left_brace = true
440 | ij_javascript_space_before_for_left_brace = true
441 | ij_javascript_space_before_for_parentheses = true
442 | ij_javascript_space_before_for_semicolon = false
443 | ij_javascript_space_before_function_left_parenth = true
444 | ij_javascript_space_before_generator_mult = false
445 | ij_javascript_space_before_if_left_brace = true
446 | ij_javascript_space_before_if_parentheses = true
447 | ij_javascript_space_before_method_call_parentheses = false
448 | ij_javascript_space_before_method_left_brace = true
449 | ij_javascript_space_before_method_parentheses = false
450 | ij_javascript_space_before_property_colon = false
451 | ij_javascript_space_before_quest = true
452 | ij_javascript_space_before_switch_left_brace = true
453 | ij_javascript_space_before_switch_parentheses = true
454 | ij_javascript_space_before_try_left_brace = true
455 | ij_javascript_space_before_type_colon = false
456 | ij_javascript_space_before_unary_not = false
457 | ij_javascript_space_before_while_keyword = true
458 | ij_javascript_space_before_while_left_brace = true
459 | ij_javascript_space_before_while_parentheses = true
460 | ij_javascript_spaces_around_additive_operators = true
461 | ij_javascript_spaces_around_arrow_function_operator = true
462 | ij_javascript_spaces_around_assignment_operators = true
463 | ij_javascript_spaces_around_bitwise_operators = true
464 | ij_javascript_spaces_around_equality_operators = true
465 | ij_javascript_spaces_around_logical_operators = true
466 | ij_javascript_spaces_around_multiplicative_operators = true
467 | ij_javascript_spaces_around_relational_operators = true
468 | ij_javascript_spaces_around_shift_operators = true
469 | ij_javascript_spaces_around_unary_operator = false
470 | ij_javascript_spaces_within_array_initializer_brackets = false
471 | ij_javascript_spaces_within_brackets = false
472 | ij_javascript_spaces_within_catch_parentheses = false
473 | ij_javascript_spaces_within_for_parentheses = false
474 | ij_javascript_spaces_within_if_parentheses = false
475 | ij_javascript_spaces_within_imports = true
476 | ij_javascript_spaces_within_interpolation_expressions = true
477 | ij_javascript_spaces_within_method_call_parentheses = false
478 | ij_javascript_spaces_within_method_parentheses = false
479 | ij_javascript_spaces_within_object_literal_braces = true
480 | ij_javascript_spaces_within_object_type_braces = true
481 | ij_javascript_spaces_within_parentheses = false
482 | ij_javascript_spaces_within_switch_parentheses = false
483 | ij_javascript_spaces_within_type_assertion = false
484 | ij_javascript_spaces_within_union_types = true
485 | ij_javascript_spaces_within_while_parentheses = false
486 | ij_javascript_special_else_if_treatment = true
487 | ij_javascript_ternary_operation_signs_on_next_line = false
488 | ij_javascript_ternary_operation_wrap = off
489 | ij_javascript_union_types_wrap = on_every_item
490 | ij_javascript_use_chained_calls_group_indents = false
491 | ij_javascript_use_double_quotes = false
492 | ij_javascript_use_explicit_js_extension = auto
493 | ij_javascript_use_path_mapping = always
494 | ij_javascript_use_public_modifier = false
495 | ij_javascript_use_semicolon_after_statement = false
496 | ij_javascript_var_declaration_wrap = on_every_item
497 | ij_javascript_while_brace_force = never
498 | ij_javascript_while_on_new_line = false
499 | ij_javascript_wrap_comments = false
500 |
501 | [{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml}]
502 | ij_continuation_indent_size = 4
503 | ij_php_align_assignments = true
504 | ij_php_align_class_constants = false
505 | ij_php_align_group_field_declarations = false
506 | ij_php_align_inline_comments = true
507 | ij_php_align_key_value_pairs = true
508 | ij_php_align_match_arm_bodies = true
509 | ij_php_align_multiline_array_initializer_expression = true
510 | ij_php_align_multiline_binary_operation = false
511 | ij_php_align_multiline_chained_methods = false
512 | ij_php_align_multiline_extends_list = true
513 | ij_php_align_multiline_for = false
514 | ij_php_align_multiline_parameters = true
515 | ij_php_align_multiline_parameters_in_calls = false
516 | ij_php_align_multiline_ternary_operation = false
517 | ij_php_align_named_arguments = true
518 | ij_php_align_phpdoc_comments = false
519 | ij_php_align_phpdoc_param_names = false
520 | ij_php_anonymous_brace_style = next_line
521 | ij_php_api_weight = 28
522 | ij_php_array_initializer_new_line_after_left_brace = true
523 | ij_php_array_initializer_right_brace_on_new_line = true
524 | ij_php_array_initializer_wrap = on_every_item
525 | ij_php_assignment_wrap = on_every_item
526 | ij_php_attributes_wrap = split_into_lines
527 | ij_php_author_weight = 3
528 | ij_php_binary_operation_sign_on_next_line = true
529 | ij_php_binary_operation_wrap = on_every_item
530 | ij_php_blank_lines_after_class_header = 0
531 | ij_php_blank_lines_after_function = 1
532 | ij_php_blank_lines_after_imports = 1
533 | ij_php_blank_lines_after_opening_tag = 1
534 | ij_php_blank_lines_after_package = 1
535 | ij_php_blank_lines_around_class = 1
536 | ij_php_blank_lines_around_constants = 1
537 | ij_php_blank_lines_around_field = 1
538 | ij_php_blank_lines_around_method = 1
539 | ij_php_blank_lines_before_class_end = 0
540 | ij_php_blank_lines_before_imports = 1
541 | ij_php_blank_lines_before_method_body = 0
542 | ij_php_blank_lines_before_package = 1
543 | ij_php_blank_lines_before_return_statement = 1
544 | ij_php_blank_lines_between_imports = 1
545 | ij_php_block_brace_style = end_of_line
546 | ij_php_call_parameters_new_line_after_left_paren = false
547 | ij_php_call_parameters_right_paren_on_new_line = false
548 | ij_php_call_parameters_wrap = on_every_item
549 | ij_php_catch_on_new_line = true
550 | ij_php_category_weight = 28
551 | ij_php_class_brace_style = next_line
552 | ij_php_comma_after_last_argument = false
553 | ij_php_comma_after_last_array_element = true
554 | ij_php_comma_after_last_closure_use_var = false
555 | ij_php_comma_after_last_parameter = false
556 | ij_php_concat_spaces = true
557 | ij_php_copyright_weight = 4
558 | ij_php_deprecated_weight = 0
559 | ij_php_do_while_brace_force = always
560 | ij_php_else_if_style = combine
561 | ij_php_else_on_new_line = true
562 | ij_php_example_weight = 28
563 | ij_php_extends_keyword_wrap = normal
564 | ij_php_extends_list_wrap = off
565 | ij_php_fields_default_visibility = protected
566 | ij_php_filesource_weight = 28
567 | ij_php_finally_on_new_line = true
568 | ij_php_for_brace_force = always
569 | ij_php_for_statement_new_line_after_left_paren = false
570 | ij_php_for_statement_right_paren_on_new_line = false
571 | ij_php_for_statement_wrap = normal
572 | ij_php_force_empty_methods_in_one_line = false
573 | ij_php_force_short_declaration_array_style = true
574 | ij_php_getters_setters_naming_style = camel_case
575 | ij_php_getters_setters_order_style = getters_first
576 | ij_php_global_weight = 28
577 | ij_php_group_use_wrap = on_every_item
578 | ij_php_if_brace_force = always
579 | ij_php_if_lparen_on_next_line = true
580 | ij_php_if_rparen_on_next_line = true
581 | ij_php_ignore_weight = 28
582 | ij_php_import_sorting = alphabetic
583 | ij_php_indent_break_from_case = true
584 | ij_php_indent_case_from_switch = true
585 | ij_php_indent_code_in_php_tags = false
586 | ij_php_internal_weight = 1
587 | ij_php_keep_blank_lines_after_lbrace = 1
588 | ij_php_keep_blank_lines_before_right_brace = 0
589 | ij_php_keep_blank_lines_in_code = 1
590 | ij_php_keep_blank_lines_in_declarations = 0
591 | ij_php_keep_control_statement_in_one_line = true
592 | ij_php_keep_first_column_comment = false
593 | ij_php_keep_indents_on_empty_lines = false
594 | ij_php_keep_line_breaks = true
595 | ij_php_keep_rparen_and_lbrace_on_one_line = true
596 | ij_php_keep_simple_classes_in_one_line = true
597 | ij_php_keep_simple_methods_in_one_line = false
598 | ij_php_lambda_brace_style = end_of_line
599 | ij_php_license_weight = 5
600 | ij_php_line_comment_add_space = false
601 | ij_php_line_comment_at_first_column = false
602 | ij_php_link_weight = 7
603 | ij_php_lower_case_boolean_const = true
604 | ij_php_lower_case_keywords = true
605 | ij_php_lower_case_null_const = true
606 | ij_php_method_brace_style = next_line
607 | ij_php_method_call_chain_wrap = on_every_item
608 | ij_php_method_parameters_new_line_after_left_paren = true
609 | ij_php_method_parameters_right_paren_on_new_line = true
610 | ij_php_method_parameters_wrap = on_every_item
611 | ij_php_method_weight = 13
612 | ij_php_modifier_list_wrap = false
613 | ij_php_multiline_chained_calls_semicolon_on_new_line = false
614 | ij_php_namespace_brace_style = 2
615 | ij_php_new_line_after_php_opening_tag = true
616 | ij_php_null_type_position = in_the_end
617 | ij_php_package_weight = 28
618 | ij_php_param_weight = 9
619 | ij_php_parameters_attributes_wrap = split_into_lines
620 | ij_php_parentheses_expression_new_line_after_left_paren = false
621 | ij_php_parentheses_expression_right_paren_on_new_line = false
622 | ij_php_phpdoc_blank_line_before_tags = true
623 | ij_php_phpdoc_blank_lines_around_parameters = true
624 | ij_php_phpdoc_keep_blank_lines = true
625 | ij_php_phpdoc_param_spaces_between_name_and_description = 1
626 | ij_php_phpdoc_param_spaces_between_tag_and_type = 1
627 | ij_php_phpdoc_param_spaces_between_type_and_name = 1
628 | ij_php_phpdoc_use_fqcn = true
629 | ij_php_phpdoc_wrap_long_lines = true
630 | ij_php_place_assignment_sign_on_next_line = false
631 | ij_php_place_parens_for_constructor = 0
632 | ij_php_property_read_weight = 11
633 | ij_php_property_weight = 10
634 | ij_php_property_write_weight = 12
635 | ij_php_return_type_on_new_line = false
636 | ij_php_return_weight = 15
637 | ij_php_see_weight = 6
638 | ij_php_since_weight = 2
639 | ij_php_sort_phpdoc_elements = true
640 | ij_php_space_after_colon = true
641 | ij_php_space_after_colon_in_enum_backed_type = true
642 | ij_php_space_after_colon_in_named_argument = true
643 | ij_php_space_after_colon_in_return_type = true
644 | ij_php_space_after_comma = true
645 | ij_php_space_after_for_semicolon = true
646 | ij_php_space_after_quest = true
647 | ij_php_space_after_type_cast = true
648 | ij_php_space_after_unary_not = true
649 | ij_php_space_before_array_initializer_left_brace = true
650 | ij_php_space_before_catch_keyword = true
651 | ij_php_space_before_catch_left_brace = true
652 | ij_php_space_before_catch_parentheses = true
653 | ij_php_space_before_class_left_brace = true
654 | ij_php_space_before_closure_left_parenthesis = true
655 | ij_php_space_before_colon = true
656 | ij_php_space_before_colon_in_enum_backed_type = false
657 | ij_php_space_before_colon_in_named_argument = false
658 | ij_php_space_before_colon_in_return_type = false
659 | ij_php_space_before_comma = false
660 | ij_php_space_before_do_left_brace = true
661 | ij_php_space_before_else_keyword = true
662 | ij_php_space_before_else_left_brace = true
663 | ij_php_space_before_finally_keyword = true
664 | ij_php_space_before_finally_left_brace = true
665 | ij_php_space_before_for_left_brace = true
666 | ij_php_space_before_for_parentheses = true
667 | ij_php_space_before_for_semicolon = false
668 | ij_php_space_before_if_left_brace = true
669 | ij_php_space_before_if_parentheses = true
670 | ij_php_space_before_method_call_parentheses = false
671 | ij_php_space_before_method_left_brace = true
672 | ij_php_space_before_method_parentheses = false
673 | ij_php_space_before_quest = true
674 | ij_php_space_before_short_closure_left_parenthesis = true
675 | ij_php_space_before_switch_left_brace = true
676 | ij_php_space_before_switch_parentheses = true
677 | ij_php_space_before_try_left_brace = true
678 | ij_php_space_before_unary_not = false
679 | ij_php_space_before_while_keyword = true
680 | ij_php_space_before_while_left_brace = true
681 | ij_php_space_before_while_parentheses = true
682 | ij_php_space_between_ternary_quest_and_colon = false
683 | ij_php_spaces_around_additive_operators = true
684 | ij_php_spaces_around_arrow = false
685 | ij_php_spaces_around_assignment_in_declare = false
686 | ij_php_spaces_around_assignment_operators = true
687 | ij_php_spaces_around_bitwise_operators = true
688 | ij_php_spaces_around_equality_operators = true
689 | ij_php_spaces_around_logical_operators = true
690 | ij_php_spaces_around_multiplicative_operators = true
691 | ij_php_spaces_around_null_coalesce_operator = true
692 | ij_php_spaces_around_pipe_in_union_type = false
693 | ij_php_spaces_around_relational_operators = true
694 | ij_php_spaces_around_shift_operators = true
695 | ij_php_spaces_around_unary_operator = false
696 | ij_php_spaces_around_var_within_brackets = false
697 | ij_php_spaces_within_array_initializer_braces = false
698 | ij_php_spaces_within_brackets = false
699 | ij_php_spaces_within_catch_parentheses = false
700 | ij_php_spaces_within_for_parentheses = false
701 | ij_php_spaces_within_if_parentheses = false
702 | ij_php_spaces_within_method_call_parentheses = false
703 | ij_php_spaces_within_method_parentheses = false
704 | ij_php_spaces_within_parentheses = false
705 | ij_php_spaces_within_short_echo_tags = true
706 | ij_php_spaces_within_switch_parentheses = false
707 | ij_php_spaces_within_while_parentheses = false
708 | ij_php_special_else_if_treatment = false
709 | ij_php_subpackage_weight = 28
710 | ij_php_ternary_operation_signs_on_next_line = true
711 | ij_php_ternary_operation_wrap = on_every_item
712 | ij_php_throws_weight = 14
713 | ij_php_todo_weight = 28
714 | ij_php_treat_multiline_arrays_and_lambdas_multiline = false
715 | ij_php_unknown_tag_weight = 28
716 | ij_php_upper_case_boolean_const = false
717 | ij_php_upper_case_null_const = false
718 | ij_php_uses_weight = 28
719 | ij_php_var_weight = 28
720 | ij_php_variable_naming_style = snake_case
721 | ij_php_version_weight = 8
722 | ij_php_while_brace_force = always
723 | ij_php_while_on_new_line = true
724 |
725 | [{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
726 | ij_continuation_indent_size = 4
727 | ij_json_array_wrapping = on_every_item
728 | ij_json_keep_blank_lines_in_code = 1
729 | ij_json_keep_indents_on_empty_lines = false
730 | ij_json_keep_line_breaks = true
731 | ij_json_keep_trailing_comma = false
732 | ij_json_object_wrapping = on_every_item
733 | ij_json_property_alignment = do_not_align
734 | ij_json_space_after_colon = true
735 | ij_json_space_after_comma = true
736 | ij_json_space_before_colon = false
737 | ij_json_space_before_comma = false
738 | ij_json_spaces_within_braces = true
739 | ij_json_spaces_within_brackets = false
740 | ij_json_wrap_long_lines = false
741 |
742 | [{*.htm,*.html,*.sht,*.shtm,*.shtml}]
743 | ij_continuation_indent_size = 4
744 | ij_visual_guides = 160
745 | ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
746 | ij_html_align_attributes = false
747 | ij_html_align_text = false
748 | ij_html_attribute_wrap = on_every_item
749 | ij_html_block_comment_add_space = false
750 | ij_html_block_comment_at_first_column = true
751 | ij_html_do_not_align_children_of_min_lines = 0
752 | ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
753 | ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
754 | ij_html_enforce_quotes = true
755 | 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
756 | ij_html_keep_blank_lines = 2
757 | ij_html_keep_indents_on_empty_lines = false
758 | ij_html_keep_line_breaks = true
759 | ij_html_keep_line_breaks_in_text = true
760 | ij_html_keep_whitespaces = false
761 | ij_html_keep_whitespaces_inside = span,pre,textarea
762 | ij_html_line_comment_at_first_column = true
763 | ij_html_new_line_after_last_attribute = never
764 | ij_html_new_line_before_first_attribute = when_multiline
765 | ij_html_quote_style = double
766 | ij_html_remove_new_line_before_tags = br
767 | ij_html_space_after_tag_name = false
768 | ij_html_space_around_equality_in_attribute = false
769 | ij_html_space_inside_empty_tag = true
770 | ij_html_text_wrap = off
771 |
772 | [{*.markdown,*.md}]
773 | ij_markdown_force_one_space_after_blockquote_symbol = true
774 | ij_markdown_force_one_space_after_header_symbol = true
775 | ij_markdown_force_one_space_after_list_bullet = true
776 | ij_markdown_force_one_space_between_words = true
777 | ij_markdown_insert_quote_arrows_on_wrap = true
778 | ij_markdown_keep_indents_on_empty_lines = false
779 | ij_markdown_keep_line_breaks_inside_text_blocks = true
780 | ij_markdown_max_lines_around_block_elements = 1
781 | ij_markdown_max_lines_around_header = 1
782 | ij_markdown_max_lines_between_paragraphs = 1
783 | ij_markdown_min_lines_around_block_elements = 1
784 | ij_markdown_min_lines_around_header = 2
785 | ij_markdown_min_lines_between_paragraphs = 1
786 | ij_markdown_wrap_text_if_long = true
787 | ij_markdown_wrap_text_inside_blockquotes = true
788 |
789 | [{*.yaml,*.yml}]
790 | ij_yaml_align_values_properties = do_not_align
791 | ij_yaml_autoinsert_sequence_marker = true
792 | ij_yaml_block_mapping_on_new_line = false
793 | ij_yaml_indent_sequence_value = true
794 | ij_yaml_keep_indents_on_empty_lines = false
795 | ij_yaml_keep_line_breaks = true
796 | ij_yaml_sequence_on_new_line = true
797 | ij_yaml_space_before_colon = false
798 | ij_yaml_spaces_within_braces = true
799 | ij_yaml_spaces_within_brackets = true
800 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: TheDragonCode
2 | open_collective: dragon-code
3 | custom: [ "https://boosty.to/dragon-code", "https://yoomoney.ru/to/410012608840929" ]
4 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | -
4 | package-ecosystem: github-actions
5 | directory: /
6 | schedule:
7 | interval: daily
8 |
--------------------------------------------------------------------------------
/.github/workflows/lint-check.yml:
--------------------------------------------------------------------------------
1 | name: "Code-Style Check"
2 |
3 | on: [ push, pull_request ]
4 |
5 | jobs:
6 | check:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Checkout code
11 | uses: actions/checkout@v3
12 |
13 | - name: Checking PHP Syntax
14 | uses: TheDragonCode/codestyler@v2.6.2
15 |
--------------------------------------------------------------------------------
/.github/workflows/lint-fixer.yml:
--------------------------------------------------------------------------------
1 | name: "Code-Style Fixer"
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 |
7 | jobs:
8 | fix:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@v3
14 |
15 | - name: Checking PHP Syntax
16 | uses: TheDragonCode/codestyler@v2.6.2
17 | with:
18 | github_token: ${{ secrets.COMPOSER_TOKEN }}
19 | fix: true
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Andrey Helldar
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Notifex
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | > You can use both [official plugins](https://laravel.com/docs/10.x/notifications) from the Laravel team and [plugins](https://laravel-notification-channels.com/) from the [community](https://laravel-notification-channels.com/).
13 | >
14 | > Of course, you can also create your own.
15 |
16 |
17 | ## Installation
18 |
19 | To get the latest version of `Notifex`, simply require the project using [Composer](https://getcomposer.org):
20 |
21 | ```
22 | composer require dragon-code/notify-exceptions
23 | ```
24 |
25 | Instead, you may of course manually update your `require` block and run `composer update`:
26 |
27 | ```json
28 | {
29 | "require": {
30 | "dragon-code/notify-exceptions": "^4.0"
31 | }
32 | }
33 | ```
34 |
35 | You can also publish the config file to change implementations (ie. interface to specific class):
36 |
37 | ```
38 | php artisan vendor:publish --provider="DragonCode\Notifex\ServiceProvider"
39 | ```
40 |
41 | And call `php artisan migrate` command from console.
42 |
43 | Now you can use the `app('notifex')` method.
44 |
45 | ### Upgrade from `andrey-helldar/notify-exceptions`
46 |
47 | 1. Replace `"andrey-helldar/notify-exceptions": "^3.0"` with `"dragon-code/notify-exceptions": "^4.0"` in the `composer.json` file;
48 | 3. Replace `Helldar\Notifex` namespace prefix with `DragonCode\Notifex`;
49 | 4. Call the `composer update` console command.
50 |
51 | ## Configuration
52 |
53 | ### Ingore bots
54 |
55 | By default, the package does not respond to errors created in the process of search bots.
56 |
57 | To enable error messages from bots, change the setting `ignore_bots` in [config/notifex.php](config/notifex.php) file.
58 |
59 | By default, false.
60 |
61 |
62 | ### Email
63 |
64 | See [configuration](config/notifex.php) file.
65 |
66 | Example email message:
67 |
68 | 
69 |
70 |
71 | ### Jira
72 |
73 | If you need to create issues in the Jira, then you need to install the package [lesstif/php-jira-rest-client](https://github.com/lesstif/php-jira-rest-client):
74 |
75 | ```bash
76 | composer require lesstif/php-jira-rest-client
77 | ```
78 |
79 | 
80 |
81 |
82 | ### Slack
83 |
84 | If you need to send messages in the Slack channel, then you need to install the
85 | package [laravel/slack-notification-channel](https://packagist.org/packages/laravel/slack-notification-channel):
86 |
87 | ```bash
88 | composer require laravel/slack-notification-channel
89 | ```
90 |
91 | ### Your notification services
92 |
93 | You can easily connect your notification services. To do this, in block `jobs` of file `config/notifex.php`, add a call to its job:
94 |
95 | ```php
96 | \DragonCode\Notifex\Jobs\ExampleJob::class
97 | ```
98 |
99 | If you need to pass any parameters to your job, you can use an associative entry, where the key is the link to the job class, and the values are the parameters:
100 |
101 | ```php
102 | \DragonCode\Notifex\Jobs\ExampleJob::class => [
103 | 'host' => env('EXAMPLE_HOST'), // http://127.0.0.1:8080
104 | 'user' => env('EXAMPLE_USER'), // 'foo'
105 | 'password' => env('EXAMPLE_PASS'), // 'bar'
106 | 'other_key' => env('EXAMPLE_OTHER_KEY'), // 12345
107 | ],
108 | ```
109 |
110 | Your job should inherit from the abstract class `DragonCode\Notifex\Abstracts\JobAbstract`. This will help to correctly create a class for work.
111 |
112 | To get the values of the settings you need to use the method `getConfig($class, $key)`:
113 |
114 | ```php
115 | $host = $this->getConfig(get_class(), 'host');
116 | $user = $this->getConfig(get_class(), 'user');
117 | $password = $this->getConfig(get_class(), 'password');
118 | $other_key = $this->getConfig(get_class(), 'other_key');
119 |
120 | // or add `config(string $key)` method:
121 |
122 | private function config(string $key)
123 | {
124 | return $this->getConfig(get_class(), $key);
125 | }
126 |
127 | $host = $this->config('host');
128 | $user = $this->config('user');
129 | $password = $this->config('password');
130 | $other_key = $this->config('other_key');
131 | ```
132 |
133 | Examples of completed classes can be found here:
134 |
135 | * [ExampleJob](src/Jobs/ExampleJob.php)
136 | * [JiraJob](src/Jobs/JiraJob.php)
137 |
138 | It is worth noting that standard jobs of Laravel are used for the call:
139 |
140 | ```bash
141 | php artisan make:job
142 | ```
143 |
144 | They should remove the call interface `ShouldQueue` and extend the class:
145 |
146 | ```php
147 | // before
148 | use Illuminate\Contracts\Queue\ShouldQueue;
149 |
150 | class ExampleJob implements ShouldQueue {}
151 |
152 | // after
153 | use DragonCode\Notifex\Abstracts\JobAbstract;
154 |
155 | class ExampleJob extends JobAbstract {}
156 | ```
157 |
158 | As the abstract class includes a call of all necessary classes and interfaces.
159 |
160 | It's all! Enjoy 😊
161 |
162 |
163 | ## Using
164 |
165 | Add exception capturing to `app/Exceptions/Handler.php`:
166 |
167 | ```php
168 | public function report(Throwable $exception)
169 | {
170 | parent::report($exception);
171 |
172 | if (app()->bound('notifex') && $this->shouldReport($exception)) {
173 | app('notifex')->send($exception);
174 | }
175 | }
176 | ```
177 |
178 | or just use in your code:
179 |
180 | ```php
181 | try {
182 | $foo = $bar
183 | } catch(\Exception $exception) {
184 | app('notifex')->send($exception);
185 | }
186 | ```
187 |
188 | #### **IMPORTANT!**
189 |
190 | To realize the possibility of saving an object to a database table, this object is processed before serialization. Due to the peculiarities of linking objects in PHP, serialization
191 | does not support the `Throwable` interface, and therefore, if you call method `app('notifex')->send($exception)` before processing a variable, the application may cause an
192 | error `Expected array for frame 0`.
193 |
194 | To avoid this, use method `parent::report($exception)` strictly **before** sending notifications.
195 |
196 |
197 | ## Test message
198 |
199 | To verivy that Notifex is configured correctly and our integration is working, use `notifex:test` command:
200 |
201 | ```
202 | php artisan notifex:test
203 | ```
204 |
205 | A `DragonCode\Notifex\Exceptions\NotifexTestException` class will be thrown and captured by Notifex. The captured exception will appear in your configured email immediately.
206 |
207 |
208 | ## Support
209 |
210 | The package out of the box supports sending notifications to the following services:
211 |
212 | * **Email** _(default, enabled)_
213 | * **Slack** _(default, disabled)_
214 | * **Jira** _(default, disabled)_
215 |
216 | ## License
217 |
218 | This package is licensed under the [MIT License](LICENSE).
219 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dragon-code/notify-exceptions",
3 | "description": "Notify the site administrator of any errors through various channels of communication.",
4 | "license": "MIT",
5 | "type": "library",
6 | "keywords": [
7 | "notify exceptions",
8 | "notifex",
9 | "laravel",
10 | "exceptions",
11 | "slack",
12 | "email",
13 | "jira"
14 | ],
15 | "authors": [
16 | {
17 | "name": "Andrey Helldar",
18 | "email": "helldar@dragon-code.pro",
19 | "homepage": "https://github.com/andrey-helldar"
20 | }
21 | ],
22 | "support": {
23 | "issues": "https://github.com/andrey-helldar/notify-exceptions/issues",
24 | "source": "https://github.com/andrey-helldar/notify-exceptions"
25 | },
26 | "funding": [
27 | {
28 | "type": "github",
29 | "url": "https://github.com/sponsors/TheDragonCode"
30 | },
31 | {
32 | "type": "open_collective",
33 | "url": "https://opencollective.com/dragon-code"
34 | },
35 | {
36 | "type": "boosty",
37 | "url": "https://boosty.to/dragon-code"
38 | },
39 | {
40 | "type": "yoomoney",
41 | "url": "https://yoomoney.ru/to/410012608840929"
42 | }
43 | ],
44 | "require": {
45 | "php": "^7.2.5 || ^8.0",
46 | "guzzlehttp/guzzle": "^7.0",
47 | "illuminate/bus": "^7.0 || ^8.0 || ^9.0",
48 | "illuminate/console": "^7.0 || ^8.0 || ^9.0",
49 | "illuminate/contracts": "^7.0 || ^8.0 || ^9.0",
50 | "illuminate/notifications": "^7.0 || ^8.0 || ^9.0",
51 | "illuminate/queue": "^7.0 || ^8.0 || ^9.0",
52 | "illuminate/support": "^7.0 || ^8.0 || ^9.0",
53 | "illuminate/view": "^7.0 || ^8.0 || ^9.0",
54 | "jaybizzle/crawler-detect": "^1.2",
55 | "symfony/debug": "^4.0",
56 | "symfony/http-kernel": "^4.0 || ^5.0 || ^6.0"
57 | },
58 | "require-dev": {
59 | "laravel/slack-notification-channel": "^2.0",
60 | "lesstif/php-jira-rest-client": "^2.1"
61 | },
62 | "conflict": {
63 | "andrey-helldar/notify-exceptions": "*"
64 | },
65 | "suggest": {
66 | "laravel/slack-notification-channel": "Slack Notification Channel for Laravel",
67 | "lesstif/php-jira-rest-client": "PHP classes interact Jira with the REST API.",
68 | "symfony/thanks": "Give thanks (in the form of a GitHub) to your fellow PHP package maintainers"
69 | },
70 | "minimum-stability": "stable",
71 | "prefer-stable": true,
72 | "autoload": {
73 | "psr-4": {
74 | "DragonCode\\Notifex\\": "src"
75 | }
76 | },
77 | "config": {
78 | "allow-plugins": {
79 | "dragon-code/codestyler": true,
80 | "ergebnis/composer-normalize": true,
81 | "friendsofphp/php-cs-fixer": true
82 | },
83 | "preferred-install": "dist",
84 | "sort-packages": true
85 | },
86 | "extra": {
87 | "laravel": {
88 | "providers": [
89 | "DragonCode\\Notifex\\ServiceProvider"
90 | ]
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/config/notifex.php:
--------------------------------------------------------------------------------
1 | env('NOTIFEX_ENABLED', true),
7 |
8 | // Specifies the name of the queue into which to write an error event for dispatch.
9 |
10 | 'queue' => env('NOTIFEX_QUEUE', 'default'),
11 |
12 | // Determines whether to ignore messages from bots.
13 |
14 | 'ignore_bots' => true,
15 | // Determination of settings and status of sending to email.
16 |
17 | 'email' => [
18 | // Determines if sending to email is allowed.
19 |
20 | 'enabled' => env('NOTIFEX_EMAIL_ENABLED', true),
21 |
22 | // Sets the sender's address.
23 |
24 | 'from' => env('NOTIFEX_EMAIL_FROM', 'example@example.com'),
25 |
26 | // Sets the recipient's address.
27 |
28 | 'to' => env('NOTIFEX_EMAIL_TO', 'example@example.com'),
29 | ],
30 |
31 | 'slack' => [
32 | // Determines if sending to slack channel is allowed.
33 |
34 | 'enabled' => env('NOTIFEX_SLACK_ENABLED', false),
35 |
36 | // Sets the webhook address for sending a message.
37 |
38 | 'webhook' => env('NOTIFEX_SLACK_WEBHOOK'),
39 |
40 | /*
41 | * If specified, the name will be used, otherwise by default.
42 | *
43 | * Available:
44 | * ['Ghost', ':ghost:']
45 | * ['Ghost']
46 | * null
47 | *
48 | * By default, null
49 | */
50 |
51 | 'from' => null,
52 |
53 | /*
54 | * If specified, notifications will be sent to the channel.
55 | *
56 | * By default, null.
57 | */
58 |
59 | 'to' => null,
60 | ],
61 |
62 | 'jobs' => [
63 | // \DragonCode\Notifex\Jobs\JiraJob::class => [
64 | // 'enabled' => env('NOTIFEX_JIRA_ENABLED', false),
65 | //
66 | // 'host' => env('NOTIFEX_JIRA_HOST'),
67 | // 'user' => env('NOTIFEX_JIRA_USER'),
68 | // 'password' => env('NOTIFEX_JIRA_PASSWORD'),
69 | //
70 | // 'project_key' => env('NOTIFEX_JIRA_PROJECT_KEY'),
71 | // 'issue_type' => env('NOTIFEX_JIRA_ISSUE_TYPE', 'Bug'),
72 | // 'priority_name' => env('NOTIFEX_JIRA_PRIORITY_NAME', 'Critical'),
73 | //],
74 | //
75 | // @see \DragonCode\Notifex\Jobs\ExampleJob
76 | // \DragonCode\Notifex\Jobs\ExampleJob::class => [
77 | // 'host' => env('EXAMPLE_HOST'), // http://127.0.0.1:8080
78 | // 'user' => env('EXAMPLE_USER'), // 'foo'
79 | // 'password' => env('EXAMPLE_PASS'), // 'bar'
80 | // 'other_key' => env('EXAMPLE_OTHER_KEY'), // 12345
81 | //],
82 | ],
83 | ];
84 |
--------------------------------------------------------------------------------
/migrations/2018_07_11_140701_create_error_notifications_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('id');
13 |
14 | $table->string('parent');
15 | $table->longText('exception');
16 |
17 | $table->timestamps();
18 | });
19 | }
20 |
21 | public function down()
22 | {
23 | Schema::dropIfExists('error_notifications');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/migrations/2019_03_12_140701_delete_error_notifications_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('id');
18 |
19 | $table->string('parent');
20 | $table->longText('exception');
21 |
22 | $table->timestamps();
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/views/body.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
54 |
55 |
56 |
57 | {!! $content !!}
58 |
59 |
79 |
80 |
90 |
91 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/resources/views/raw.blade.php:
--------------------------------------------------------------------------------
1 | {!! $content !!}
2 |
--------------------------------------------------------------------------------
/resources/views/subject.blade.php:
--------------------------------------------------------------------------------
1 | [notifex] | {{ $environment }} | {{ $host }} | {{ class_basename($exception) }}
2 |
--------------------------------------------------------------------------------
/src/Abstracts/JobAbstract.php:
--------------------------------------------------------------------------------
1 | classname = $classname;
38 | $this->message = $message;
39 | $this->file = $file;
40 | $this->line = $line;
41 | $this->trace_as_string = $trace_as_string;
42 | }
43 |
44 | protected function getConfig(string $class, string $key)
45 | {
46 | return Config::get(sprintf('notifex.jobs.%s.%s', $class, $key));
47 | }
48 |
49 | protected function environment(): string
50 | {
51 | return App::environment();
52 | }
53 |
54 | protected function classname(): string
55 | {
56 | return class_basename($this->classname);
57 | }
58 |
59 | protected function host(): string
60 | {
61 | return Http::host();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Console/TestException.php:
--------------------------------------------------------------------------------
1 | send(
19 | $this->getException()
20 | );
21 |
22 | $this->info('Notifex is working fine ✅');
23 | }
24 | catch (NotifexTestException $e) {
25 | $this->consoleApp()->renderThrowable($e, $this->output);
26 | }
27 | }
28 |
29 | protected function getException(): NotifexTestException
30 | {
31 | return new NotifexTestException();
32 | }
33 |
34 | protected function consoleApp(): ConsoleApplication
35 | {
36 | return new ConsoleApplication();
37 | }
38 |
39 | protected function send(NotifexTestException $e): void
40 | {
41 | app('notifex')->send($e);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Exceptions/NotifexTestException.php:
--------------------------------------------------------------------------------
1 | config('host');
12 | $user = $this->config('user');
13 | $password = $this->config('password');
14 | $other_key = $this->config('other_key');
15 |
16 | // Your actions.
17 | //
18 | // $classname = $this->classname;
19 | // $class_basename = class_basename($this->classname);
20 | // $message = $this->message;
21 | // $file = $this->file;
22 | // $line = $this->line;
23 | // $trace_as_string = $this->trace_as_string;
24 | }
25 |
26 | protected function config(string $key)
27 | {
28 | return $this->getConfig(
29 | $this->getClass(),
30 | $key
31 | );
32 | }
33 |
34 | protected function getClass(): string
35 | {
36 | return get_class();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Jobs/JiraJob.php:
--------------------------------------------------------------------------------
1 | getIssueField();
21 | $service = $this->getIssueService();
22 |
23 | $field
24 | ->setProjectKey($this->config('project_key'))
25 | ->setIssueType($this->config('issue_type'))
26 | ->setPriorityName($this->config('priority_name'))
27 | ->setSummary($this->title())
28 | ->setDescription($this->description())
29 | ->addLabel($this->host())
30 | ->addLabel($this->environment())
31 | ->addLabel($this->classname());
32 |
33 | $service->create($field);
34 | }
35 |
36 | protected function title(): string
37 | {
38 | return sprintf('%s | %s | %s', $this->environment(), $this->host(), $this->classname());
39 | }
40 |
41 | protected function description(): string
42 | {
43 | return implode(PHP_EOL, [
44 | sprintf('*%s*', $this->message),
45 | sprintf('_%s:%s_', $this->file, $this->line),
46 | sprintf('{code:bash}%s{code}', $this->trace_as_string),
47 | ]);
48 | }
49 |
50 | protected function getJiraConfiguration(): ArrayConfiguration
51 | {
52 | return new ArrayConfiguration([
53 | 'jiraHost' => $this->config('host'),
54 | 'jiraUser' => $this->config('user'),
55 | 'jiraPassword' => $this->config('password'),
56 | ]);
57 | }
58 |
59 | protected function config(string $key)
60 | {
61 | return $this->getConfig(get_class(), $key);
62 | }
63 |
64 | protected function getIssueField(): IssueField
65 | {
66 | return new IssueField();
67 | }
68 |
69 | /**
70 | * @throws \JiraRestApi\JiraException
71 | *
72 | * @return \JiraRestApi\Issue\IssueService
73 | */
74 | protected function getIssueService(): IssueService
75 | {
76 | return new IssueService(
77 | $this->getJiraConfiguration()
78 | );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Jobs/SlackJob.php:
--------------------------------------------------------------------------------
1 | notify(
13 | $this->getSlackNotify()
14 | );
15 | }
16 |
17 | /**
18 | * Route notifications for the Slack channel.
19 | *
20 | * @param \Illuminate\Notifications\Notification $notification
21 | *
22 | * @return string
23 | */
24 | public function routeNotificationForSlack($notification): ?string
25 | {
26 | return $this->getConfig(get_class(), 'webhook');
27 | }
28 |
29 | protected function title(): string
30 | {
31 | return implode(PHP_EOL, [
32 | sprintf('*%s | %s | %s*', $this->environment(), $this->host(), $this->classname()),
33 | sprintf('`%s:%s`', $this->file, $this->line),
34 | ]);
35 | }
36 |
37 | protected function getSlackNotify(): SlackNotify
38 | {
39 | return new SlackNotify($this->title(), $this->message, $this->trace_as_string);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Mail/ExceptionEmail.php:
--------------------------------------------------------------------------------
1 | subject = $subject;
21 | $this->content = $content;
22 | $this->queue = $this->getQueueName();
23 | }
24 |
25 | public function build()
26 | {
27 | $this->setMailTo();
28 | $this->setMailFrom();
29 |
30 | return $this->view('notifex::raw')
31 | ->with('content', $this->content);
32 | }
33 |
34 | protected function setMailTo(): void
35 | {
36 | $this->to(
37 | Config::get('notifex.email.to')
38 | );
39 | }
40 |
41 | protected function setMailFrom(): void
42 | {
43 | $this->from(
44 | Config::get('notifex.email.from')
45 | );
46 | }
47 |
48 | protected function getQueueName(): string
49 | {
50 | return Config::get('notifex.queue', 'default');
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Notifications/SlackNotify.php:
--------------------------------------------------------------------------------
1 | title = $title;
24 | $this->message = $message;
25 | $this->trace_as_string = $trace_as_string;
26 | }
27 |
28 | /**
29 | * Get the notification's delivery channels.
30 | *
31 | * @param mixed $notifiable
32 | *
33 | * @return array
34 | */
35 | public function via($notifiable)
36 | {
37 | return ['slack'];
38 | }
39 |
40 | /**
41 | * Get the Slack representation of the notification.
42 | *
43 | * @param $notifiable
44 | *
45 | * @return \Illuminate\Notifications\Messages\SlackMessage
46 | */
47 | public function toSlack($notifiable)
48 | {
49 | return $this->prepareMessage($this->message())
50 | ->error()
51 | ->content($this->title)
52 | ->attachment(function (SlackAttachment $attachment) {
53 | $attachment
54 | ->title($this->message)
55 | ->content($this->trace_as_string)
56 | ->footer($this->appName())
57 | ->timestamp($this->currentTime());
58 | });
59 | }
60 |
61 | protected function message(): SlackMessage
62 | {
63 | return new SlackMessage();
64 | }
65 |
66 | protected function prepareMessage(SlackMessage $message): SlackMessage
67 | {
68 | $this->from($message);
69 | $this->to($message);
70 |
71 | return $message;
72 | }
73 |
74 | protected function appName(): string
75 | {
76 | return App::name();
77 | }
78 |
79 | protected function from(SlackMessage $message)
80 | {
81 | if ($from = Config::get('notifex.slack.from')) {
82 | if (count($from) === 2) {
83 | [$username, $icon] = $from;
84 | }
85 | elseif (count($from) === 1) {
86 | [$username] = $from;
87 | }
88 |
89 | if ($username ?? false) {
90 | $message->from($username, $icon ?? null);
91 | }
92 | }
93 | }
94 |
95 | protected function to(SlackMessage $message)
96 | {
97 | if ($to = Config::get('notifex.slack.to')) {
98 | $channel = ltrim($to, '#');
99 |
100 | $message->to('#' . $channel);
101 | }
102 | }
103 |
104 | protected function currentTime(): DateTimeInterface
105 | {
106 | return Carbon::now();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/ServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadViewsFrom(self::VIEWS_PATH, 'notifex');
21 |
22 | if ($this->app->runningInConsole()) {
23 | $this->publishes([
24 | self::CONFIG_PATH => $this->app->configPath('notifex.php'),
25 | ], 'config');
26 |
27 | $this->publishes([
28 | self::VIEWS_PATH => $this->app->resourcePath('views/vendor/notifex'),
29 | ], 'notifex-views');
30 |
31 | $this->loadMigrationsFrom(__DIR__ . '/../migrations');
32 |
33 | $this->commands([
34 | TestException::class,
35 | ]);
36 | }
37 | }
38 |
39 | /**
40 | * Register bindings in the container.
41 | */
42 | public function register()
43 | {
44 | $this->mergeConfigFrom(self::CONFIG_PATH, 'notifex');
45 |
46 | $this->app->singleton('notifex', NotifyException::class);
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | *
52 | * @return array
53 | */
54 | public function provides()
55 | {
56 | return ['notifex'];
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Services/Email.php:
--------------------------------------------------------------------------------
1 | handler = $handler;
18 | $this->exception = $exception;
19 |
20 | $this->send(
21 | $this->getException()
22 | );
23 | }
24 |
25 | protected function subject(): string
26 | {
27 | return $this->handler->convertExceptionToString($this->exception);
28 | }
29 |
30 | protected function content(): string
31 | {
32 | return $this->handler->convertExceptionToHtml($this->exception);
33 | }
34 |
35 | protected function getException(): ExceptionEmail
36 | {
37 | return new ExceptionEmail($this->subject(), $this->content());
38 | }
39 |
40 | protected function send(ExceptionEmail $e): void
41 | {
42 | Mail::send($e);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Services/ExceptionHandler.php:
--------------------------------------------------------------------------------
1 | view = $view;
30 | }
31 |
32 | /**
33 | * Create a string for the given exception.
34 | *
35 | * @param Throwable $exception
36 | *
37 | * @return string
38 | */
39 | public function convertExceptionToString(Throwable $exception)
40 | {
41 | $environment = $this->environment();
42 | $host = $this->host();
43 |
44 | return $this->view
45 | ->make('notifex::subject', compact('exception', 'environment', 'host'))
46 | ->render();
47 | }
48 |
49 | /**
50 | * Create a html for the given exception.
51 | *
52 | * @param Throwable $exception
53 | *
54 | * @return string
55 | */
56 | public function convertExceptionToHtml(Throwable $exception)
57 | {
58 | $flat = $this->getFlattenedException($exception);
59 | $handler = new SymfonyExceptionHandler();
60 |
61 | return $this->decorate($handler->getContent($flat), $handler->getStylesheet($flat), $flat);
62 | }
63 |
64 | /**
65 | * Converts the Exception in a PHP Exception to be able to serialize it.
66 | *
67 | * @param Throwable $exception
68 | *
69 | * @return \Symfony\Component\Debug\Exception\FlattenException
70 | */
71 | protected function getFlattenedException(Throwable $exception)
72 | {
73 | if (! $exception instanceof FlattenException) {
74 | $exception = FlattenException::createFromThrowable($exception);
75 | }
76 |
77 | return $exception;
78 | }
79 |
80 | /**
81 | * Get the html response content.
82 | *
83 | * @param string $content
84 | * @param string $css
85 | * @param Exception|Throwable $exception
86 | *
87 | * @return string
88 | */
89 | protected function decorate($content, $css, $exception)
90 | {
91 | return $this->view
92 | ->make('notifex::body', compact('content', 'css', 'exception'))
93 | ->render();
94 | }
95 |
96 | protected function environment(): string
97 | {
98 | return App::environment();
99 | }
100 |
101 | protected function host(): string
102 | {
103 | return Http::host();
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/Services/NotifyException.php:
--------------------------------------------------------------------------------
1 | queue = Config::get('notifex.queue', 'default');
29 |
30 | $this->handler = $handler;
31 | }
32 |
33 | /**
34 | * @param Throwable $exception
35 | */
36 | public function send(Throwable $exception)
37 | {
38 | try {
39 | if ($this->isIgnoreBots() || ! $this->isEnabled()) {
40 | return;
41 | }
42 |
43 | $this->exception = $exception;
44 |
45 | $this->sendEmail();
46 | $this->sendJobs();
47 | }
48 | catch (Throwable $exception) {
49 | $this->log($exception, __FUNCTION__);
50 | }
51 | }
52 |
53 | protected function sendEmail()
54 | {
55 | try {
56 | if (Config::get('notifex.email.enabled', true)) {
57 | new Email($this->handler, $this->exception);
58 | }
59 | }
60 | catch (Throwable $exception) {
61 | $this->log($exception, __FUNCTION__);
62 | }
63 | }
64 |
65 | protected function sendJobs()
66 | {
67 | try {
68 | $jobs = (array) Config::get('notifex.jobs', []);
69 |
70 | if (! count($jobs)) {
71 | return;
72 | }
73 |
74 | $classname = (string) get_class($this->exception);
75 | $message = (string) $this->exception->getMessage();
76 | $file = (string) $this->exception->getFile();
77 | $line = (int) $this->exception->getLine();
78 | $trace_as_string = (string) $this->exception->getTraceAsString();
79 |
80 | foreach ($jobs as $job => $params) {
81 | try {
82 | if ($params['enabled'] ?? true) {
83 | $job = is_numeric($job) ? $params : $job;
84 |
85 | dispatch(new $job($classname, $message, $file, $line, $trace_as_string))
86 | ->onQueue($this->queue);
87 | }
88 | }
89 | catch (Throwable $exception) {
90 | $this->log($exception, __FUNCTION__);
91 | }
92 | }
93 | }
94 | catch (Throwable $exception) {
95 | $this->log($exception, __FUNCTION__);
96 | }
97 | }
98 |
99 | protected function isIgnoreBots(): bool
100 | {
101 | $ignore_bots = Config::get('notifex.ignore_bots', true);
102 |
103 | if (! $ignore_bots) {
104 | return false;
105 | }
106 |
107 | $crawler = new CrawlerDetect();
108 |
109 | return $crawler->isCrawler($this->userAgent());
110 | }
111 |
112 | protected function isEnabled()
113 | {
114 | $enabled = Config::get('notifex.enabled', true);
115 | $email = Config::get('notifex.email.enabled', true);
116 |
117 | $jobs = array_filter(Config::get('notifex.jobs', []), function ($item) {
118 | return $item['enabled'] ?? false;
119 | });
120 |
121 | return $enabled && ($email || count($jobs) > 0);
122 | }
123 |
124 | protected function userAgent(): ?string
125 | {
126 | return Http::userAgent();
127 | }
128 |
129 | protected function log(Throwable $exception, string $function_name)
130 | {
131 | Log::error(sprintf(
132 | 'Exception thrown in %s::%s when capturing an exception',
133 | get_class(),
134 | $function_name
135 | ));
136 |
137 | Log::error($exception);
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/Support/App.php:
--------------------------------------------------------------------------------
1 | url(), PHP_URL_HOST);
12 | }
13 |
14 | public function url(): string
15 | {
16 | return app('request')->url() ?? Config::get('app.url') ?: 'http://localhost';
17 | }
18 |
19 | public function userAgent(): ?string
20 | {
21 | return app('request')->userAgent() ?? null;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Traits/JobsConfiguration.php:
--------------------------------------------------------------------------------
1 |