Merge branch 'master' into blacklist

This commit is contained in:
n1rwana 2022-10-01 17:14:43 +03:00 committed by GitHub
commit 03ac5b6554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 904 additions and 452 deletions

View file

@ -1,11 +1,8 @@
<?xml encoding="UTF-8"?>
<!ELEMENT latte (tags,filters,variables,functions)>
<!ATTLIST latte vendor #REQUIRED>
<!ATTLIST latte version #REQUIRED>
<!ELEMENT tags (tag)+>
<!ELEMENT tag (arguments)?>
<!ATTLIST tag name CDATA #REQUIRED>
<!ATTLIST tag type (PAIR|UNPAIRED|UNPAIRED_ATTR|ATTR_ONLY|AUTO_EMPTY) #REQUIRED>
@ -13,34 +10,26 @@
<!ATTLIST tag arguments CDATA #IMPLIED>
<!ATTLIST tag deprecatedMessage CDATA #IMPLIED>
<!ATTLIST tag multiLine (true|false) #IMPLIED>
<!ELEMENT arguments (argument)+>
<!ELEMENT argument EMPTY>
<!ATTLIST argument name #REQUIRED>
<!ATTLIST argument types CDATA #REQUIRED>
<!ATTLIST argument repeatable (true|false) #IMPLIED>
<!ATTLIST argument required (true|false) #IMPLIED>
<!ATTLIST argument validType #IMPLIED>
<!ATTLIST argument validType #IMPLIED>
<!ELEMENT filters (filter)+>
<!ELEMENT filter EMPTY>
<!ATTLIST filter name #REQUIRED>
<!ATTLIST filter description CDATA #IMPLIED>
<!ATTLIST filter arguments CDATA #IMPLIED>
<!ATTLIST filter insertColons #IMPLIED>
<!ATTLIST filter insertColons #IMPLIED>
<!ELEMENT variables (variable)+>
<!ELEMENT variable EMPTY>
<!ATTLIST variable name #REQUIRED>
<!ATTLIST variable type CDATA #REQUIRED>
<!ELEMENT functions (function)+>
<!ELEMENT function EMPTY>
<!ATTLIST function name #REQUIRED>
<!ATTLIST function name #REQUIRED>
<!ATTLIST function arguments CDATA #REQUIRED>
<!ATTLIST function returnType #REQUIRED>
<!ATTLIST function returnType #REQUIRED>
<!ATTLIST function description CDATA #IMPLIED>

View file

@ -1,290 +1,290 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE latte PUBLIC "-//LATTE//Latte plugin XML V0.0.1//EN" "Latte.dtd">
<latte vendor="latte" version="1">
<tags>
<tag name="_" type="AUTO_EMPTY" allowedFilters="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="=" type="UNPAIRED" allowedFilters="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="block" type="AUTO_EMPTY" allowedFilters="true" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="breakIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="capture" type="PAIR" allowedFilters="true" multiLine="true">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION" required="true" />
</arguments>
</tag>
<tag name="case" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="catch" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="contentType" type="UNPAIRED">
<arguments>
<argument name="content-type" types="CONTENT_TYPE" validType="string" required="true" />
</arguments>
</tag>
<tag name="continueIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="debugbreak" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="default" type="UNPAIRED">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="define" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" required="true" />
<argument name="variable" types="VARIABLE_DEFINITION_ITEM" repeatable="true" />
</arguments>
</tag>
<tag name="do" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="dump" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="else" type="UNPAIRED_ATTR" />
<tag name="elseif" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="elseifset" type="UNPAIRED">
<arguments>
<argument name="var" types="VARIABLE,BLOCK" validType="string" required="true" />
</arguments>
</tag>
<tag name="extends" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION,NONE" validType="string" required="true" />
</arguments>
</tag>
<tag name="first" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" required="true" />
</arguments>
</tag>
<tag name="for" type="PAIR" arguments="initialization; condition; afterthought" multiLine="true" />
<tag name="foreach" type="PAIR" arguments="expression as [$key =>] $value" allowedFilters="true" multiLine="true" />
<tag name="if" type="PAIR">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="ifset" type="PAIR">
<arguments>
<argument name="var" types="VARIABLE,BLOCK,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="import" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="include" type="UNPAIRED" allowedFilters="true">
<arguments>
<argument name="file" types="BLOCK,IDENTIFIER,PHP_EXPRESSION" validType="string" required="true" />
<argument name="arguments" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<tag name="includeblock" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="l" type="UNPAIRED" />
<tag name="last" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" required="true" />
</arguments>
</tag>
<tag name="layout" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION,NONE" validType="string" required="true" />
</arguments>
</tag>
<tag name="class" type="ATTR_ONLY" arguments="class" />
<tag name="attr" type="ATTR_ONLY" arguments="attr" />
<tag name="ifcontent" type="ATTR_ONLY" />
<tag name="php" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="r" type="UNPAIRED" />
<tag name="sandbox" type="UNPAIRED">
<arguments>
<argument name="file" types="BLOCK,PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
<argument name="key-value" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<tag name="sep" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" />
</arguments>
</tag>
<tag name="snippet" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" />
</arguments>
</tag>
<tag name="snippetArea" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="spaceless" type="PAIR" />
<tag name="switch" type="PAIR" multiLine="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" />
</arguments>
</tag>
<tag name="syntax" type="PAIR" arguments="off | double | latte" multiLine="true" />
<tag name="templatePrint" type="UNPAIRED">
<arguments>
<argument name="class-name" types="PHP_CLASS_NAME" />
</arguments>
</tag>
<tag name="templateType" type="UNPAIRED">
<arguments>
<argument name="class-name" types="PHP_CLASS_NAME" required="true" />
</arguments>
</tag>
<tag name="try" type="PAIR" />
<tag name="rollback" type="UNPAIRED" />
<tag name="tag" type="ATTR_ONLY">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" validType="string" repeatable="true" />
</arguments>
</tag>
<tag name="ifchanged" type="PAIR">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="skipIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="var" type="UNPAIRED">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="trace" type="UNPAIRED" />
<tag name="varPrint" type="UNPAIRED" arguments="all" />
<tag name="varType" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_TYPE" required="true" />
<argument name="variable" types="VARIABLE_DEFINITION" required="true" />
</arguments>
</tag>
<tag name="while" type="PAIR" multiLine="true">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="iterateWhile" type="PAIR" multiLine="true" />
<tag name="embed" type="PAIR" multiLine="true">
<arguments>
<argument name="file" types="BLOCK_USAGE,PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
<argument name="key-value" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<!-- @deprecated - latte -->
<tag name="assign" type="UNPAIRED" arguments="$variable = expr" />
<tag name="truncate" type="UNPAIRED" arguments="expression" deprecatedMessage="Tag {? ...} is deprecated in Latte 2.4. For variable definitions use {var ...} or {php ...} in other cases." />
</tags>
<filters>
<filter name="truncate" arguments=":($length, $append = '…')" description="shortens the length preserving whole words" insertColons=":" />
<filter name="substr" arguments=":($offset [, $length])" description="returns part of the string" insertColons=":" />
<filter name="trim" arguments=":($charset = mezery)" description="strips whitespace or other characters from the beginning and end of the string" />
<filter name="stripHtml" arguments="" description="removes HTML tags and converts HTML entities to text" />
<filter name="strip" arguments="" description="removes whitespace" />
<filter name="indent" arguments=":($level = 1, $char = '\t')" description="indents the text from left with number of tabs" />
<filter name="replace" arguments=":($search, $replace = '')" description="replaces all occurrences of the search string with the replacement" insertColons=":" />
<filter name="replaceRE" arguments=":($pattern, $replace = '')" description="replaces all occurrences according to regular expression" insertColons=":" />
<filter name="padLeft" arguments=":($length, $pad = ' ')" description="completes the string to given length from left" insertColons=":" />
<filter name="padRight" arguments=":($length, $pad = ' ')" description="completes the string to given length from right" insertColons=":" />
<filter name="repeat" arguments=":($count)" description="repeats the string" insertColons=":" />
<filter name="implode" arguments=":($glue = '')" description="joins an array to a string" />
<filter name="webalize" description="adjusts the UTF-8 string to the shape used in the URL" />
<filter name="breaklines" description="inserts HTML line breaks before all newlines" />
<filter name="reverse" description="reverse an UTF-8 string or array" />
<filter name="length" description="returns length of a string or array" />
<filter name="sort" description="simply sorts array" />
<filter name="reverse" description="array sorted in reverse order (used with |sort)" />
<filter name="batch" arguments=":($array, $length [, $item])" description="returns length of a string or array" insertColons="::" />
<tags>
<tag name="_" type="AUTO_EMPTY" allowedFilters="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="=" type="UNPAIRED" allowedFilters="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="block" type="AUTO_EMPTY" allowedFilters="true" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="breakIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="capture" type="PAIR" allowedFilters="true" multiLine="true">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION" required="true" />
</arguments>
</tag>
<tag name="case" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="catch" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="contentType" type="UNPAIRED">
<arguments>
<argument name="content-type" types="CONTENT_TYPE" validType="string" required="true" />
</arguments>
</tag>
<tag name="continueIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="debugbreak" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="default" type="UNPAIRED">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="define" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" required="true" />
<argument name="variable" types="VARIABLE_DEFINITION_ITEM" repeatable="true" />
</arguments>
</tag>
<tag name="do" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="dump" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="else" type="UNPAIRED_ATTR" />
<tag name="elseif" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="elseifset" type="UNPAIRED">
<arguments>
<argument name="var" types="VARIABLE,BLOCK" validType="string" required="true" />
</arguments>
</tag>
<tag name="extends" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION,NONE" validType="string" required="true" />
</arguments>
</tag>
<tag name="first" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" required="true" />
</arguments>
</tag>
<tag name="for" type="PAIR" arguments="initialization; condition; afterthought" multiLine="true" />
<tag name="foreach" type="PAIR" arguments="expression as [$key =>] $value" allowedFilters="true" multiLine="true" />
<tag name="if" type="PAIR">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="ifset" type="PAIR">
<arguments>
<argument name="var" types="VARIABLE,BLOCK,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="import" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="include" type="UNPAIRED" allowedFilters="true">
<arguments>
<argument name="file" types="BLOCK,IDENTIFIER,PHP_EXPRESSION" validType="string" required="true" />
<argument name="arguments" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<tag name="includeblock" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="l" type="UNPAIRED" />
<tag name="last" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" required="true" />
</arguments>
</tag>
<tag name="layout" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION,NONE" validType="string" required="true" />
</arguments>
</tag>
<tag name="class" type="ATTR_ONLY" arguments="class" />
<tag name="attr" type="ATTR_ONLY" arguments="attr" />
<tag name="ifcontent" type="ATTR_ONLY" />
<tag name="php" type="UNPAIRED">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" />
</arguments>
</tag>
<tag name="r" type="UNPAIRED" />
<tag name="sandbox" type="UNPAIRED">
<arguments>
<argument name="file" types="BLOCK,PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
<argument name="key-value" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<tag name="sep" type="PAIR">
<arguments>
<argument name="width" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="int" />
</arguments>
</tag>
<tag name="snippet" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" />
</arguments>
</tag>
<tag name="snippetArea" type="PAIR" multiLine="true">
<arguments>
<argument name="name" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="string" required="true" />
</arguments>
</tag>
<tag name="spaceless" type="PAIR" />
<tag name="switch" type="PAIR" multiLine="true">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" />
</arguments>
</tag>
<tag name="syntax" type="PAIR" arguments="off | double | latte" multiLine="true" />
<tag name="templatePrint" type="UNPAIRED">
<arguments>
<argument name="class-name" types="PHP_CLASS_NAME" />
</arguments>
</tag>
<tag name="templateType" type="UNPAIRED">
<arguments>
<argument name="class-name" types="PHP_CLASS_NAME" required="true" />
</arguments>
</tag>
<tag name="try" type="PAIR" />
<tag name="rollback" type="UNPAIRED" />
<tag name="tag" type="ATTR_ONLY">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" validType="string" repeatable="true" />
</arguments>
</tag>
<tag name="ifchanged" type="PAIR">
<arguments>
<argument name="expression" types="PHP_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="skipIf" type="UNPAIRED">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="var" type="UNPAIRED">
<arguments>
<argument name="variable" types="VARIABLE_DEFINITION_EXPRESSION" required="true" repeatable="true" />
</arguments>
</tag>
<tag name="trace" type="UNPAIRED" />
<tag name="varPrint" type="UNPAIRED" arguments="all" />
<tag name="varType" type="UNPAIRED">
<arguments>
<argument name="file" types="PHP_TYPE" required="true" />
<argument name="variable" types="VARIABLE_DEFINITION" required="true" />
</arguments>
</tag>
<tag name="while" type="PAIR" multiLine="true">
<arguments>
<argument name="condition" types="PHP_CONDITION" validType="bool" required="true" />
</arguments>
</tag>
<tag name="iterateWhile" type="PAIR" multiLine="true" />
<tag name="embed" type="PAIR" multiLine="true">
<arguments>
<argument name="file" types="BLOCK_USAGE,PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
<argument name="key-value" types="KEY_VALUE" repeatable="true" />
</arguments>
</tag>
<!-- @deprecated - latte -->
<tag name="assign" type="UNPAIRED" arguments="$variable = expr" />
<tag name="truncate" type="UNPAIRED" arguments="expression" deprecatedMessage="Tag {? ...} is deprecated in Latte 2.4. For variable definitions use {var ...} or {php ...} in other cases." />
</tags>
<filters>
<filter name="truncate" arguments=":($length, $append = '…')" description="shortens the length preserving whole words" insertColons=":" />
<filter name="substr" arguments=":($offset [, $length])" description="returns part of the string" insertColons=":" />
<filter name="trim" arguments=":($charset = mezery)" description="strips whitespace or other characters from the beginning and end of the string" />
<filter name="stripHtml" arguments="" description="removes HTML tags and converts HTML entities to text" />
<filter name="strip" arguments="" description="removes whitespace" />
<filter name="indent" arguments=":($level = 1, $char = '\t')" description="indents the text from left with number of tabs" />
<filter name="replace" arguments=":($search, $replace = '')" description="replaces all occurrences of the search string with the replacement" insertColons=":" />
<filter name="replaceRE" arguments=":($pattern, $replace = '')" description="replaces all occurrences according to regular expression" insertColons=":" />
<filter name="padLeft" arguments=":($length, $pad = ' ')" description="completes the string to given length from left" insertColons=":" />
<filter name="padRight" arguments=":($length, $pad = ' ')" description="completes the string to given length from right" insertColons=":" />
<filter name="repeat" arguments=":($count)" description="repeats the string" insertColons=":" />
<filter name="implode" arguments=":($glue = '')" description="joins an array to a string" />
<filter name="webalize" description="adjusts the UTF-8 string to the shape used in the URL" />
<filter name="breaklines" description="inserts HTML line breaks before all newlines" />
<filter name="reverse" description="reverse an UTF-8 string or array" />
<filter name="length" description="returns length of a string or array" />
<filter name="sort" description="simply sorts array" />
<filter name="reverse" description="array sorted in reverse order (used with |sort)" />
<filter name="batch" arguments=":($array, $length [, $item])" description="returns length of a string or array" insertColons="::" />
<filter name="clamp" description="returns value clamped to the inclusive range of min and max." insertColons="::" />
<filter name="clamp" description="returns value clamped to the inclusive range of min and max." insertColons="::" />
<filter name="lower" description="makes a string lower case" />
<filter name="upper" description="makes a string upper case" />
<filter name="firstUpper" description="makes the first letter upper case" />
<filter name="capitalize" description="lower case, the first letter of each word upper case" />
<filter name="lower" description="makes a string lower case" />
<filter name="upper" description="makes a string upper case" />
<filter name="firstUpper" description="makes the first letter upper case" />
<filter name="capitalize" description="lower case, the first letter of each word upper case" />
<filter name="date" arguments=":($format)" description="formats date" insertColons=":" />
<filter name="number" arguments=":($decimals = 0, $decPoint = '.', $thousandsSep = ',')" description="format number" />
<filter name="bytes" arguments=":($precision = 2)" description="formats size in bytes" />
<filter name="dataStream" arguments=":($mimetype = 'detect')" description="Data URI protocol conversion" />
<filter name="date" arguments=":($format)" description="formats date" insertColons=":" />
<filter name="number" arguments=":($decimals = 0, $decPoint = '.', $thousandsSep = ',')" description="format number" />
<filter name="bytes" arguments=":($precision = 2)" description="formats size in bytes" />
<filter name="dataStream" arguments=":($mimetype = 'detect')" description="Data URI protocol conversion" />
<filter name="noescape" description="prints a variable without escaping" />
<filter name="escapeurl" description="escapes parameter in URL" />
<filter name="noescape" description="prints a variable without escaping" />
<filter name="escapeurl" description="escapes parameter in URL" />
<filter name="nocheck" description="prevents automatic URL sanitization" />
<filter name="checkurl" description="sanitizes string for use inside href attribute" />
<filter name="nocheck" description="prevents automatic URL sanitization" />
<filter name="checkurl" description="sanitizes string for use inside href attribute" />
<filter name="query" description="generates a query string in the URL" />
<filter name="ceil" arguments=":(int $precision = 0)" description="rounds a number up to a given precision" />
<filter name="explode" arguments=":(string $separator = '')" description="splits a string by the given delimiter" />
<filter name="first" description="returns first element of array or character of string" />
<filter name="floor" arguments=":(int $precision = 0)" description="rounds a number down to a given precision" />
<filter name="join" arguments=":(string $glue = '')" description="joins an array to a string" />
<filter name="last" description="returns last element of array or character of string" />
<filter name="random" description="returns random element of array or character of string" />
<filter name="round" arguments=":(int $precision = 0)" description="rounds a number to a given precision" />
<filter name="slice" arguments=":(int $start, int $length = null, bool $preserveKeys = false)" description="extracts a slice of an array or a string" insertColons=":" />
<filter name="spaceless" description="removes whitespace" />
<filter name="split" arguments=":(string $separator = '')" description="splits a string by the given delimiter" />
</filters>
<functions>
<function name="clamp" returnType="int|float" arguments="(int|float $value, int|float $min, int|float $max)" description="clamps value to the inclusive range of min and max" />
<function name="divisibleBy" returnType="bool" arguments="(int $value)" description="checks if a variable is divisible by a number" />
<function name="even" returnType="bool" arguments="(int $value)" description="checks if the given number is even" />
<function name="first" returnType="mixed" arguments="(string|array $value)" description="returns first element of array or character of string" />
<function name="last" returnType="mixed" arguments="(string|array $value)" description="returns last element of array or character of string" />
<function name="odd" returnType="bool" arguments="(int $value)" description="checks if the given number is odd" />
<function name="slice" returnType="string|array" arguments="(string|array $value, int $start, int $length = null, bool $preserveKeys = false)" description="extracts a slice of an array or a string" />
</functions>
<filter name="query" description="generates a query string in the URL" />
<filter name="ceil" arguments=":(int $precision = 0)" description="rounds a number up to a given precision" />
<filter name="explode" arguments=":(string $separator = '')" description="splits a string by the given delimiter" />
<filter name="first" description="returns first element of array or character of string" />
<filter name="floor" arguments=":(int $precision = 0)" description="rounds a number down to a given precision" />
<filter name="join" arguments=":(string $glue = '')" description="joins an array to a string" />
<filter name="last" description="returns last element of array or character of string" />
<filter name="random" description="returns random element of array or character of string" />
<filter name="round" arguments=":(int $precision = 0)" description="rounds a number to a given precision" />
<filter name="slice" arguments=":(int $start, int $length = null, bool $preserveKeys = false)" description="extracts a slice of an array or a string" insertColons=":" />
<filter name="spaceless" description="removes whitespace" />
<filter name="split" arguments=":(string $separator = '')" description="splits a string by the given delimiter" />
</filters>
<functions>
<function name="clamp" returnType="int|float" arguments="(int|float $value, int|float $min, int|float $max)" description="clamps value to the inclusive range of min and max" />
<function name="divisibleBy" returnType="bool" arguments="(int $value)" description="checks if a variable is divisible by a number" />
<function name="even" returnType="bool" arguments="(int $value)" description="checks if the given number is even" />
<function name="first" returnType="mixed" arguments="(string|array $value)" description="returns first element of array or character of string" />
<function name="last" returnType="mixed" arguments="(string|array $value)" description="returns last element of array or character of string" />
<function name="odd" returnType="bool" arguments="(int $value)" description="checks if the given number is odd" />
<function name="slice" returnType="string|array" arguments="(string|array $value, int $start, int $length = null, bool $preserveKeys = false)" description="extracts a slice of an array or a string" />
</functions>
</latte>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/openvk.iml" filepath="$PROJECT_DIR$/.idea/openvk.iml" />
</modules>
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/openvk.iml" filepath="$PROJECT_DIR$/.idea/openvk.iml" />
</modules>
</component>
</project>

View file

@ -1,46 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/vendor/rybakit/msgpack" />
<excludeFolder url="file://$MODULE_DIR$/vendor/chillerlan/php-qrcode" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/chillerlan/php-settings-container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/vearutop/php-obscene-censor-rus" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scssphp/scssphp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/bhaktaraz/php-rss-generator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/erusev/parsedown" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ezyang/htmlpurifier" />
<excludeFolder url="file://$MODULE_DIR$/vendor/whichbrowser/parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/komeiji-satori/curl" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/james-heinrich/getid3" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/wapmorgan/binary-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/al/emoji-detector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/lfkeitel/phptotp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/zadarma/user-api-v1" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/wapmorgan/morphos" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/vendor/rybakit/msgpack" />
<excludeFolder url="file://$MODULE_DIR$/vendor/chillerlan/php-qrcode" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/chillerlan/php-settings-container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/vearutop/php-obscene-censor-rus" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scssphp/scssphp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/bhaktaraz/php-rss-generator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/erusev/parsedown" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ezyang/htmlpurifier" />
<excludeFolder url="file://$MODULE_DIR$/vendor/whichbrowser/parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/komeiji-satori/curl" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/james-heinrich/getid3" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/wapmorgan/binary-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/al/emoji-detector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/lfkeitel/phptotp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/zadarma/user-api-v1" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/wapmorgan/morphos" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -1,48 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/rybakit/msgpack" />
<path value="$PROJECT_DIR$/vendor/chillerlan/php-qrcode" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/chillerlan/php-settings-container" />
<path value="$PROJECT_DIR$/vendor/vearutop/php-obscene-censor-rus" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/scssphp/scssphp" />
<path value="$PROJECT_DIR$/vendor/bhaktaraz/php-rss-generator" />
<path value="$PROJECT_DIR$/vendor/erusev/parsedown" />
<path value="$PROJECT_DIR$/vendor/ezyang/htmlpurifier" />
<path value="$PROJECT_DIR$/vendor/whichbrowser/parser" />
<path value="$PROJECT_DIR$/vendor/komeiji-satori/curl" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/james-heinrich/getid3" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/wapmorgan/binary-stream" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/al/emoji-detector" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/lfkeitel/phptotp" />
<path value="$PROJECT_DIR$/vendor/zadarma/user-api-v1" />
<path value="$PROJECT_DIR$/../../../chandler" />
<path value="$PROJECT_DIR$/../../../vendor" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/wapmorgan/morphos" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.4">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/rybakit/msgpack" />
<path value="$PROJECT_DIR$/vendor/chillerlan/php-qrcode" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/chillerlan/php-settings-container" />
<path value="$PROJECT_DIR$/vendor/vearutop/php-obscene-censor-rus" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/scssphp/scssphp" />
<path value="$PROJECT_DIR$/vendor/bhaktaraz/php-rss-generator" />
<path value="$PROJECT_DIR$/vendor/erusev/parsedown" />
<path value="$PROJECT_DIR$/vendor/ezyang/htmlpurifier" />
<path value="$PROJECT_DIR$/vendor/whichbrowser/parser" />
<path value="$PROJECT_DIR$/vendor/komeiji-satori/curl" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/james-heinrich/getid3" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/wapmorgan/binary-stream" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/al/emoji-detector" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/lfkeitel/phptotp" />
<path value="$PROJECT_DIR$/vendor/zadarma/user-api-v1" />
<path value="$PROJECT_DIR$/../../../chandler" />
<path value="$PROJECT_DIR$/../../../vendor" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/wapmorgan/morphos" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.4">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

View file

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -133,15 +133,18 @@ final class Friends extends VKAPIRequestHandler
return $response;
}
function getRequests(string $fields = "", int $offset = 0, int $count = 100): object
function getRequests(string $fields = "", int $offset = 0, int $count = 100, int $extended = 0): object
{
if ($count >= 1000)
$this->fail(100, "One of the required parameters was not passed or is invalid.");
$this->requireUser();
$i = 0;
$offset++;
$followers = [];
foreach($this->getUser()->getFollowers() as $follower) {
foreach($this->getUser()->getFollowers($offset, $count) as $follower) {
$followers[$i] = $follower->getId();
$i++;
}
@ -149,8 +152,10 @@ final class Friends extends VKAPIRequestHandler
$response = $followers;
$usersApi = new Users($this->getUser());
if(!is_null($fields))
$response = $usersApi->get(implode(',', $followers), $fields, 0, $count); # FIXME
if($extended == 1)
$response = $usersApi->get(implode(',', $followers), $fields, 0, $count);
else
$response = $usersApi->get(implode(',', $followers), "", 0, $count);
foreach($response as $user)
$user->user_id = $user->id;

View file

@ -27,14 +27,23 @@ class NewMessageEvent implements ILPEmitable
if($peer === $userId)
$peer = $msg->getRecipient()->getId();
/*
* Source:
* https://github.com/danyadev/longpoll-doc
*/
return [
4, # event type
$msg->getId(), # messageId
256, # checked for spam flag
$peer, # TODO calculate peer correctly
$msg->getSendTime()->timestamp(), # creation time in unix
$msg->getText(), # text (formatted)
[], # empty additional info
[], # empty attachments
$msg->getId() << 2, # id as random_id
$peer, # conversation id
0 # not edited yet
];
}
}

View file

@ -0,0 +1,34 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Entities;
use openvk\Web\Models\RowModel;
use openvk\Web\Models\Entities\{User, Club};
use openvk\Web\Models\Repositories\{Users, Clubs};
class Alias extends RowModel
{
protected $tableName = "aliases";
function getOwnerId(): int
{
return $this->getRecord()->owner_id;
}
function getType(): string
{
if ($this->getOwnerId() < 0)
return "club";
return "user";
}
function getUser(): ?User
{
return (new Users)->get($this->getOwnerId());
}
function getClub(): ?Club
{
return (new Clubs)->get($this->getOwnerId() * -1);
}
}

View file

@ -911,6 +911,10 @@ class User extends RowModel
$pClub = DatabaseConnection::i()->getContext()->table("groups")->where("shortcode", $code)->fetch();
if(!is_null($pClub))
return false;
$pAlias = DatabaseConnection::i()->getContext()->table("aliases")->where("shortcode", $code)->fetch();
if(!is_null($pAlias))
return false;
}
$this->stateChanges("shortcode", $code);

View file

@ -0,0 +1,35 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Repositories;
use openvk\Web\Models\Entities\Alias;
use Nette\Database\Table\ActiveRow;
use Chandler\Database\DatabaseConnection as DB;
use openvk\Web\Models\Entities\{Club, User};
use openvk\Web\Models\Repositories\{Clubs, Users};
class Aliases
{
private $context;
private $aliases;
function __construct()
{
$this->context = DB::i()->getContext();
$this->aliases = $this->context->table("aliases");
}
private function toAlias(?ActiveRow $ar): ?Alias
{
return is_null($ar) ? NULL : new Alias($ar);
}
function get(int $id): ?Alias
{
return $this->toAlias($this->aliases->get($id));
}
function getByShortcode(string $shortcode): ?Alias
{
return $this->toAlias($this->aliases->where("shortcode", $shortcode)->fetch());
}
}

View file

@ -1,6 +1,7 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Repositories;
use openvk\Web\Models\Entities\Club;
use openvk\Web\Models\Repositories\Aliases;
use Nette\Database\Table\ActiveRow;
use Chandler\Database\DatabaseConnection;
@ -22,7 +23,17 @@ class Clubs
function getByShortURL(string $url): ?Club
{
return $this->toClub($this->clubs->where("shortcode", $url)->fetch());
$shortcode = $this->toClub($this->clubs->where("shortcode", $url)->fetch());
if ($shortcode)
return $shortcode;
$alias = (new Aliases)->getByShortcode($url);
if (!$alias) return NULL;
if ($alias->getType() !== "club") return NULL;
return $alias->getClub();
}
function get(int $id): ?Club
@ -45,6 +56,9 @@ class Clubs
function getPopularClubs(): \Traversable
{
// TODO rewrite
/*
$query = "SELECT ROW_NUMBER() OVER (ORDER BY `subscriptions` DESC) as `place`, `target` as `id`, COUNT(`follower`) as `subscriptions` FROM `subscriptions` WHERE `model` = \"openvk\\\Web\\\Models\\\Entities\\\Club\" GROUP BY `target` ORDER BY `subscriptions` DESC, `id` LIMIT 30;";
$entries = DatabaseConnection::i()->getConnection()->query($query);
@ -54,6 +68,7 @@ class Clubs
"club" => $this->get($entry["id"]),
"subscriptions" => $entry["subscriptions"],
];
*/
}
use \Nette\SmartObject;

View file

@ -1,6 +1,7 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Repositories;
use openvk\Web\Models\Entities\User;
use openvk\Web\Models\Repositories\Aliases;
use Nette\Database\Table\ActiveRow;
use Chandler\Database\DatabaseConnection;
use Chandler\Security\User as ChandlerUser;
@ -9,11 +10,13 @@ class Users
{
private $context;
private $users;
private $aliases;
function __construct()
{
$this->context = DatabaseConnection::i()->getContext();
$this->users = $this->context->table("profiles");
$this->aliases = $this->context->table("aliases");
}
private function toUser(?ActiveRow $ar): ?User
@ -28,7 +31,17 @@ class Users
function getByShortURL(string $url): ?User
{
return $this->toUser($this->users->where("shortcode", $url)->fetch());
$shortcode = $this->toUser($this->users->where("shortcode", $url)->fetch());
if ($shortcode)
return $shortcode;
$alias = (new Aliases)->getByShortcode($url);
if (!$alias) return NULL;
if ($alias->getType() !== "user") return NULL;
return $alias->getUser();
}
function getByChandlerUser(ChandlerUser $user): ?User

View file

@ -64,7 +64,7 @@ final class AboutPresenter extends OpenVKPresenter
$this->template->usersStats = (new Users)->getStatistics();
$this->template->clubsCount = (new Clubs)->getCount();
$this->template->postsCount = (new Posts)->getCount();
$this->template->popularClubs = iterator_to_array((new Clubs)->getPopularClubs());
$this->template->popularClubs = [];
$this->template->admins = iterator_to_array((new Users)->getInstanceAdmins());
}

View file

@ -6,7 +6,7 @@ use openvk\Web\Models\Repositories\Applications;
final class AppsPresenter extends OpenVKPresenter
{
private $apps;
protected $presenterName = "apps";
function __construct(Applications $apps)
{
$this->apps = $apps;

View file

@ -84,6 +84,9 @@ final class AuthPresenter extends OpenVKPresenter
if (strtotime($this->postParam("birthday")) > time())
$this->flashFail("err", tr("invalid_birth_date"), tr("invalid_birth_date_comment"));
if (!$this->postParam("confirmation"))
$this->flashFail("err", tr("error"), tr("checkbox_in_registration_unchecked"));
try {
$user = new User;
$user->setFirst_Name($this->postParam("first_name"));

View file

@ -6,6 +6,7 @@ use openvk\Web\Models\Repositories\{Comments, Clubs};
final class CommentPresenter extends OpenVKPresenter
{
protected $presenterName = "comment";
private $models = [
"posts" => "openvk\\Web\\Models\\Repositories\\Posts",
"photos" => "openvk\\Web\\Models\\Repositories\\Photos",

View file

@ -7,6 +7,7 @@ final class GiftsPresenter extends OpenVKPresenter
{
private $gifts;
private $users;
protected $presenterName = "gifts";
function __construct(Gifts $gifts, Users $users)
{

View file

@ -8,6 +8,7 @@ use Chandler\Security\Authenticator;
final class GroupPresenter extends OpenVKPresenter
{
private $clubs;
protected $presenterName = "group";
function __construct(Clubs $clubs)
{

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace openvk\Web\Presenters;
final class MaintenancePresenter extends OpenVKPresenter
{
protected $presenterName = "maintenance";
function renderSection(string $name): void
{
if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["maintenanceMode"][$name])
$this->flashFail("err", tr("error"), tr("forbidden"));
$this->template->name = [
"photos" => tr("my_photos"),
"videos" => tr("my_videos"),
"messenger" => tr("my_messages"),
"user" => tr("users"),
"group" => tr("my_groups"),
"comment" => tr("comments"),
"gifts" => tr("gifts"),
"apps" => tr("apps"),
"notes" => tr("my_notes"),
"notification" => tr("my_feedback"),
"support" => tr("menu_support"),
"topics" => tr("topics")
][$name] ?? $name;
}
function renderAll(): void
{
}
}

View file

@ -9,11 +9,13 @@ final class MessengerPresenter extends OpenVKPresenter
{
private $messages;
private $signaler;
protected $presenterName = "messenger";
function __construct(Messages $messages)
{
$this->messages = $messages;
$this->signaler = SignalManager::i();
parent::__construct();
}
@ -94,6 +96,13 @@ final class MessengerPresenter extends OpenVKPresenter
$legacy = $this->queryParam("version") < 3;
$time = intval($this->queryParam("wait"));
if($time > 60)
$time = 60;
elseif($time == 0)
$time = 25; // default
$this->signaler->listen(function($event, $eId) use ($id) {
exit(json_encode([
"ts" => time(),
@ -101,7 +110,7 @@ final class MessengerPresenter extends OpenVKPresenter
$event->getVKAPISummary($id),
],
]));
}, $id);
}, $id, $time);
}
function renderApiGetMessages(int $sel, int $lastMsg): void

View file

@ -6,6 +6,7 @@ use openvk\Web\Models\Entities\Note;
final class NotesPresenter extends OpenVKPresenter
{
private $notes;
protected $presenterName = "notes";
function __construct(Notes $notes)
{

View file

@ -3,6 +3,8 @@ namespace openvk\Web\Presenters;
final class NotificationPresenter extends OpenVKPresenter
{
protected $presenterName = "notification";
function renderFeed(): void
{
$this->assertUserLoggedIn();

View file

@ -17,6 +17,7 @@ abstract class OpenVKPresenter extends SimplePresenter
protected $deactivationTolerant = false;
protected $errorTemplate = "@error";
protected $user = NULL;
protected $presenterName;
private function calculateQueryString(array $data): string
{
@ -202,6 +203,7 @@ abstract class OpenVKPresenter extends SimplePresenter
$userValidated = 0;
$cacheTime = OPENVK_ROOT_CONF["openvk"]["preferences"]["nginxCacheTime"] ?? 0;
if(!is_null($user)) {
$this->user = (object) [];
$this->user->raw = $user;
@ -264,6 +266,16 @@ abstract class OpenVKPresenter extends SimplePresenter
header("X-Accel-Expires: $cacheTime");
setlocale(LC_TIME, ...(explode(";", tr("__locale"))));
if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["maintenanceMode"]["all"]) {
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["maintenanceMode"][$this->presenterName]) {
$this->pass("openvk!Maintenance->section", $this->presenterName);
}
} else {
if ($this->presenterName != "maintenance") {
$this->redirect("/maintenances/");
}
}
parent::onStartup();
}

View file

@ -9,6 +9,7 @@ final class PhotosPresenter extends OpenVKPresenter
private $users;
private $photos;
private $albums;
protected $presenterName = "photos";
function __construct(Photos $photos, Albums $albums, Users $users)
{

View file

@ -11,6 +11,7 @@ final class SupportPresenter extends OpenVKPresenter
{
protected $banTolerant = true;
protected $deactivationTolerant = true;
protected $presenterName = "support";
private $tickets;
private $comments;
@ -155,11 +156,12 @@ final class SupportPresenter extends OpenVKPresenter
$this->notFound();
} else {
if($ticket->getUserId() !== $this->user->id && $this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0))
$this->redirect("/support/tickets");
$_redirect = "/support/tickets";
else
$this->redirect("/support");
$_redirect = "/support?act=list";
$ticket->delete();
$this->redirect($_redirect);
}
}
}

View file

@ -7,6 +7,7 @@ final class TopicsPresenter extends OpenVKPresenter
{
private $topics;
private $clubs;
protected $presenterName = "topics";
function __construct(Topics $topics, Clubs $clubs)
{

View file

@ -14,11 +14,11 @@ use Nette\Database\UniqueConstraintViolationException;
final class UserPresenter extends OpenVKPresenter
{
public $deactivationTolerant = false;
protected $presenterName = "user";
private $users;
private $blacklists;
public $deactivationTolerant = false;
function __construct(Users $users, Blacklists $blacklists)
{
$this->users = $users;

View file

@ -8,6 +8,7 @@ final class VideosPresenter extends OpenVKPresenter
{
private $videos;
private $users;
protected $presenterName = "videos";
function __construct(Videos $videos, Users $users)
{

View file

@ -87,12 +87,15 @@
{captcha_template()|noescape}
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="checkbox" required="true" name="confirmation" /> {_checkbox_in_registration|noescape}
<br /><br />
<input type="submit" value="{_registration}" class="button" />
<a href="/login">{_log_in}</a>
</td>

View file

@ -0,0 +1,20 @@
{extends "../@layout.xml"}
{block title}
{_global_maintenance}
{/block}
{block header}
{_global_maintenance}
{/block}
{block content}
<div class="container_gray">
<center style="background: white;border: #DEDEDE solid 1px;">
<img src="/assets/packages/static/openvk/img/oof.apng" style="width: 20%;" />
<span style="color: #707070;margin: 10px 0;display: block;">
{_undergoing_global_maintenance}
</span>
</center>
</div>
{/block}

View file

@ -0,0 +1,20 @@
{extends "../@layout.xml"}
{block title}
{_section_maintenance}
{/block}
{block header}
{_section_maintenance}
{/block}
{block content}
<div class="container_gray">
<center style="background: white;border: #DEDEDE solid 1px;">
<img src="/assets/packages/static/openvk/img/oof.apng" style="width: 20%;" />
<span style="color: #707070;margin: 10px 0;display: block;">
{tr("undergoing_section_maintenance", $name)|noescape}
</span>
</center>
</div>
{/block}

View file

@ -53,7 +53,7 @@
<div n:attr="id => ($act === 'online' ? 'activetabs' : 'ki')" class="tab">
<a n:attr="id => ($act === 'online' ? 'act_tab_a' : 'ki')" href="?act=online">{_online}</a>
</div>
<div n:attr="id => ($act === 'incoming' || $act === 'outcoming' ? 'activetabs' : 'ki')" class="tab">
<div n:if="!is_null($thisUser) && $user->getId() === $thisUser->getId()" n:attr="id => ($act === 'incoming' || $act === 'outcoming' ? 'activetabs' : 'ki')" class="tab">
<a n:attr="id => ($act === 'incoming' || $act === 'outcoming' ? 'act_tab_a' : 'ki')" href="?act=incoming">{_req}</a>
</div>
{/block}

View file

@ -79,9 +79,9 @@
{/block}
{block actions}
<a href="{$x->getURL()}" class="profile_link">{_check_community}</a>
{if $x->canBeModifiedBy($thisUser ?? NULL)}
{var $clubPinned = $thisUser->isClubPinned($x)}
<a href="{$x->getURL()}" class="profile_link">{_check_community}</a>
<a href="/groups_pin?club={$x->getId()}&hash={rawurlencode($csrfToken)}" class="profile_link" n:if="$clubPinned || $thisUser->getPinnedClubCount() <= 10" id="_pinGroup" data-group-name="{$x->getName()}" data-group-url="{$x->getUrl()}">
{if $clubPinned}
{_remove_from_left_menu}
@ -89,6 +89,15 @@
{_add_to_left_menu}
{/if}
</a>
{/if}
{if $x->getSubscriptionStatus($thisUser) == false}
<form class="profile_link_form" action="/setSub/club" method="post">
<input type="hidden" name="act" value="add" />
<input type="hidden" name="id" value="{$x->getId()}" />
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="submit" class="profile_link" value="{_join_community}" />
</form>
{else}
<form class="profile_link_form" action="/setSub/club" method="post">
<input type="hidden" name="act" value="rem" />
<input type="hidden" name="id" value="{$x->getId()}" />

View file

@ -45,4 +45,6 @@ services:
- openvk\Web\Models\Repositories\Applications
- openvk\Web\Models\Repositories\ContentSearchRepository
- openvk\Web\Models\Repositories\Blacklists
- openvk\Web\Models\Repositories\Aliases
- openvk\Web\Models\Repositories\BannedLinks
- openvk\Web\Presenters\MaintenancePresenter

View file

@ -335,3 +335,7 @@ routes:
handler: "UnknownTextRouteStrategy->delegate"
placeholders:
shortCode: "[a-z][a-z0-9\\@\\.\\_]{0,30}[a-z0-9]"
- url: "/maintenance/{text}"
handler: "Maintenance->section"
- url: "/maintenances/"
handler: "Maintenance->all"

View file

@ -1,14 +1,13 @@
CREATE TABLE `links_banned` (
`id` bigint UNSIGNED NOT NULL,
`domain` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`regexp_rule` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
`domain` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
`regexp_rule` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
`reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci,
`initiator` bigint UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
ALTER TABLE `links_banned`
ADD PRIMARY KEY (`id`);
ALTER TABLE `links_banned`
MODIFY `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;

View file

@ -0,0 +1,11 @@
CREATE TABLE `aliases` (
`id` bigint UNSIGNED NOT NULL,
`owner_id` bigint NOT NULL,
`shortcode` varchar(36) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
ALTER TABLE `aliases`
ADD PRIMARY KEY (`id`);
ALTER TABLE `aliases`
MODIFY `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT;

View file

@ -17,6 +17,8 @@
"password" = "Գաղտնաբառ";
"registration" = "Գրանցում";
"forgot_password" = "Մոռացե՞լ եք գաղտնաբառը";
"checkbox_in_registration" = "Ես համաձայն եմ <a href='/privacy'>կոնֆիդենցիալության քաղաքականությանն</a> ու <a href='/about'>կայքի կանոնադրությանը</a>։";
"checkbox_in_registration_unchecked" = "Դուք պետք է համաձայնվեք պայմանների հետ նախքան գրանցվելը։";
"login_failed" = "Չհաջողվեց մուտք գործել";
"invalid_username_or_password" = "Սխալ օգտատիրոջ անուն կամ գաղտնաբառ։ Դուք կարող եք <a href='/restore'>վերականգնել ձեր գաղտնաբառը</a>։";
@ -93,6 +95,9 @@
"years_many" = "$1 տարեկան";
"years_other" = "$1 տարեկան";
"show_my_birthday" = "Ցույց տալ ծննդյան օրը";
"show_only_month_and_day" = "Ցուցադրել միայն ամիսն ու օրը";
"relationship" = "Ընտանեկան դրություն";
"relationship_0" = "Ընտրված չէ";
@ -144,8 +149,8 @@
"updated_at" = "Թարմացված է $1";
"user_banned" = "Ցավո՛ք, մենք ստիպված <b>$1</b>-ի էջը կասեցրել ենք։";
"user_banned_comment" = "Մոդերատորի մեկնաբանությունը․ ";
"user_banned" = "Ցավո՛ք, մենք ստիպված կասեցրել ենք <b>$1</b>-ի էջը։";
"user_banned_comment" = "Մոդերատորի մեկնաբանությունը․";
/* Wall */
@ -154,6 +159,10 @@
"post_writes_m" = "գրել է";
"post_writes_f" = "գրել է";
"post_writes_g" = "հրապարակել են";
"post_deact_m" = "ջնջել է էջը հետևյալ բառերով.";
"post_deact_f" = "ջնջել է էջը հետևյալ բառերով.";
"post_deact_silent_m" = "սուս ու փուս ջնջել է էջը։";
"post_deact_silent_f" = "սուս ու փուս ջնջել է էջը։";
"wall" = "Պատ";
"post" = "Գրություն";
"write" = "Գրել";
@ -167,7 +176,7 @@
"comments_tip" = "Եղե՛ք առաջինը ով կթողնի իր կարծիքը։";
"your_comment" = "Ձեր մեկնաբանությունը";
"shown" = "Ցուցադրված է";
"x_out_of" = "$1 –ը ՝";
"x_out_of" = "$1ը";
"wall_zero" = "գրություն չկա";
"wall_one" = "մեկ գրություն";
"wall_few" = "$1 գրություն";
@ -215,6 +224,8 @@
"incoming_req" = "Բաժանորդներ";
"outcoming_req" = "Հայցեր";
"req" = "Հայցեր";
"friends_online" = "Ընկերները ցանցում";
"all_friends" = "Բոլոր ընկերները";
"req_zero" = "Ոչ մի հայտ չի գտնվել...";
"req_one" = "Գտնվեց մեկ հայտ";
@ -246,6 +257,12 @@
"subscriptions_many" = "$1 բաժանորդագրություն";
"subscriptions_other" = "$1 բաժանորդագրություն";
"friends_list_online_zero" = "Դուք դեռ չունեք ցանցի մեջ գտնվող ընկերներ";
"friends_list_online_one" = "Ձեր $1 ընկերը ցանցի մեջ է";
"friends_list_online_few" = "Ձեր $1 ընկերները ցանցի մեջ են";
"friends_list_online_many" = "Ձեր $1 ընկերները ցանցի մեջ են";
"friends_list_online_other" = "Ձեր $1 ընկերները ցանցի մեջ են";
/* Group */
"name_group" = "Անվանում";
@ -364,6 +381,10 @@
"edit_note" = "Խմբագրել նշումը";
"actions" = "Գործողություններ";
"notes_start_screen" = "Նշումների շնորհիվ Դուք կարող եք կիսվել ընկերների հետ տարբեր իրադարձություններով, և իմանալ թե ինչ է կատարվում իրենց մոտ։";
"note_preview" = "Նախադիտում";
"note_preview_warn" = "Սա ընդամենը նախադիտում է";
"note_preview_warn_details" = "Պահպանելուց հետո նշումները կարող են այլ տեսք ունենալ։ Ու մեկ էլ, այդքան հաճախ նախադիտում մի արեք։";
"note_preview_empty_err" = "Ինչու՞ նախադիտել նշումը առանց վերնագրի կամ բովանդակության։";
"edited" = "Խմբագրված է";
@ -428,6 +449,7 @@
"avatar" = "Ավատար";
"privacy" = "Գաղտնիություն";
"interface" = "Արտաքին տեսք";
"security" = "Անվտանգություն";
"profile_picture" = "Էջի նկար";
@ -445,7 +467,7 @@
"arbitrary_avatars" = "Կամայական";
"cut" = "Կտրվածք";
"round_avatars" = "Կլոր ավատար";
"round_avatars" = "Շրջանաձև";
"apply_style_for_this_device" = "Հաստատել տեսքը միայն այս սարքի համար";
@ -508,6 +530,33 @@
"email_change_confirm_message" = "Որպեսզի Ձեր փոփոխությունը կատարվի, հաստատե՛ք Ձեր նոր էլեկտրոնային հասցեն։ Այնտեղ մենք ուղարկել ենք հրահանգները։";
"profile_deactivate" = "Էջի հեռացում";
"profile_deactivate_button" = "Ջնջել էջը";
"profile_deactivate_header" = "Մենք ցավում ենք որ Դուք ցանկանում եք ջնջել ձեր էջը։ Դրա համար Դուք կարող եք նշել հեռացման պատճառը և Ձեր կարծիքը այդ առումով։ Մեզ համար կարևոր է Ձեր կարծիքը, որպեսզի դարձնենք կայքը ավելի լավը։";
"profile_deactivate_reason_header" = "Խնդրում ենք, նշել Ձեր էջի ջնջման պատճառները";
"profile_deactivate_reason_1" = "Ես ունեմ այլ էջ այս կայնքում";
"profile_deactivate_reason_1_text" = "Ես նոր էջ եմ սկսել ու ցանկանում եմ սկսել ամեն ինչ նորից";
"profile_deactivate_reason_2" = "Կայքն ինձնից շատ ժամանակ է խլում";
"profile_deactivate_reason_2_text" = "Թեկուզ այս կայքը լավն է, բայց ցավոք ինձնից ահագին ժամանակ է խլում։";
"profile_deactivate_reason_3" = "Կայքը բազմաթիվ անցանկանալի մատերիալներ է պարունակում";
"profile_deactivate_reason_3_text" = "Ես բազմաթիվ պոռնոգրաֆիա ու անօրինական կինոներ եմ գրել բոլ ա։ Հիմա հավես չկա։";
"profile_deactivate_reason_4" = "Ինձ անհանգստացնում է իմ տվյալների անվտանգությունը";
"profile_deactivate_reason_4_text" = "Ինձ հետևում են ու շատ վախենալու է ինձ այստեղ գտնվելը";
"profile_deactivate_reason_5" = "Իմ էջը չեն մեկնաբանում";
"profile_deactivate_reason_5_text" = "Ինձ այստեղ շան տեղ դնող չկա ու ես տխրում եմ։ Դուք կզղջաք որ ես հեռացա...";
"profile_deactivate_reason_6" = "Այլ պատճառ";
"profile_deactivated_msg" = "Ձեր էջը <b>ջնջված է</b>։<br/><br/>Եթե Դուք ուզենաք նորից օգտվել Ձեր էջով, կարող եք <a href='/settings/reactivate'>ապաակտիվացնել այն</a> մինչև $1:";
"profile_deactivated_status" = "Էջը ջնջված է";
"profile_deactivated_info" = "Օգտատիրոջ էջը հեռացվել է։<br/>Մանրամասն տեղեկատվությունը բացակայում է։";
"share_with_friends" = "Պատմել ընկերներին";
"end_all_sessions" = "Դուրս գալ բոլոր սեսսիաներից";
"end_all_sessions_description" = "Եթե ցանկանում եք դուրս գալ $1ից ամեն դեվայսից, սեղմե՛ք ներքևի կոճակը";
"end_all_sessions_done" = "Բոլոր սեսսիաները նետված են, ներառյալ բջջային հավելվածները";
/* Two-factor authentication */
"two_factor_authentication" = "Երկքայլ աուտենտիֆիկացիա";
@ -708,6 +757,75 @@
"users_gifts" = "Նվերներ";
/* Apps */
"app" = "Հավելված";
"apps" = "Հավելվածներ";
"my_apps" = "Իմ հավելվածները";
"all_apps" = "Բոլոր հավելվածները";
"installed_apps" = "Տեղադրված հավելվածները";
"own_apps" = "Կառավարում";
"own_apps_alternate" = "Իմ այլ հավելվածները";
"app_play" = "միացնել";
"app_uninstall" = "անջատել";
"app_edit" = "խմբագրել";
"app_dev" = "Մշակող";
"create_app" = "Ստեղծել հավելված";
"edit_app" = "Խմբագրել հավելվածը";
"new_app" = "Նոր հավելված";
"app_news" = "Նորություններով նշում";
"app_state" = "Կարգավիճակ";
"app_enabled" = "Միացված է";
"app_creation_hint_url" = "URLում նշեք կոնկրետ հասցեն իր սխեմայով (https), պորտով (80) և անհրաժեշտ միացման կարգավորումներով։";
"app_creation_hint_iframe" = "Ձեր հավելվածը բացված է iframeով։";
"app_balance" = "Հավելվածի հաշվին կա <b>$1</b> ձայն։";
"app_users" = "Ձեր հավելվածով օգտվում է <b>$1</b> հոգի։";
"app_withdrawal_q" = "դուրս բերե՞լ";
"app_withdrawal" = "Միջոցների դուրս բերում";
"app_withdrawal_empty" = "Կներեք, դատարկությունը չհաջողվեց դուրս բերել։";
"app_withdrawal_created" = "$1 ձայնի դուրս բերման հայտը գրանցված է։ Սպասեք հաշվառմանը։";
"appjs_payment" = "Գնման վճարում";
"appjs_payment_intro" = "Դուք պատրաստվում եք հավելվածի գնումը վճարել";
"appjs_order_items" = "Գնման ցուցակ";
"appjs_payment_total" = "Վճարման ընդհանուր գին";
"appjs_payment_confirm" = "Վճարել";
"appjs_err_funds" = "Չհաջողվե՛ց վճարել գնումը անբավարար միջոցների համար։";
"appjs_wall_post" = "Հրապարակել գրությունտը";
"appjs_wall_post_desc" = "ցանկանում է Ձեր պատին գրություն թողնել";
"appjs_sperm_friends" = "ձեր ընկերներին";
"appjs_sperm_friends_desc" = "ավելացնել օգտատերերին որպես ընկերներ և կարդալ Ձեր գրությունները";
"appjs_sperm_wall" = "ձեր պատին";
"appjs_sperm_wall_desc" = "դիտել Ձեր լուրերը, կարդալ պատն ու թողել գրություններ";
"appjs_sperm_messages" = "ձեր նամակներին";
"appjs_sperm_messages_desc" = "կարդալ և գրել նամակներ Ձեր անունից";
"appjs_sperm_groups" = "ձեր հանրություններին";
"appjs_sperm_groups_desc" = "դիտել Ձեր խմբերի ցուցակն ու բաժանորդագրել դեպի այլ խմբեր";
"appjs_sperm_likes" = "լայքելու ֆունկցիոնալին";
"appjs_sperm_likes_desc" = "տեղադրել և հանել \"Դուր գալու\" ռեակցիաները ձայնագրություններից";
"appjs_sperm_request" = "Հասանելիության հարցում";
"appjs_sperm_requests" = "հասանելիություն է խնդրում";
"appjs_sperm_can" = "Հավելվածը կարող է";
"appjs_sperm_allow" = "Թույլատրել";
"appjs_sperm_disallow" = "Չթույլատրել";
"app_uninstalled" = "Հավելվածն անջատված է";
"app_uninstalled_desc" = "Այն Ձեր անունից էլ չի կարող կատարել գործողություններ։";
"app_err_not_found" = "Հավելվածը չի գտնվել";
"app_err_not_found_desc" = "Սխալ կամ անջատված իդենտիֆիկատոր։";
"app_err_forbidden_desc" = "Այս հավելվածը Ձերը չէ։";
"app_err_url" = "Սխալ հասցե";
"app_err_url_desc" = "Հավելվածի հասցեն չանցավ ստուգումը. համոզվե՛ք որ այն ճիշտ է գրված:";
"app_err_ava" = "Չհաջողվե՛ց վերբեռնել ավատարը:";
"app_err_ava_desc" = "Ավատարը չափազանց մեծ և ծուռ է. ընդհանուր բնույթի սխալ №$res.";
"app_err_note" = "Չհաջողվե՛ց ամրացնել նորությունների նիշքը";
"app_err_note_desc" = "Համոզվե՛ք որ հղումը ճիշտ է և պատկանում է Ձեզ։";
/* Support */
"support_opened" = "Բաց";
@ -767,7 +885,12 @@
"banned_alt" = "Օգտատերը արգելափակված է";
"banned_1" = "Կներե՛ք, <b>$1</b>, բայց Դուք կասեցված եք։";
"banned_2" = "Պատճառը հետևյալն է․ <b>$1</b>. Ափսոս, բայց մենք ստիպված Ձեզ հավերժ ենք կասեցրել;";
"banned_perm" = "Ցավոք, մենք ստիպված արգելափակել ենք Ձեզ ընդմիշտ։";
"banned_until_time" = "Այս անգամ մենք ստիպված արգելափակել ենք Ձեզ մինչև <b>$1</b>";
"banned_3" = "Դուք դեռ կարող եք <a href=\"/support?act=new\">գրել նամակ աջակցության ծառայությանը</a>, եթե համարում եք որ դա սխալմունք է, կամ էլ կարող եք <a href=\"/logout?hash=$1\">դուրս գալ</a>։";
"banned_unban_myself" = "Ապասառեցնել էջը";
"banned_unban_title" = "Ձեր հաշիվը ապասառեցված է։";
"banned_unban_description" = "Աշխատե՛ք այլևս չխախտել կանոնները։";
/* Registration confirm */
@ -996,6 +1119,17 @@
"admin_commerce_disabled" = "Կոմմերցիան անջատված է համակարգային ադմինիստրատորի կողմից";
"admin_commerce_disabled_desc" = "Վաուչերների և նվերների կարգավորումները կպահպանվեն, բայց ոչ մի ազդեցություն չեն ունենա։";
"admin_banned_links" = "Արգելափակված հղումներ";
"admin_banned_link" = "Հղում";
"admin_banned_domain" = "Դոմեն";
"admin_banned_link_description" = "Պրոտոկոլով (https://example.com/)";
"admin_banned_link_regexp" = "Ռեգուլյար արտահայտություն";
"admin_banned_link_regexp_description" = "Տեղադրվում է վերոնշյալ դոմենից հետո։ Մի լրացրե՛ք, եթե ցանկանում եք արգելափակել ամբողջ դոմենը";
"admin_banned_link_reason" = "Պատճառ";
"admin_banned_link_initiator" = "Նախաձեռնող";
"admin_banned_link_not_specified" = "Հղումը նշված չէ";
"admin_banned_link_not_found" = "Հղումը չի գտնվել";
/* Paginator (deprecated) */
"paginator_back" = "Հետ";
@ -1059,3 +1193,21 @@
"cookies_popup_content" = "Cookie բառը անգլերենից նշանակում է թխվածքաբլիթ, իսկ թխվածքաբլիթը համեղ է։ Մեր կայքը չի ուտում թխվածք, բայց օգտագործում է այն ուղղակի սեսսիան կողմնորոշելու համար։ Ավելի մանրամասն կարող եք ծանոթանալ մեր <a href='/privacy'>գաղտնիության քաղաքականությանը</a> հավելյալ ինֆորմացիայի համար։";
"cookies_popup_agree" = "Համաձայն եմ";
/* Away */
"url_is_banned" = "Անցումն անհնար է";
"url_is_banned_comment" = "Ադմինիստրացիան <b>$1</b> խորհուրդ չի տալից անցնել այս հղումով։";
"url_is_banned_comment_r" = "Ադմինիստրացիան <b>$1</b> խորհուրդ չի տալից անցնել այս հղումով։<br><br>Պատճառը: <b>$2</b>";
"url_is_banned_default_reason" = "Հղումը դեպի կայք կարող է ստեղծված լինել շորթողներից ՝ օգտատերերին խաբելու և խարդախության նպատակներով, շահույթ ստանալու համար։";
"url_is_banned_title" = "Հղում դեպի կասկածելի կայք";
"url_is_banned_proceed" = "Անցնել հղումով";
/* Maintenance */
"global_maintenance" = "Տեխնիկական աշխատանքներ";
"section_maintenance" = "Բաժինը անհասանելի է";
"undergoing_global_maintenance" = "Ցավոք սրտի, հիմա հոսքը փակված է տեխնիկական աշխատանքներ անցկացնելու համար։ Մենք արդեն աշխատում ենք խնդիրները շտկելու ուղղությամբ։ Խնդրում ենք այցելել մի քիչ ուշ։";
"undergoing_section_maintenance" = "Ցավոք սրտի, <b>$1</b> բաժինը ժամանակավորապես անհասանելի է։ Մենք արդեն աշխատում ենք խնդիրները շտկելու ուղղությամբ։ Խնդրում ենք այցելել մի քիչ ուշ։";
"topics" = "Թեմաներ";

View file

@ -1156,3 +1156,12 @@
"url_is_banned_default_reason" = "The link you are trying to open may lead you to a site that was created for the purpose of deceiving users with the intention of gaining profit.";
"url_is_banned_title" = "Link to a suspicious site";
"url_is_banned_proceed" = "Follow the link";
/* Maintenance */
"global_maintenance" = "Undergoing maintenance";
"section_maintenance" = "The section is not available";
"undergoing_global_maintenance" = "Unfortunately, the instance is now closed for technical work. We are already working on troubleshooting. Please try to come back later.";
"undergoing_section_maintenance" = "Unfortunately, the <b>$1</b> section is temporarily unavailable. We are already working on troubleshooting. Please try to come back later.";
"topics" = "Topics";

View file

@ -13,7 +13,7 @@ list:
flag: "ua"
name: "Ukrainian"
native_name: "Україньска"
author: "Andrej Lenťaj, Maxim Hrabovi (dechioyo) and Kirill (mbsoft)"
author: "Yaroslav Bjelograd, Andrej Lenťaj, Maxim Hrabovi (dechioyo) and Kirill (mbsoft)"
- code: "by"
flag: "by"
name: "Belarussian"

View file

@ -15,6 +15,8 @@
"password" = "Пароль";
"registration" = "Регистрация";
"forgot_password" = "Забыли пароль?";
"checkbox_in_registration" = "Я согласен с <a href='/privacy'>политикой конфиденциальности</a> и <a href='/about'>правилами сайта</a>";
"checkbox_in_registration_unchecked" = "Вы должны согласиться с политикой конфиденциальности и правилами, чтобы зарегистрироваться.";
"login_failed" = "Не удалось войти";
"invalid_username_or_password" = "Неверное имя пользователя или пароль. <a href='/restore'>Забыли пароль?</a>";
@ -990,7 +992,7 @@
"changes_saved_comment" = "Новые данные появятся на вашей странице";
"photo_saved" = "Фотография сохранена";
"photo_saved_comment" = "Новое изображние профиля появится у вас на странице";
"photo_saved_comment" = "Новое изображение профиля появится у вас на странице";
"shared_succ" = "Запись появится на вашей стене. Нажмите на уведомление, чтобы перейти к своей стене.";
@ -1216,3 +1218,12 @@
"url_is_banned_default_reason" = "Ссылка, по которой вы попытались перейти, может вести на сайт, который был создан с целью обмана пользователей и получения за счёт этого прибыли.";
"url_is_banned_title" = "Ссылка на подозрительный сайт";
"url_is_banned_proceed" = "Перейти по ссылке";
/* Maintenance */
"global_maintenance" = "Технические работы";
"section_maintenance" = "Раздел недоступен";
"undergoing_global_maintenance" = "К сожалению, сейчас инстанс закрыт на технические работы. Мы уже работаем над устранением неисправностей. Пожалуйста, попробуйте зайти позже.";
"undergoing_section_maintenance" = "К сожалению, раздел <b>$1</b> временно недоступен. Мы уже работаем над устранением неисправностей. Пожалуйста, попробуйте зайти позже.";
"topics" = "Темы";

View file

@ -15,6 +15,8 @@
"password" = "Пароль";
"registration" = "Реєстрація";
"forgot_password" = "Забули пароль?";
"checkbox_in_registration" = "Я згоден з <a href='/privacy'>політикою конфіденційності</a> і <a href='/about'>правилами сайту</a>";
"checkbox_in_registration_unchecked" = "Ви повинні погодитися з політикою конфіденційності та правилами, щоб зареєструватися.";
"login_failed" = "Не вдалося увійти";
"invalid_username_or_password" = "Неправильне ім'я користувача або пароль. <a href='/restore'>Забули пароль?</a>";
@ -210,6 +212,7 @@
/* Friends */
"friends" = "Друзі";
"followers" = "Підписники";
"follower" = "Підписник";
"friends_add" = "Додати в друзі";
@ -218,10 +221,11 @@
"friends_accept" = "Прийняти заявку";
"send_message" = "Відправити повідомлення";
"incoming_req" = "Підписники";
"outcoming_req" = "Вихідні";
"req" = "Заявки";
"outcoming_req" = "Заявки";
"friends_online" = "Друзі онлайн";
"all_friends" = "Усі друзі";
"req" = "Заявки";
"req_zero" = "Не знайдено жодної заявки...";
"req_one" = "Знайдена $1 заявка";
@ -235,18 +239,18 @@
"friends_many" = "$1 друзів";
"friends_other" = "$1 друзів";
"friends_list_zero" = "У вас поки немає друзів";
"friends_list_one" = "У Вас $1 друг";
"friends_list_few" = "У Вас $1 друг";
"friends_many" = "$1 друзів";
"friends_other" = "$1 друзів";
"friends_online_zero" = "Жодного друга онлайн";
"friends_online_one" = "$1 друг онлайн";
"friends_online_few" = "$1 друга онлайн";
"friends_online_many" = "$1 друзів онлайн";
"friends_online_other" = "$1 друзів онлайн";
"friends_list_zero" = "У вас поки немає друзів";
"friends_list_one" = "У Вас $1 друг";
"friends_list_few" = "У Вас $1 друг";
"friends_many" = "$1 друзів";
"friends_other" = "$1 друзів";
"followers_zero" = "Жодного підписника";
"followers_one" = "$1 підписник";
"followers_few" = "$1 підписника";
@ -1122,6 +1126,17 @@
"admin_commerce_disabled" = "Комерція відключена системним адміністратором";
"admin_commerce_disabled_desc" = "Налаштування ваучерів та подарунків будуть збережені, але не матимуть впливу.";
"admin_banned_links" = "Заблоковані посилання";
"admin_banned_link" = "Посилання";
"admin_banned_domain" = "Домен";
"admin_banned_link_description" = "З протоколом (https://example.org/)";
"admin_banned_link_regexp" = "Регулярний вираз";
"admin_banned_link_regexp_description" = "Підставляється після домену, зазначеного вище. Не заповнюйте, якщо хочете заблокувати весь домен";
"admin_banned_link_reason" = "Причина";
"admin_banned_link_initiator" = "Ініціатор";
"admin_banned_link_not_specified" = "Посилання не зазначено";
"admin_banned_link_not_found" = "Посилання не знайдено";
/* Paginator (deprecated) */
"paginator_back" = "Назад";
@ -1185,3 +1200,12 @@
"cookies_popup_content" = "Цей веб-сайт використовує cookies для того, щоб ідентифікувати вашу сесію і нічого більше. Ознайомтеся з нашою <a href='/privacy'>політикою конфіденційності</a> для отримання додаткової інформації.";
"cookies_popup_agree" = "Згоден";
/* Away */
"url_is_banned" = "Перехід неможливий";
"url_is_banned_comment" = "Адміністрація <b>$1</b> не рекомендує переходити за цим посиланням.";
"url_is_banned_comment_r" = "Адміністрація <b>$1</b> не рекомендує переходити за цим посиланням.<br><br>Підстава: <b>$2</b>";
"url_is_banned_default_reason" = "Посилання, за яким Ви спробували перейти, може вести на сайт, що був створений з метою обману користувачів і отримання шляхом цього неправомірного прибутку.";
"url_is_banned_title" = "Посилання на підозрілий сайт";
"url_is_banned_proceed" = "Перейти за посиланням";

View file

@ -60,6 +60,20 @@ openvk:
susLinks:
warnings: true
showReason: true
maintenanceMode:
all: false
photos: false
videos: false
messenger: false
user: false
group: false
comment: false
gifts: false
apps: false
notes: false
notification: false
support: false
topics: false
ton:
enabled: false
address: "🅿"