mirror of
https://github.com/openvk/openvk
synced 2025-03-14 21:45:22 +03:00
Merge branch 'master' into feature-reports
This commit is contained in:
commit
f86963dedd
88 changed files with 2756 additions and 312 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,7 +5,7 @@ update.pid.old
|
|||
Web/static/js/node_modules
|
||||
|
||||
tmp/*
|
||||
!tmp/.gitkeep
|
||||
!tmp/api-storage
|
||||
!tmp/themepack_artifacts/.gitkeep
|
||||
themepacks/*
|
||||
!themepacks/.gitkeep
|
||||
|
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
46
.idea/intellij-latte/xmlSources/Latte.dtd
Normal file
46
.idea/intellij-latte/xmlSources/Latte.dtd
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?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>
|
||||
<!ATTLIST tag allowedFilters (true|false) #IMPLIED>
|
||||
<!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>
|
||||
|
||||
<!ELEMENT filters (filter)+>
|
||||
|
||||
<!ELEMENT filter EMPTY>
|
||||
<!ATTLIST filter name #REQUIRED>
|
||||
<!ATTLIST filter description CDATA #IMPLIED>
|
||||
<!ATTLIST filter arguments CDATA #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 arguments CDATA #REQUIRED>
|
||||
<!ATTLIST function returnType #REQUIRED>
|
||||
<!ATTLIST function description CDATA #IMPLIED>
|
290
.idea/intellij-latte/xmlSources/Latte.xml
Normal file
290
.idea/intellij-latte/xmlSources/Latte.xml
Normal file
|
@ -0,0 +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="::" />
|
||||
|
||||
<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="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="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>
|
||||
</latte>
|
59
.idea/intellij-latte/xmlSources/NetteApplication.xml
Normal file
59
.idea/intellij-latte/xmlSources/NetteApplication.xml
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE latte PUBLIC "-//LATTE//Latte plugin configuration XML V0.0.1//EN" "Latte.dtd">
|
||||
<latte version="1" vendor="nette/application">
|
||||
<tags>
|
||||
<!-- nette/application tags -->
|
||||
<tag name="cache" type="PAIR" arguments="if => expr, key, …">
|
||||
<arguments>
|
||||
<argument name="name[:part]" types="KEY_VALUE" validType="string" required="true" />
|
||||
<argument name="arguments" types="PHP_EXPRESSION" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="control" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="name[:part]" types="PHP_IDENTIFIER,PHP_EXPRESSION" validType="string" required="true" />
|
||||
<argument name="arguments" types="PHP_EXPRESSION" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="link" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="destination" types="LINK_DESTINATION,PHP_EXPRESSION" validType="string" required="true" />
|
||||
<argument name="arguments" types="LINK_PARAMETERS" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="href" type="ATTR_ONLY">
|
||||
<arguments>
|
||||
<argument name="destination" types="LINK_DESTINATION,PHP_EXPRESSION" validType="string" required="true" />
|
||||
<argument name="arguments" types="LINK_PARAMETERS" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="nonce" type="ATTR_ONLY" />
|
||||
<tag name="plink" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="destination" types="LINK_DESTINATION,PHP_EXPRESSION" validType="string" required="true" />
|
||||
<argument name="arguments" types="LINK_PARAMETERS" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<!-- @deprecated - nette/application -->
|
||||
<tag name="ifCurrent" type="PAIR" deprecatedMessage="Tag {ifCurrent} is deprecated in Latte 2.6. Use custom function isLinkCurrent() instead.">
|
||||
<arguments>
|
||||
<argument name="destination" types="LINK_DESTINATION,PHP_EXPRESSION" validType="string" required="true" />
|
||||
<argument name="arguments" types="LINK_PARAMETERS" repeatable="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
</tags>
|
||||
<variables>
|
||||
<variable name="control" type="\Nette\Application\UI\Control" />
|
||||
<variable name="basePath" type="string" />
|
||||
<variable name="baseUrl" type="string" />
|
||||
<variable name="flashes" type="mixed[]" />
|
||||
<variable name="presenter" type="\Nette\Application\UI\Presenter" />
|
||||
<variable name="iterator" type="\Latte\Runtime\CachingIterator" />
|
||||
<variable name="form" type="\Nette\Application\UI\Form" />
|
||||
<variable name="user" type="\Nette\Security\User" />
|
||||
</variables>
|
||||
<functions>
|
||||
<function name="isLinkCurrent" returnType="bool" arguments="(string $destination = null, $args = [])" />
|
||||
<function name="isModuleCurrent" returnType="bool" arguments="(string $moduleName)" />
|
||||
</functions>
|
||||
</latte>
|
41
.idea/intellij-latte/xmlSources/NetteForms.xml
Normal file
41
.idea/intellij-latte/xmlSources/NetteForms.xml
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE latte PUBLIC "-//LATTE//Latte plugin configuration XML V0.0.1//EN" "Latte.dtd">
|
||||
<latte version="1" vendor="nette/forms">
|
||||
<tags>
|
||||
<tag name="form" type="PAIR" multiLine="true">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="formContainer" type="PAIR" multiLine="true">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="formPrint" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="input" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,CONTROL,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="inputError" type="UNPAIRED">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,CONTROL,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="label" type="AUTO_EMPTY">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,CONTROL,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
<tag name="name" type="ATTR_ONLY">
|
||||
<arguments>
|
||||
<argument name="name" types="PHP_IDENTIFIER,VARIABLE,CONTROL,PHP_EXPRESSION" validType="string" required="true" />
|
||||
</arguments>
|
||||
</tag>
|
||||
</tags>
|
||||
</latte>
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +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>
|
||||
</project>
|
45
.idea/openvk.iml
Normal file
45
.idea/openvk.iml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
47
.idea/php.xml
Normal file
47
.idea/php.xml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?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" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.4">
|
||||
<option name="suggestChangeDefaultLanguageLevel" value="false" />
|
||||
</component>
|
||||
</project>
|
10
.idea/runConfigurations.xml
Normal file
10
.idea/runConfigurations.xml
Normal file
|
@ -0,0 +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>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
86
CLI/RebuildImagesCommand.php
Normal file
86
CLI/RebuildImagesCommand.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\CLI;
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
use openvk\Web\Models\Repositories\Photos;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Nette\Utils\ImageException;
|
||||
|
||||
class RebuildImagesCommand extends Command
|
||||
{
|
||||
private $images;
|
||||
|
||||
protected static $defaultName = "build-images";
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->images = DatabaseConnection::i()->getContext()->table("photos");
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setDescription("Create resized versions of images")
|
||||
->setHelp("This command allows you to resize all your images after configuration change")
|
||||
->addOption("upgrade-only", "U", InputOption::VALUE_NEGATABLE, "Only upgrade images which aren't resized?");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$header = $output->section();
|
||||
$counter = $output->section();
|
||||
|
||||
$header->writeln([
|
||||
"Image Rebuild Utility",
|
||||
"=====================",
|
||||
"",
|
||||
]);
|
||||
|
||||
$filter = ["deleted" => false];
|
||||
if($input->getOption("upgrade-only"))
|
||||
$filter["sizes"] = NULL;
|
||||
|
||||
$selection = $this->images->select("id")->where($filter);
|
||||
$totalPics = $selection->count();
|
||||
$header->writeln([
|
||||
"Total of $totalPics images found.",
|
||||
"",
|
||||
]);
|
||||
|
||||
$errors = 0;
|
||||
$count = 0;
|
||||
$avgTime = NULL;
|
||||
$begin = new \DateTimeImmutable("now");
|
||||
foreach($selection as $idHolder) {
|
||||
$start = microtime(true);
|
||||
|
||||
try {
|
||||
$photo = (new Photos)->get($idHolder->id);
|
||||
$photo->getSizes(true, true);
|
||||
$photo->getDimensions();
|
||||
} catch(ImageException $ex) {
|
||||
$errors++;
|
||||
}
|
||||
|
||||
$timeConsumed = microtime(true) - $start;
|
||||
if(!$avgTime)
|
||||
$avgTime = $timeConsumed;
|
||||
else
|
||||
$avgTime = ($avgTime + $timeConsumed) / 2;
|
||||
|
||||
$eta = $begin->getTimestamp() + ceil($totalPics * $avgTime);
|
||||
$int = (new \DateTimeImmutable("now"))->diff(new \DateTimeImmutable("@$eta"));
|
||||
$int = $int->d . "d" . $int->h . "h" . $int->i . "m" . $int->s . "s";
|
||||
$pct = floor(100 * ($count / $totalPics));
|
||||
|
||||
$counter->overwrite("Processed " . ++$count . " images... ($pct% $int left $errors/$count fail)");
|
||||
}
|
||||
|
||||
$counter->overwrite("Processing finished :3");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
35
README.md
35
README.md
|
@ -6,13 +6,13 @@ _[Русский](README_RU.md)_
|
|||
|
||||
VKontakte belongs to Pavel Durov and VK Group.
|
||||
|
||||
To be honest, we don't even know whether it even works. However, this version is maintained and we will be happy to accept your bugreports [in our bug-tracker](https://github.com/openvk/openvk/projects/1). You should also be able to submit them using [ticketing system](https://openvk.su/support?act=new) (you will need an OVK account for this).
|
||||
To be honest, we don't know whether it even works. However, this version is maintained and we will be happy to accept your bugreports [in our bug-tracker](https://github.com/openvk/openvk/projects/1). You should also be able to submit them using [ticketing system](https://openvk.su/support?act=new) (you will need an OVK account for this).
|
||||
|
||||
## When's the release?
|
||||
|
||||
Please use the master branch, as it has the most changes.
|
||||
|
||||
Updating the source code is done with this command: `git pull`
|
||||
We will release OpenVK as soon as it's ready. As for now you can:
|
||||
* `git clone` this repo's master branch (use `git pull` to update)
|
||||
* Grab a prebuilt OpenVK distro from [GitHub artifacts](https://github.com/openvk/archive/actions/workflows/nightly.yml)
|
||||
|
||||
## Instances
|
||||
|
||||
|
@ -24,7 +24,7 @@ Updating the source code is done with this command: `git pull`
|
|||
|
||||
Yes! And you're very welcome to.
|
||||
|
||||
However, OVK makes use of Chandler Application Server. This software requires extensions, that may not be provided by your hosting provider (namely, sodium and yaml. this extensions are available on most of ISPManager hostings).
|
||||
However, OVK makes use of Chandler Application Server. This software requires extensions, that may not be provided by your hosting provider (namely, sodium and yaml. these extensions are available on most of ISPManager hostings).
|
||||
|
||||
If you want, you can add your instance to the list above so that people can register there.
|
||||
|
||||
|
@ -32,7 +32,7 @@ If you want, you can add your instance to the list above so that people can regi
|
|||
|
||||
1. Install PHP 7.4, web-server, Composer, Node.js, Yarn and [Chandler](https://github.com/openvk/chandler)
|
||||
|
||||
* PHP 8 has **not** yet been tested, so you should not expect it to work.
|
||||
* PHP 8 has **not** yet been tested, so you should not expect it to work. (edit: it does not work).
|
||||
|
||||
2. Install [commitcaptcha](https://github.com/openvk/commitcaptcha) and OpenVK as Chandler extensions like this:
|
||||
|
||||
|
@ -48,26 +48,25 @@ ln -s /path/to/chandler/extensions/available/commitcaptcha /path/to/chandler/ext
|
|||
ln -s /path/to/chandler/extensions/available/openvk /path/to/chandler/extensions/enabled/
|
||||
```
|
||||
|
||||
4. Import `install/init-static-db.sql` to **same database** you installed Chandler to and import all sqls from `install/sqls` to **same database**
|
||||
5. Import `install/init-event-db.sql` to **separate database**
|
||||
6. Copy `openvk-example.yml` to `openvk.yml` and change options
|
||||
4. Import `install/init-static-db.sql` to the **same database** you installed Chandler to and import all sqls from `install/sqls` to the **same database**
|
||||
5. Import `install/init-event-db.sql` to a **separate database** (Yandex.Clickhouse can also be used, higly recommended)
|
||||
6. Copy `openvk-example.yml` to `openvk.yml` and change options to your liking
|
||||
7. Run `composer install` in OpenVK directory
|
||||
8. Move to `Web/static/js` and execute `yarn install`
|
||||
9. Set `openvk` as your root app in `chandler.yml`
|
||||
8. Run `composer install` in commitcaptcha directory
|
||||
9. Move to `Web/static/js` and execute `yarn install`
|
||||
10. Set `openvk` as your root app in `chandler.yml`
|
||||
|
||||
Once you are done, you can login as a system administrator on the network itself (no registration required):
|
||||
|
||||
* **Login**: `admin@localhost.localdomain6`
|
||||
* **Password**: `admin`
|
||||
* It is recommended to change the password before using the built-in account.
|
||||
* It is recommended to change the password of the built-in account or disable it.
|
||||
|
||||
Full example installation instruction for CentOS 8 is also available [here](https://docs.openvk.su/openvk_engine/centos8_installation/).
|
||||
💡Confused? Full installation walkthrough is available [here](https://docs.openvk.su/openvk_engine/centos8_installation/) (CentOS 8 [and](https://almalinux.org/) [family](https://yum.oracle.com/oracle-linux-isos.html)).
|
||||
|
||||
### If my website uses OpenVK, should I publish it's sources?
|
||||
### If my website uses OpenVK, should I release it's sources?
|
||||
|
||||
You are encouraged to do so. We don't enforce this though. You can keep your sources to yourself (unless you distribute your OpenVK distro to other people).
|
||||
|
||||
You also not required to publish source texts of your themepacks and plugins.
|
||||
It depends. You can keep the sources to yourself if you do not plan to distribute your website binaries. If your website software must be distributed, it can stay non-OSS provided the OpenVK is not used as a primary application and is not modified. If you modified OpenVK for your needs or your work is based on it and you're planning to redistribute this, then you should license it under terms of any LGPL-compatible license (like OSL, GPL, LGPL etc).
|
||||
|
||||
## Where can I get assistance?
|
||||
|
||||
|
@ -80,7 +79,7 @@ You may reach out to us via:
|
|||
* [Discussions](https://github.com/openvk/openvk/discussions)
|
||||
* Matrix chat: #openvk:matrix.org
|
||||
|
||||
**Attention**: bug tracker, telegram and matrix chat are public places. And ticketing system is being served by volunteers. If you need to report something, that shouldn't be immediately disclosed to general public (for instance, vulnerability report), please use contact us directly at this email: **openvk [at] tutanota [dot] com**
|
||||
**Attention**: bug tracker, board, telegram and matrix chat are public places. And ticketing system is being served by volunteers. If you need to report something, that shouldn't be immediately disclosed to general public (for instance, vulnerability report), please use contact us directly at this email: **openvk [at] tutanota [dot] com**
|
||||
|
||||
<a href="https://codeberg.org/OpenVK/openvk">
|
||||
<img alt="Get it on Codeberg" src="https://codeberg.org/Codeberg/GetItOnCodeberg/media/branch/main/get-it-on-blue-on-white.png" height="60">
|
||||
|
|
23
README_RU.md
23
README_RU.md
|
@ -10,9 +10,9 @@ _[English](README.md)_
|
|||
|
||||
## Когда релиз?
|
||||
|
||||
Пожалуйста, используйте ветку master, так как в ней больше всего изменений.
|
||||
|
||||
Обновление исходного кода выполняется с помощью этой команды: `git pull`.
|
||||
Мы выпустим OpenVK, как только он будет готов. На данный момент Вы можете:
|
||||
* Сделать `git clone` master ветки этой репозитории (используйте `git pull` для обновления)
|
||||
* Взять готовую сборку OpenVK из [GitHub Actions](https://github.com/openvk/archive/actions/workflows/nightly.yml)
|
||||
|
||||
## Инстанции
|
||||
|
||||
|
@ -32,7 +32,7 @@ _[English](README.md)_
|
|||
|
||||
1. Установите PHP 7.4, веб-сервер, Composer, Node.js, Yarn и [Chandler](https://github.com/openvk/chandler)
|
||||
|
||||
* PHP 8 еще **не** тестировался, поэтому не стоит ожидать, что он будет работать.
|
||||
* PHP 8 еще **не** тестировался, поэтому не стоит ожидать, что он будет работать (обновление: он не работает).
|
||||
|
||||
2. Установите [commitcaptcha](https://github.com/openvk/commitcaptcha) и OpenVK в качестве расширений Chandler следующим образом:
|
||||
|
||||
|
@ -49,11 +49,12 @@ ln -s /path/to/chandler/extensions/available/openvk /path/to/chandler/extensions
|
|||
```
|
||||
|
||||
4. Импортируйте `install/init-static-db.sql` в **ту же базу данных**, в которую вы установили Chandler, и импортируйте все SQL файлы из папки `install/sqls` в **ту же базу данных**
|
||||
5. Импортируйте `install/init-event-db.sql` в **отдельную базу данных**
|
||||
5. Импортируйте `install/init-event-db.sql` в **отдельную базу данных** (Яндекс.Clickhouse также может быть использован, настоятельно рекомендуется)
|
||||
6. Скопируйте `openvk-example.yml` в `openvk.yml` и измените параметры
|
||||
7. Запустите `composer install` в директории OpenVK
|
||||
8. Перейдите в `Web/static/js` и выполните `yarn install`
|
||||
9. Установите `openvk` в качестве корневого приложения в файле `chandler.yml`
|
||||
8. Запустите `composer install` в директории commitcaptcha
|
||||
9. Перейдите в `Web/static/js` и выполните `yarn install`
|
||||
10. Установите `openvk` в качестве корневого приложения в файле `chandler.yml`
|
||||
|
||||
После этого вы можете войти как системный администратор в саму сеть (регистрация не требуется):
|
||||
|
||||
|
@ -61,13 +62,11 @@ ln -s /path/to/chandler/extensions/available/openvk /path/to/chandler/extensions
|
|||
* **Пароль**: `admin`
|
||||
* Перед использованием встроенной учетной записи рекомендуется сменить пароль.
|
||||
|
||||
Полный пример инструкции по установке CentOS 8 также доступен [здесь](https://docs.openvk.su/openvk_engine/centos8_installation/).
|
||||
💡Запутались? Полное руководство по установке доступно [здесь](https://docs.openvk.su/openvk_engine/centos8_installation/) (CentOS 8 [и](https://almalinux.org/ru/) [семейство](https://yum.oracle.com/oracle-linux-isos.html)).
|
||||
|
||||
### Если мой сайт использует OpenVK, должен ли я публиковать его исходные тексты?
|
||||
|
||||
Вам рекомендуется это делать. Однако мы не следим за этим. Вы можете держать свои исходные тексты при себе (если только вы не распространяете свой дистрибутив OpenVK среди других людей).
|
||||
|
||||
Вы также не обязаны публиковать исходные тексты ваших тематических пакетов и плагинов.
|
||||
Это зависит от обстоятельств. Вы можете оставить исходные тексты при себе, если не планируете распространять бинарники вашего сайта. Если программное обеспечение вашего сайта должно распространяться, оно может оставаться не-OSS при условии, что OpenVK не используется в качестве основного приложения и не модифицируется. Если вы модифицировали OpenVK для своих нужд или ваша работа основана на нем и вы планируете ее распространять, то вы должны лицензировать ее на условиях любой совместимой с LGPL лицензии (например, OSL, GPL, LGPL и т.д.).
|
||||
|
||||
## Где я могу получить помощь?
|
||||
|
||||
|
@ -80,7 +79,7 @@ ln -s /path/to/chandler/extensions/available/openvk /path/to/chandler/extensions
|
|||
* [Обсуждения](https://github.com/openvk/openvk/discussions)
|
||||
* Чат в Matrix: #ovk:matrix.org
|
||||
|
||||
**Внимание**: баг-трекер, телеграм- и matrix-чат являются публичными местами, и жалобы в OVK обслуживается волонтерами. Если вам нужно сообщить о чем-то, что не должно быть раскрыто широкой публике (например, сообщение об уязвимости), пожалуйста, свяжитесь с нами напрямую по этому адресу: **openvk [собака] tutanota [точка] com**.
|
||||
**Внимание**: баг-трекер, форум, телеграм- и matrix-чат являются публичными местами, и жалобы в OVK обслуживается волонтерами. Если вам нужно сообщить о чем-то, что не должно быть раскрыто широкой публике (например, сообщение об уязвимости), пожалуйста, свяжитесь с нами напрямую по этому адресу: **openvk [собака] tutanota [точка] com**.
|
||||
|
||||
<a href="https://codeberg.org/OpenVK/openvk">
|
||||
<img alt="Получить на Codeberg" src="https://codeberg.org/Codeberg/GetItOnCodeberg/media/branch/main/get-it-on-blue-on-white.png" height="60">
|
||||
|
|
|
@ -60,7 +60,7 @@ final class Account extends VKAPIRequestHandler
|
|||
return 1;
|
||||
}
|
||||
|
||||
function getAppPermissions(): object
|
||||
function getAppPermissions(): int
|
||||
{
|
||||
return 9355263;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ final class Friends extends VKAPIRequestHandler
|
|||
$usersApi = new Users($this->getUser());
|
||||
|
||||
if (!is_null($fields)) {
|
||||
$response = $usersApi->get(implode(',', $friends), $fields, 0, $count, true); // FIXME
|
||||
$response = $usersApi->get(implode(',', $friends), $fields, 0, $count); // FIXME
|
||||
}
|
||||
|
||||
return (object) [
|
||||
|
|
74
VKAPI/Handlers/Likes.php
Normal file
74
VKAPI/Handlers/Likes.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\VKAPI\Handlers;
|
||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
||||
|
||||
final class Likes extends VKAPIRequestHandler
|
||||
{
|
||||
function add(string $type, int $owner_id, int $item_id): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
switch ($type) {
|
||||
case 'post':
|
||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
||||
if (is_null($post)) $this->fail(100, 'One of the parameters specified was missing or invalid: object not found');
|
||||
|
||||
$post->setLike(true, $this->getUser());
|
||||
return (object)[
|
||||
"likes" => $post->getLikesCount()
|
||||
];
|
||||
break;
|
||||
default:
|
||||
$this->fail(100, 'One of the parameters specified was missing or invalid: incorrect type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function remove(string $type, int $owner_id, int $item_id): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
switch ($type) {
|
||||
case 'post':
|
||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
||||
if (is_null($post)) $this->fail(100, 'One of the parameters specified was missing or invalid: object not found');
|
||||
|
||||
$post->setLike(false, $this->getUser());
|
||||
return (object)[
|
||||
"likes" => $post->getLikesCount()
|
||||
];
|
||||
break;
|
||||
default:
|
||||
$this->fail(100, 'One of the parameters specified was missing or invalid: incorrect type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function isLiked(int $user_id, string $type, int $owner_id, int $item_id): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
switch ($type) {
|
||||
case 'post':
|
||||
$user = (new UsersRepo)->get($user_id);
|
||||
if (is_null($user)) return (object)[
|
||||
"liked" => 0,
|
||||
"copied" => 0,
|
||||
"sex" => 0
|
||||
];
|
||||
|
||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
||||
if (is_null($post)) $this->fail(100, 'One of the parameters specified was missing or invalid: object not found');
|
||||
|
||||
return (object)[
|
||||
"liked" => (int) $post->hasLikeFrom($user),
|
||||
"copied" => 0 // TODO: handle this
|
||||
];
|
||||
break;
|
||||
default:
|
||||
$this->fail(100, 'One of the parameters specified was missing or invalid: incorrect type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ use openvk\Web\Events\NewMessageEvent;
|
|||
use openvk\Web\Models\Entities\{Correspondence, Message};
|
||||
use openvk\Web\Models\Repositories\{Messages as MSGRepo, Users as USRRepo};
|
||||
use openvk\VKAPI\Structures\{Message as APIMsg, Conversation as APIConvo};
|
||||
use openvk\VKAPI\Handlers\Users as APIUsers;
|
||||
use Chandler\Signaling\SignalManager;
|
||||
|
||||
final class Messages extends VKAPIRequestHandler
|
||||
|
@ -48,10 +49,12 @@ final class Messages extends VKAPIRequestHandler
|
|||
$rMsg->read_state = 1;
|
||||
$rMsg->out = (int) ($message->getSender()->getId() === $this->getUser()->getId());
|
||||
$rMsg->body = $message->getText(false);
|
||||
$rMsg->text = $message->getText(false);
|
||||
$rMsg->emoji = true;
|
||||
|
||||
if($preview_length > 0)
|
||||
$rMsg->body = ovk_proc_strtr($rMsg->body, $preview_length);
|
||||
$rMsg->text = ovk_proc_strtr($rMsg->text, $preview_length);
|
||||
|
||||
$items[] = $rMsg;
|
||||
}
|
||||
|
@ -145,12 +148,14 @@ final class Messages extends VKAPIRequestHandler
|
|||
return 1;
|
||||
}
|
||||
|
||||
function getConversations(int $offset = 0, int $count = 20, string $filter = "all", int $extended = 0): object
|
||||
function getConversations(int $offset = 0, int $count = 20, string $filter = "all", int $extended = 0, string $fields = ""): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
$convos = (new MSGRepo)->getCorrespondencies($this->getUser(), -1, $count, $offset);
|
||||
$list = [];
|
||||
|
||||
$users = [];
|
||||
foreach($convos as $convo) {
|
||||
$correspondents = $convo->getCorrespondents();
|
||||
if($correspondents[0]->getId() === $this->getUser()->getId())
|
||||
|
@ -189,7 +194,13 @@ final class Messages extends VKAPIRequestHandler
|
|||
$lastMessagePreview->read_state = 1;
|
||||
$lastMessagePreview->out = (int) ($lastMessage->getSender()->getId() === $this->getUser()->getId());
|
||||
$lastMessagePreview->body = $lastMessage->getText(false);
|
||||
$lastMessagePreview->text = $lastMessage->getText(false);
|
||||
$lastMessagePreview->emoji = true;
|
||||
|
||||
if($extended == 1) {
|
||||
$users[] = $lastMessage->getSender()->getId();
|
||||
$users[] = $author;
|
||||
}
|
||||
}
|
||||
|
||||
$list[] = [
|
||||
|
@ -198,10 +209,20 @@ final class Messages extends VKAPIRequestHandler
|
|||
];
|
||||
}
|
||||
|
||||
return (object) [
|
||||
"count" => sizeof($list),
|
||||
"items" => $list,
|
||||
];
|
||||
if($extended == 0){
|
||||
return (object) [
|
||||
"count" => sizeof($list),
|
||||
"items" => $list,
|
||||
];
|
||||
} else {
|
||||
$users = array_unique($users);
|
||||
|
||||
return (object) [
|
||||
"count" => sizeof($list),
|
||||
"items" => $list,
|
||||
"profiles" => (new APIUsers)->get(implode(',', $users), $fields, $offset, $count)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0): object
|
||||
|
@ -230,6 +251,7 @@ final class Messages extends VKAPIRequestHandler
|
|||
$rMsg->read_state = 1;
|
||||
$rMsg->out = (int) ($msgU->sender_id === $this->getUser()->getId());
|
||||
$rMsg->body = $message->getText(false);
|
||||
$rMsg->text = $message->getText(false);
|
||||
$rMsg->emoji = true;
|
||||
|
||||
$results[] = $rMsg;
|
||||
|
|
230
VKAPI/Handlers/Photos.php
Normal file
230
VKAPI/Handlers/Photos.php
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\VKAPI\Handlers;
|
||||
|
||||
use Nette\InvalidStateException;
|
||||
use Nette\Utils\ImageException;
|
||||
use openvk\Web\Models\Entities\Photo;
|
||||
use openvk\Web\Models\Repositories\Albums;
|
||||
use openvk\Web\Models\Repositories\Clubs;
|
||||
|
||||
final class Photos extends VKAPIRequestHandler
|
||||
{
|
||||
private function getPhotoUploadUrl(string $field, int $group = 0, bool $multifile = false): string
|
||||
{
|
||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||
$uploadInfo = [
|
||||
1,
|
||||
$field,
|
||||
(int) $multifile,
|
||||
0,
|
||||
time(),
|
||||
$this->getUser()->getId(),
|
||||
$group,
|
||||
0, # this is unused but stays here base64 reasons (X2 doesn't work, so there's dummy value for short)
|
||||
];
|
||||
$uploadInfo = pack("vZ10v2P3S", ...$uploadInfo);
|
||||
$uploadInfo = base64_encode($uploadInfo);
|
||||
$uploadHash = hash_hmac("sha3-224", $uploadInfo, $secret);
|
||||
$uploadInfo = rawurlencode($uploadInfo);
|
||||
|
||||
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/upload/photo/$uploadHash?$uploadInfo";
|
||||
}
|
||||
|
||||
private function getImagePath(string $photo, string $hash, ?string& $up = NULL, ?string& $group = NULL): string
|
||||
{
|
||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||
if(!hash_equals(hash_hmac("sha3-224", $photo, $secret), $hash))
|
||||
$this->fail(121, "Incorrect hash");
|
||||
|
||||
[$up, $image, $group] = explode("|", $photo);
|
||||
|
||||
$imagePath = __DIR__ . "/../../tmp/api-storage/photos/$up" . "_$image.oct";
|
||||
if(!file_exists($imagePath))
|
||||
$this->fail(10, "Invalid image");
|
||||
|
||||
return $imagePath;
|
||||
}
|
||||
|
||||
function getOwnerPhotoUploadServer(int $owner_id = 0): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
if($owner_id < 0) {
|
||||
$club = (new Clubs)->get(abs($owner_id));
|
||||
if(!$club)
|
||||
$this->fail(0404, "Club not found");
|
||||
else if(!$club->canBeModifiedBy($this->getUser()))
|
||||
$this->fail(200, "Access: Club can't be 'written' by user");
|
||||
}
|
||||
|
||||
return (object) [
|
||||
"upload_url" => $this->getPhotoUploadUrl("photo", isset($club) ? 0 : $club->getId()),
|
||||
];
|
||||
}
|
||||
|
||||
function saveOwnerPhoto(string $photo, string $hash): object
|
||||
{
|
||||
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
||||
if($group == 0) {
|
||||
$user = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader);
|
||||
$album = (new Albums)->getUserAvatarAlbum($user);
|
||||
} else {
|
||||
$club = (new Clubs)->get((int) $group);
|
||||
$album = (new Albums)->getClubAvatarAlbum($club);
|
||||
}
|
||||
|
||||
try {
|
||||
$avatar = new Photo;
|
||||
$avatar->setOwner((int) $uploader);
|
||||
$avatar->setDescription("Profile photo");
|
||||
$avatar->setCreated(time());
|
||||
$avatar->setFile([
|
||||
"tmp_name" => $imagePath,
|
||||
"error" => 0,
|
||||
]);
|
||||
$avatar->save();
|
||||
$album->addPhoto($avatar);
|
||||
unlink($imagePath);
|
||||
} catch(ImageException | InvalidStateException $e) {
|
||||
unlink($imagePath);
|
||||
$this->fail(129, "Invalid image file");
|
||||
}
|
||||
|
||||
return (object) [
|
||||
"photo_hash" => NULL,
|
||||
"photo_src" => $avatar->getURL(),
|
||||
];
|
||||
}
|
||||
|
||||
function getWallUploadServer(?int $group_id = NULL): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
$album = NULL;
|
||||
if(!is_null($group_id)) {
|
||||
$club = (new Clubs)->get(abs($group_id));
|
||||
if(!$club)
|
||||
$this->fail(0404, "Club not found");
|
||||
else if(!$club->canBeModifiedBy($this->getUser()))
|
||||
$this->fail(200, "Access: Club can't be 'written' by user");
|
||||
} else {
|
||||
$album = (new Albums)->getUserWallAlbum($this->getUser());
|
||||
}
|
||||
|
||||
return (object) [
|
||||
"upload_url" => $this->getPhotoUploadUrl("photo", $group_id ?? 0),
|
||||
"album_id" => $album,
|
||||
"user_id" => $this->getUser()->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
function saveWallPhoto(string $photo, string $hash, int $group_id = 0, ?string $caption = NULL): array
|
||||
{
|
||||
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
||||
if($group_id != $group)
|
||||
$this->fail(8, "group_id doesn't match");
|
||||
|
||||
$album = NULL;
|
||||
if($group_id != 0) {
|
||||
$uploader = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader);
|
||||
$album = (new Albums)->getUserWallAlbum($uploader);
|
||||
}
|
||||
|
||||
try {
|
||||
$photo = new Photo;
|
||||
$photo->setOwner((int) $uploader);
|
||||
$photo->setCreated(time());
|
||||
$photo->setFile([
|
||||
"tmp_name" => $imagePath,
|
||||
"error" => 0,
|
||||
]);
|
||||
|
||||
if (!is_null($caption))
|
||||
$photo->setDescription($caption);
|
||||
|
||||
$photo->save();
|
||||
unlink($imagePath);
|
||||
} catch(ImageException | InvalidStateException $e) {
|
||||
unlink($imagePath);
|
||||
$this->fail(129, "Invalid image file");
|
||||
}
|
||||
|
||||
if(!is_null($album))
|
||||
$album->addPhoto($photo);
|
||||
|
||||
return [
|
||||
$photo->toVkApiStruct(),
|
||||
];
|
||||
}
|
||||
|
||||
function getUploadServer(?int $album_id = NULL): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
# Not checking rights to album because save() method will do so anyways
|
||||
return (object) [
|
||||
"upload_url" => $this->getPhotoUploadUrl("photo", 0, true),
|
||||
"album_id" => $album_id,
|
||||
"user_id" => $this->getUser()->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
function save(string $photos_list, string $hash, int $album_id = 0, ?string $caption = NULL): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||
if(!hash_equals(hash_hmac("sha3-224", $photos_list, $secret), $hash))
|
||||
$this->fail(121, "Incorrect hash");
|
||||
|
||||
$album = NULL;
|
||||
if($album_id != 0) {
|
||||
$album_ = (new Albums)->get($album_id);
|
||||
if(!$album_)
|
||||
$this->fail(0404, "Invalid album");
|
||||
else if(!$album_->canBeModifiedBy($this->getUser()))
|
||||
$this->fail(15, "Access: Album can't be 'written' by user");
|
||||
|
||||
$album = $album_;
|
||||
}
|
||||
|
||||
$pList = json_decode($photos_list);
|
||||
$imagePaths = [];
|
||||
foreach($pList as $pDesc)
|
||||
$imagePaths[] = __DIR__ . "/../../tmp/api-storage/photos/$pDesc->keyholder" . "_$pDesc->resource.oct";
|
||||
|
||||
$images = [];
|
||||
try {
|
||||
foreach($imagePaths as $imagePath) {
|
||||
$photo = new Photo;
|
||||
$photo->setOwner($this->getUser()->getId());
|
||||
$photo->setCreated(time());
|
||||
$photo->setFile([
|
||||
"tmp_name" => $imagePath,
|
||||
"error" => 0,
|
||||
]);
|
||||
|
||||
if (!is_null($caption))
|
||||
$photo->setDescription($caption);
|
||||
|
||||
$photo->save();
|
||||
unlink($imagePath);
|
||||
|
||||
if(!is_null($album))
|
||||
$album->addPhoto($photo);
|
||||
|
||||
$images[] = $photo->toVkApiStruct();
|
||||
}
|
||||
} catch(ImageException | InvalidStateException $e) {
|
||||
foreach($imagePaths as $imagePath)
|
||||
unlink($imagePath);
|
||||
|
||||
$this->fail(129, "Invalid image file");
|
||||
}
|
||||
|
||||
return (object) [
|
||||
"count" => sizeof($images),
|
||||
"items" => $images,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -5,13 +5,15 @@ use openvk\Web\Models\Repositories\Users as UsersRepo;
|
|||
|
||||
final class Users extends VKAPIRequestHandler
|
||||
{
|
||||
function get(string $user_ids = "0", string $fields = "", int $offset = 0, int $count = 100): array
|
||||
function get(string $user_ids = "0", string $fields = "", int $offset = 0, int $count = 100, User $authuser = null /* костыль(( */): array
|
||||
{
|
||||
$this->requireUser();
|
||||
// $this->requireUser();
|
||||
|
||||
if($authuser == null) $authuser = $this->getUser();
|
||||
|
||||
$users = new UsersRepo;
|
||||
if($user_ids == "0")
|
||||
$user_ids = (string) $this->getUser()->getId();
|
||||
$user_ids = (string) $authuser->getId();
|
||||
|
||||
$usrs = explode(',', $user_ids);
|
||||
$response;
|
||||
|
@ -51,7 +53,7 @@ final class Users extends VKAPIRequestHandler
|
|||
$response[$i]->verified = intval($usr->isVerified());
|
||||
break;
|
||||
case 'sex':
|
||||
$response[$i]->sex = $this->getUser()->isFemale() ? 1 : 2;
|
||||
$response[$i]->sex = $usr->isFemale() ? 1 : 2;
|
||||
break;
|
||||
case 'has_photo':
|
||||
$response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1;
|
||||
|
@ -71,10 +73,10 @@ final class Users extends VKAPIRequestHandler
|
|||
$response[$i]->screen_name = $usr->getShortCode();
|
||||
break;
|
||||
case 'friend_status':
|
||||
switch($usr->getSubscriptionStatus($this->getUser())) {
|
||||
switch($usr->getSubscriptionStatus($authuser)) {
|
||||
case 3:
|
||||
case 0:
|
||||
$response[$i]->friend_status = $usr->getSubscriptionStatus($this->getUser());
|
||||
$response[$i]->friend_status = $usr->getSubscriptionStatus($authuser);
|
||||
break;
|
||||
case 1:
|
||||
$response[$i]->friend_status = 2;
|
||||
|
@ -158,13 +160,14 @@ final class Users extends VKAPIRequestHandler
|
|||
$users = new UsersRepo;
|
||||
|
||||
$array = [];
|
||||
$find = $users->find($q);
|
||||
|
||||
foreach ($users->find($q) as $user) {
|
||||
foreach ($find as $user) {
|
||||
$array[] = $user->getId();
|
||||
}
|
||||
|
||||
return (object)[
|
||||
"count" => $users->getFoundCount($q),
|
||||
"count" => $find->size(),
|
||||
"items" => $this->get(implode(',', $array), $fields, $offset, $count)
|
||||
];
|
||||
}
|
||||
|
|
|
@ -22,6 +22,32 @@ final class Wall extends VKAPIRequestHandler
|
|||
|
||||
foreach ($posts->getPostsFromUsersWall((int)$owner_id, 1, $count, $offset) as $post) {
|
||||
$from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId();
|
||||
|
||||
$attachments;
|
||||
foreach($post->getChildren() as $attachment)
|
||||
{
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo)
|
||||
{
|
||||
$attachments[] = [
|
||||
"type" => "photo",
|
||||
"photo" => [
|
||||
"album_id" => $attachment->getAlbum() ? $attachment->getAlbum()->getId() : null,
|
||||
"date" => $attachment->getPublicationTime()->timestamp(),
|
||||
"id" => $attachment->getVirtualId(),
|
||||
"owner_id" => $attachment->getOwner()->getId(),
|
||||
"sizes" => array([
|
||||
"height" => 500, // Для временного компросима оставляю статическое число. Если каждый раз обращаться к файлу за количеством пикселов, то наступает пuпuська полная с производительностью, так что пока так
|
||||
"url" => $attachment->getURL(),
|
||||
"type" => "m",
|
||||
"width" => 500,
|
||||
]),
|
||||
"text" => "",
|
||||
"has_tags" => false
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$items[] = (object)[
|
||||
"id" => $post->getVirtualId(),
|
||||
"from_id" => $from_id,
|
||||
|
@ -35,6 +61,7 @@ final class Wall extends VKAPIRequestHandler
|
|||
"can_archive" => false, // TODO MAYBE
|
||||
"is_archived" => false,
|
||||
"is_pinned" => $post->isPinned(),
|
||||
"attachments" => $attachments,
|
||||
"post_source" => (object)["type" => "vk"],
|
||||
"comments" => (object)[
|
||||
"count" => $post->getCommentsCount(),
|
||||
|
@ -56,6 +83,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
$profiles[] = $from_id;
|
||||
else
|
||||
$groups[] = $from_id * -1;
|
||||
|
||||
$attachments = null; // free attachments so it will not clone everythingg
|
||||
}
|
||||
|
||||
if($extended == 1)
|
||||
|
@ -127,6 +156,31 @@ final class Wall extends VKAPIRequestHandler
|
|||
$post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1]));
|
||||
if($post) {
|
||||
$from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId();
|
||||
$attachments;
|
||||
foreach($post->getChildren() as $attachment)
|
||||
{
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo)
|
||||
{
|
||||
$attachments[] = [
|
||||
"type" => "photo",
|
||||
"photo" => [
|
||||
"album_id" => $attachment->getAlbum() ? $attachment->getAlbum()->getId() : null,
|
||||
"date" => $attachment->getPublicationTime()->timestamp(),
|
||||
"id" => $attachment->getVirtualId(),
|
||||
"owner_id" => $attachment->getOwner()->getId(),
|
||||
"sizes" => array([
|
||||
"height" => 500, // я ещё я заебался вставлять одинаковый код в два разных места
|
||||
"url" => $attachment->getURL(),
|
||||
"type" => "m",
|
||||
"width" => 500,
|
||||
]),
|
||||
"text" => "",
|
||||
"has_tags" => false
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$items[] = (object)[
|
||||
"id" => $post->getVirtualId(),
|
||||
"from_id" => $from_id,
|
||||
|
@ -141,6 +195,7 @@ final class Wall extends VKAPIRequestHandler
|
|||
"is_archived" => false,
|
||||
"is_pinned" => $post->isPinned(),
|
||||
"post_source" => (object)["type" => "vk"],
|
||||
"attachments" => $attachments,
|
||||
"comments" => (object)[
|
||||
"count" => $post->getCommentsCount(),
|
||||
"can_post" => 1
|
||||
|
@ -161,6 +216,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
$profiles[] = $from_id;
|
||||
else
|
||||
$groups[] = $from_id * -1;
|
||||
|
||||
$attachments = null; // free attachments so it will not clone everythingg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,11 @@ final class Message
|
|||
public $out;
|
||||
public $title = "";
|
||||
public $body;
|
||||
public $text;
|
||||
public $attachments = [];
|
||||
public $fwd_messages = [];
|
||||
public $emoji;
|
||||
public $important = 1;
|
||||
public $important = true;
|
||||
public $deleted = 0;
|
||||
public $random_id = NULL;
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ class Club extends RowModel
|
|||
return iterator_to_array($avPhotos)[0] ?? NULL;
|
||||
}
|
||||
|
||||
function getAvatarUrl(): string
|
||||
function getAvatarUrl(string $size = "miniscule"): string
|
||||
{
|
||||
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||
$avPhoto = $this->getAvatarPhoto();
|
||||
|
||||
return is_null($avPhoto) ? "$serverUrl/assets/packages/static/openvk/img/camera_200.png" : $avPhoto->getURL();
|
||||
return is_null($avPhoto) ? "$serverUrl/assets/packages/static/openvk/img/camera_200.png" : $avPhoto->getURLBySizeId($size);
|
||||
}
|
||||
|
||||
function getAvatarLink(): string
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Entities;
|
||||
use MessagePack\MessagePack;
|
||||
use openvk\Web\Models\Entities\Album;
|
||||
use openvk\Web\Models\Repositories\Albums;
|
||||
use Chandler\Database\DatabaseConnection as DB;
|
||||
use Nette\InvalidStateException as ISE;
|
||||
use Nette\Utils\Image;
|
||||
|
@ -8,21 +11,83 @@ class Photo extends Media
|
|||
{
|
||||
protected $tableName = "photos";
|
||||
protected $fileExtension = "jpeg";
|
||||
|
||||
|
||||
const ALLOWED_SIDE_MULTIPLIER = 7;
|
||||
|
||||
|
||||
private function resizeImage(string $filename, string $outputDir, \SimpleXMLElement $size): array
|
||||
{
|
||||
$res = [false];
|
||||
$image = Image::fromFile($filename);
|
||||
$requiresProportion = ((string) $size["requireProp"]) != "none";
|
||||
if($requiresProportion) {
|
||||
$props = explode(":", (string) $size["requireProp"]);
|
||||
$px = (int) $props[0];
|
||||
$py = (int) $props[1];
|
||||
if(($image->getWidth() / $image->getHeight()) > ($px / $py)) {
|
||||
# For some weird reason using resize with EXACT flag causes system to consume an unholy amount of RAM
|
||||
$image->crop(0, 0, "100%", (int) ceil(($px * $image->getWidth()) / $py));
|
||||
$res[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($size["maxSize"])) {
|
||||
$maxSize = (int) $size["maxSize"];
|
||||
$image->resize($maxSize, $maxSize, Image::SHRINK_ONLY | Image::FIT);
|
||||
} else if(isset($size["maxResolution"])) {
|
||||
$resolution = explode("x", (string) $size["maxResolution"]);
|
||||
$image->resize((int) $resolution[0], (int) $resolution[1], Image::SHRINK_ONLY | Image::FIT);
|
||||
} else {
|
||||
throw new \RuntimeException("Malformed size description: " . (string) $size["id"]);
|
||||
}
|
||||
|
||||
$res[1] = $image->getWidth();
|
||||
$res[2] = $image->getHeight();
|
||||
if($res[1] <= 300 || $res[2] <= 300)
|
||||
$image->save("$outputDir/" . (string) $size["id"] . ".gif");
|
||||
else
|
||||
$image->save("$outputDir/" . (string) $size["id"] . ".jpeg");
|
||||
|
||||
imagedestroy($image->getImageResource());
|
||||
unset($image);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function saveImageResizedCopies(string $filename, string $hash): void
|
||||
{
|
||||
$dir = dirname($this->pathFromHash($hash));
|
||||
$dir = "$dir/$hash" . "_cropped";
|
||||
if(!is_dir($dir)) {
|
||||
@unlink($dir); # Added to transparently bypass issues with dead pesudofolders summoned by buggy SWIFT impls (selectel)
|
||||
mkdir($dir);
|
||||
}
|
||||
|
||||
$sizes = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
||||
if(!$sizes)
|
||||
throw new \RuntimeException("Could not load photosizes.xml!");
|
||||
|
||||
$sizesMeta = [];
|
||||
foreach($sizes->Size as $size)
|
||||
$sizesMeta[(string) $size["id"]] = $this->resizeImage($filename, $dir, $size);
|
||||
|
||||
$sizesMeta = MessagePack::pack($sizesMeta);
|
||||
$this->stateChanges("sizes", $sizesMeta);
|
||||
}
|
||||
|
||||
protected function saveFile(string $filename, string $hash): bool
|
||||
{
|
||||
$image = Image::fromFile($filename);
|
||||
if(($image->height >= ($image->width * Photo::ALLOWED_SIDE_MULTIPLIER)) || ($image->width >= ($image->height * Photo::ALLOWED_SIDE_MULTIPLIER)))
|
||||
throw new ISE("Invalid layout: image is too wide/short");
|
||||
|
||||
|
||||
$image->resize(8192, 4320, Image::SHRINK_ONLY | Image::FIT);
|
||||
$image->save($this->pathFromHash($hash), 92, Image::JPEG);
|
||||
$this->saveImageResizedCopies($filename, $hash);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function crop(real $left, real $top, real $width, real $height): bool
|
||||
function crop(real $left, real $top, real $width, real $height): void
|
||||
{
|
||||
if(isset($this->changes["hash"]))
|
||||
$hash = $this->changes["hash"];
|
||||
|
@ -33,7 +98,7 @@ class Photo extends Media
|
|||
|
||||
$image = Image::fromFile($this->pathFromHash($hash));
|
||||
$image->crop($left, $top, $width, $height);
|
||||
return $image->save($this->pathFromHash($hash));
|
||||
$image->save($this->pathFromHash($hash));
|
||||
}
|
||||
|
||||
function isolate(): void
|
||||
|
@ -43,7 +108,128 @@ class Photo extends Media
|
|||
|
||||
DB::i()->getContext()->table("album_relations")->where("media", $this->getRecord()->id)->delete();
|
||||
}
|
||||
|
||||
|
||||
function getSizes(bool $upgrade = false, bool $forceUpdate = false): ?array
|
||||
{
|
||||
$sizes = $this->getRecord()->sizes;
|
||||
if(!$sizes || $forceUpdate) {
|
||||
if($forceUpdate || $upgrade || OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["upgradeStructure"]) {
|
||||
$hash = $this->getRecord()->hash;
|
||||
$this->saveImageResizedCopies($this->pathFromHash($hash), $hash);
|
||||
$this->save();
|
||||
|
||||
return $this->getSizes();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$res = [];
|
||||
$sizes = MessagePack::unpack($sizes);
|
||||
foreach($sizes as $id => $meta) {
|
||||
$url = $this->getURL();
|
||||
$url = str_replace(".$this->fileExtension", "_cropped/$id.", $url);
|
||||
$url .= ($meta[1] <= 300 || $meta[2] <= 300) ? "gif" : "jpeg";
|
||||
|
||||
$res[$id] = (object) [
|
||||
"url" => $url,
|
||||
"width" => $meta[1],
|
||||
"height" => $meta[2],
|
||||
"crop" => $meta[0]
|
||||
];
|
||||
}
|
||||
|
||||
[$x, $y] = $this->getDimensions();
|
||||
$res["UPLOADED_MAXRES"] = (object) [
|
||||
"url" => $this->getURL(),
|
||||
"width" => $x,
|
||||
"height" => $y,
|
||||
"crop" => false
|
||||
];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
function getVkApiSizes(): ?array
|
||||
{
|
||||
$res = [];
|
||||
$sizes = $this->getSizes();
|
||||
if(!$sizes)
|
||||
return NULL;
|
||||
|
||||
$manifest = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
||||
if(!$manifest)
|
||||
return NULL;
|
||||
|
||||
$mappings = [];
|
||||
foreach($manifest->Size as $size)
|
||||
$mappings[(string) $size["id"]] = (string) $size["vkId"];
|
||||
|
||||
foreach($sizes as $id => $meta)
|
||||
$res[$mappings[$id] ?? $id] = $meta;
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
function getURLBySizeId(string $size): string
|
||||
{
|
||||
$sizes = $this->getSizes();
|
||||
if(!$sizes)
|
||||
return $this->getURL();
|
||||
|
||||
$size = $sizes[$size];
|
||||
if(!$size)
|
||||
return $this->getURL();
|
||||
|
||||
return $size->url;
|
||||
}
|
||||
|
||||
function getDimensions(): array
|
||||
{
|
||||
$x = $this->getRecord()->width;
|
||||
$y = $this->getRecord()->height;
|
||||
if(!$x) { # no sizes in database
|
||||
$hash = $this->getRecord()->hash;
|
||||
$image = Image::fromFile($this->pathFromHash($hash));
|
||||
|
||||
$x = $image->getWidth();
|
||||
$y = $image->getHeight();
|
||||
$this->stateChanges("width", $x);
|
||||
$this->stateChanges("height", $y);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return [$x, $y];
|
||||
}
|
||||
|
||||
function getAlbum(): ?Album
|
||||
{
|
||||
return (new Albums)->getAlbumByPhotoId($this);
|
||||
}
|
||||
|
||||
function toVkApiStruct(): object
|
||||
{
|
||||
$res = (object) [];
|
||||
|
||||
$res->id = $res->pid = $this->getId();
|
||||
$res->owner_id = $res->user_id = $this->getOwner()->getId()->getId();
|
||||
$res->aid = $res->album_id = NULL;
|
||||
$res->width = $this->getDimensions()[0];
|
||||
$res->height = $this->getDimensions()[1];
|
||||
$res->date = $res->created = $this->getPublicationTime()->timestamp();
|
||||
|
||||
$res->sizes = $this->getVkApiSizes();
|
||||
$res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule");
|
||||
$res->src = $res->photo_130 = $this->getURLBySizeId("tiny");
|
||||
$res->src_big = $res->photo_604 = $this->getURLBySizeId("normal");
|
||||
$res->src_xbig = $res->photo_807 = $this->getURLBySizeId("large");
|
||||
$res->src_xxbig = $res->photo_1280 = $this->getURLBySizeId("larger");
|
||||
$res->src_xxxbig = $res->photo_2560 = $this->getURLBySizeId("original");
|
||||
$res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES");
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
static function fastMake(int $owner, string $description = "", array $file, ?Album $album = NULL, bool $anon = false): Photo
|
||||
{
|
||||
$photo = new static;
|
||||
|
@ -53,10 +239,10 @@ class Photo extends Media
|
|||
$photo->setCreated(time());
|
||||
$photo->setFile($file);
|
||||
$photo->save();
|
||||
|
||||
|
||||
if(!is_null($album))
|
||||
$album->addPhoto($photo);
|
||||
|
||||
|
||||
return $photo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@ class User extends RowModel
|
|||
const NSFW_TOLERANT = 1;
|
||||
const NSFW_FULL_TOLERANT = 2;
|
||||
|
||||
protected function _abstractRelationGenerator(string $filename, int $page = 1): \Traversable
|
||||
protected function _abstractRelationGenerator(string $filename, int $page = 1, int $limit = 6): \Traversable
|
||||
{
|
||||
$id = $this->getId();
|
||||
$query = "SELECT id FROM\n" . file_get_contents(__DIR__ . "/../sql/$filename.tsql");
|
||||
$query .= "\n LIMIT 6 OFFSET " . ( ($page - 1) * 6 );
|
||||
$query .= "\n LIMIT " . $limit . " OFFSET " . ( ($page - 1) * $limit );
|
||||
|
||||
$rels = DatabaseConnection::i()->getConnection()->query($query, $id, $id);
|
||||
foreach($rels as $rel) {
|
||||
|
@ -102,7 +102,7 @@ class User extends RowModel
|
|||
return "/id" . $this->getId();
|
||||
}
|
||||
|
||||
function getAvatarUrl(): string
|
||||
function getAvatarUrl(string $size = "miniscule"): string
|
||||
{
|
||||
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||
|
||||
|
@ -115,7 +115,7 @@ class User extends RowModel
|
|||
if(is_null($avPhoto))
|
||||
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
|
||||
else
|
||||
return $avPhoto->getURL();
|
||||
return $avPhoto->getURLBySizeId($size);
|
||||
}
|
||||
|
||||
function getAvatarLink(): string
|
||||
|
@ -214,6 +214,11 @@ class User extends RowModel
|
|||
{
|
||||
return $this->getRecord()->block_reason;
|
||||
}
|
||||
|
||||
function getBanInSupportReason(): ?string
|
||||
{
|
||||
return $this->getRecord()->block_in_support_reason;
|
||||
}
|
||||
|
||||
function getType(): int
|
||||
{
|
||||
|
@ -438,9 +443,9 @@ class User extends RowModel
|
|||
];
|
||||
}
|
||||
|
||||
function getFriends(int $page = 1): \Traversable
|
||||
function getFriends(int $page = 1, int $limit = 6): \Traversable
|
||||
{
|
||||
return $this->_abstractRelationGenerator("get-friends", $page);
|
||||
return $this->_abstractRelationGenerator("get-friends", $page, $limit);
|
||||
}
|
||||
|
||||
function getFriendsCount(): int
|
||||
|
@ -448,9 +453,9 @@ class User extends RowModel
|
|||
return $this->_abstractRelationCount("get-friends");
|
||||
}
|
||||
|
||||
function getFollowers(int $page = 1): \Traversable
|
||||
function getFollowers(int $page = 1, int $limit = 6): \Traversable
|
||||
{
|
||||
return $this->_abstractRelationGenerator("get-followers", $page);
|
||||
return $this->_abstractRelationGenerator("get-followers", $page, $limit);
|
||||
}
|
||||
|
||||
function getFollowersCount(): int
|
||||
|
@ -458,9 +463,9 @@ class User extends RowModel
|
|||
return $this->_abstractRelationCount("get-followers");
|
||||
}
|
||||
|
||||
function getSubscriptions(int $page = 1): \Traversable
|
||||
function getSubscriptions(int $page = 1, int $limit = 6): \Traversable
|
||||
{
|
||||
return $this->_abstractRelationGenerator("get-subscriptions-user", $page);
|
||||
return $this->_abstractRelationGenerator("get-subscriptions-user", $page, $limit);
|
||||
}
|
||||
|
||||
function getSubscriptionsCount(): int
|
||||
|
@ -673,6 +678,11 @@ class User extends RowModel
|
|||
{
|
||||
return !is_null($this->getBanReason());
|
||||
}
|
||||
|
||||
function isBannedInSupport(): bool
|
||||
{
|
||||
return !is_null($this->getBanInSupportReason());
|
||||
}
|
||||
|
||||
function isOnline(): bool
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Repositories;
|
||||
use openvk\Web\Models\Entities\Album;
|
||||
use openvk\Web\Models\Entities\Photo;
|
||||
use openvk\Web\Models\Entities\Club;
|
||||
use openvk\Web\Models\Entities\User;
|
||||
use Nette\Database\Table\ActiveRow;
|
||||
|
@ -115,4 +116,11 @@ class Albums
|
|||
|
||||
return new Album($album);
|
||||
}
|
||||
|
||||
function getAlbumByPhotoId(Photo $photo): ?Album
|
||||
{
|
||||
$dbalbum = $this->context->table("album_relations")->where(["media" => $photo->getId()])->fetch();
|
||||
|
||||
return $dbalbum->collection ? $this->get($dbalbum->collection) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,6 @@ class Posts
|
|||
{
|
||||
$post = $this->posts->where(['wall' => $wall, 'virtual_id' => $post])->fetch();
|
||||
if(!is_null($post))
|
||||
|
||||
return new Post($post);
|
||||
else
|
||||
return null;
|
||||
|
|
|
@ -39,7 +39,7 @@ class Users
|
|||
function find(string $query): Util\EntityStream
|
||||
{
|
||||
$query = "%$query%";
|
||||
$result = $this->users->where("CONCAT_WS(' ', first_name, last_name, pseudo) LIKE ?", $query)->where("deleted", 0);
|
||||
$result = $this->users->where("CONCAT_WS(' ', first_name, last_name, pseudo, shortcode) LIKE ?", $query)->where("deleted", 0);
|
||||
|
||||
return new Util\EntityStream("User", $result);
|
||||
}
|
||||
|
|
|
@ -346,7 +346,20 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->ban($this->queryParam("reason"));
|
||||
exit(json_encode([ "reason" => $this->queryParam("reason") ]));
|
||||
exit(json_encode([ "success" => true, "reason" => $this->queryParam("reason") ]));
|
||||
}
|
||||
|
||||
function renderQuickUnban(int $id): void
|
||||
{
|
||||
$this->assertNoCSRF();
|
||||
|
||||
$user = $this->users->get($id);
|
||||
if(!$user)
|
||||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->setBlock_Reason(null);
|
||||
$user->save();
|
||||
exit(json_encode([ "success" => true ]));
|
||||
}
|
||||
|
||||
function renderQuickWarn(int $id): void
|
||||
|
|
|
@ -4,6 +4,7 @@ use openvk\Web\Models\Entities\IP;
|
|||
use openvk\Web\Models\Entities\User;
|
||||
use openvk\Web\Models\Entities\PasswordReset;
|
||||
use openvk\Web\Models\Entities\EmailVerification;
|
||||
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
||||
use openvk\Web\Models\Repositories\IPs;
|
||||
use openvk\Web\Models\Repositories\Users;
|
||||
use openvk\Web\Models\Repositories\Restores;
|
||||
|
@ -88,20 +89,25 @@ final class AuthPresenter extends OpenVKPresenter
|
|||
if (strtotime($this->postParam("birthday")) > time())
|
||||
$this->flashFail("err", tr("invalid_birth_date"), tr("invalid_birth_date_comment"));
|
||||
|
||||
try {
|
||||
$user = new User;
|
||||
$user->setFirst_Name($this->postParam("first_name"));
|
||||
$user->setLast_Name($this->postParam("last_name"));
|
||||
$user->setSex((int)($this->postParam("sex") === "female"));
|
||||
$user->setEmail($this->postParam("email"));
|
||||
$user->setSince(date("Y-m-d H:i:s"));
|
||||
$user->setRegistering_Ip(CONNECTING_IP);
|
||||
$user->setBirthday(strtotime($this->postParam("birthday")));
|
||||
$user->setActivated((int)!OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']);
|
||||
} catch(InvalidUserNameException $ex) {
|
||||
$this->flashFail("err", tr("error"), tr("invalid_real_name"));
|
||||
}
|
||||
|
||||
$chUser = ChandlerUser::create($this->postParam("email"), $this->postParam("password"));
|
||||
if(!$chUser)
|
||||
$this->flashFail("err", tr("failed_to_register"), tr("user_already_exists"));
|
||||
|
||||
$user = new User;
|
||||
|
||||
$user->setUser($chUser->getId());
|
||||
$user->setFirst_Name($this->postParam("first_name"));
|
||||
$user->setLast_Name($this->postParam("last_name"));
|
||||
$user->setSex((int) ($this->postParam("sex") === "female"));
|
||||
$user->setEmail($this->postParam("email"));
|
||||
$user->setSince(date("Y-m-d H:i:s"));
|
||||
$user->setRegistering_Ip(CONNECTING_IP);
|
||||
$user->setBirthday(strtotime($this->postParam("birthday")));
|
||||
$user->setActivated((int) !OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']);
|
||||
$user->save();
|
||||
|
||||
if(!is_null($referer)) {
|
||||
|
|
|
@ -204,6 +204,8 @@ abstract class OpenVKPresenter extends SimplePresenter
|
|||
$this->template->isXmas = intval(date('d')) >= 1 && date('m') == 12 || intval(date('d')) <= 15 && date('m') == 1 ? true : false;
|
||||
$this->template->isTimezoned = Session::i()->get("_timezoneOffset");
|
||||
|
||||
$userValidated = 0;
|
||||
$cacheTime = OPENVK_ROOT_CONF["openvk"]["preferences"]["nginxCacheTime"] ?? 0;
|
||||
if(!is_null($user)) {
|
||||
$this->user = (object) [];
|
||||
$this->user->raw = $user;
|
||||
|
@ -261,6 +263,8 @@ abstract class OpenVKPresenter extends SimplePresenter
|
|||
exit;
|
||||
}
|
||||
|
||||
$userValidated = 1;
|
||||
$cacheTime = 0; # Force no cache
|
||||
if ($this->user->identity->onlineStatus() == 0) {
|
||||
$this->user->identity->setOnline(time());
|
||||
$this->user->identity->save();
|
||||
|
@ -273,6 +277,8 @@ abstract class OpenVKPresenter extends SimplePresenter
|
|||
}
|
||||
}
|
||||
|
||||
header("X-OpenVK-User-Validated: $userValidated");
|
||||
header("X-Accel-Expires: $cacheTime");
|
||||
setlocale(LC_TIME, ...(explode(";", tr("__locale"))));
|
||||
|
||||
parent::onStartup();
|
||||
|
|
|
@ -276,6 +276,8 @@ final class PhotosPresenter extends OpenVKPresenter
|
|||
|
||||
$photo->isolate();
|
||||
$photo->delete();
|
||||
exit("Фотография успешно удалена!");
|
||||
|
||||
$this->flash("succ", "Фотография удалена", "Эта фотография была успешно удалена.");
|
||||
$this->redirect("/id0", static::REDIRECT_TEMPORARY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ final class SearchPresenter extends OpenVKPresenter
|
|||
$type = $this->queryParam("type") ?? "users";
|
||||
$page = (int) ($this->queryParam("p") ?? 1);
|
||||
|
||||
$this->willExecuteWriteAction();
|
||||
if($query != "")
|
||||
$this->assertUserLoggedIn();
|
||||
|
||||
// https://youtu.be/pSAWM5YuXx8
|
||||
|
||||
$repos = [ "groups" => "clubs", "users" => "users" ];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
use openvk\Web\Models\Entities\Ticket;
|
||||
use openvk\Web\Models\Repositories\Tickets;
|
||||
use openvk\Web\Models\Repositories\{Tickets, Users};
|
||||
use openvk\Web\Models\Entities\TicketComment;
|
||||
use openvk\Web\Models\Repositories\TicketComments;
|
||||
use openvk\Web\Util\Telegram;
|
||||
|
@ -34,7 +34,13 @@ final class SupportPresenter extends OpenVKPresenter
|
|||
$this->template->tickets = $this->tickets->getTicketsByUserId($this->user->id, $this->template->page);
|
||||
}
|
||||
|
||||
if($this->template->mode === "new")
|
||||
$this->template->banReason = $this->user->identity->getBanInSupportReason();
|
||||
|
||||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
if($this->user->identity->isBannedInSupport())
|
||||
$this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment"));
|
||||
|
||||
if(!empty($this->postParam("name")) && !empty($this->postParam("text"))) {
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
|
@ -268,4 +274,32 @@ final class SupportPresenter extends OpenVKPresenter
|
|||
|
||||
exit(header("HTTP/1.1 200 OK"));
|
||||
}
|
||||
}
|
||||
|
||||
function renderQuickBanInSupport(int $id): void
|
||||
{
|
||||
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);
|
||||
$this->assertNoCSRF();
|
||||
|
||||
$user = (new Users)->get($id);
|
||||
if(!$user)
|
||||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->setBlock_In_Support_Reason($this->queryParam("reason"));
|
||||
$user->save();
|
||||
$this->returnJson([ "success" => true, "reason" => $this->queryParam("reason") ]);
|
||||
}
|
||||
|
||||
function renderQuickUnbanInSupport(int $id): void
|
||||
{
|
||||
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);
|
||||
$this->assertNoCSRF();
|
||||
|
||||
$user = (new Users)->get($id);
|
||||
if(!$user)
|
||||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->setBlock_In_Support_Reason(null);
|
||||
$user->save();
|
||||
$this->returnJson([ "success" => true ]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,7 +285,6 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$photo->setCreated(time());
|
||||
$photo->save();
|
||||
} catch(ISE $ex) {
|
||||
$name = $album->getName();
|
||||
$this->flashFail("err", tr("error"), tr("error_upload_failed"));
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,92 @@ final class VKAPIPresenter extends OpenVKPresenter
|
|||
exit; # Terminate request processing as this is definitely a CORS preflight request.
|
||||
}
|
||||
}
|
||||
|
||||
function renderPhotoUpload(string $signature): void
|
||||
{
|
||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||
$computedSignature = hash_hmac("sha3-224", $_SERVER["QUERY_STRING"], $secret);
|
||||
if(!(strlen($signature) == 56 && sodium_memcmp($signature, $computedSignature) == 0)) {
|
||||
header("HTTP/1.1 422 Unprocessable Entity");
|
||||
exit("Try harder <3");
|
||||
}
|
||||
|
||||
$data = unpack("vDOMAIN/Z10FIELD/vMF/vMP/PTIME/PUSER/PGROUP", base64_decode($_SERVER["QUERY_STRING"]));
|
||||
if((time() - $data["TIME"]) > 600) {
|
||||
header("HTTP/1.1 422 Unprocessable Entity");
|
||||
exit("Expired");
|
||||
}
|
||||
|
||||
$folder = __DIR__ . "../../tmp/api-storage/photos";
|
||||
$maxSize = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["api"]["maxFileSize"];
|
||||
$maxFiles = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["api"]["maxFilesPerDomain"];
|
||||
$usrFiles = sizeof(glob("$folder/$data[USER]_*.oct"));
|
||||
if($usrFiles >= $maxFiles) {
|
||||
header("HTTP/1.1 507 Insufficient Storage");
|
||||
exit("There are $maxFiles pending already. Please save them before uploading more :3");
|
||||
}
|
||||
|
||||
# Not multifile
|
||||
if($data["MF"] === 0) {
|
||||
$file = $_FILES[$data["FIELD"]];
|
||||
if(!$file) {
|
||||
header("HTTP/1.0 400");
|
||||
exit("No file");
|
||||
} else if($file["error"] != UPLOAD_ERR_OK) {
|
||||
header("HTTP/1.0 500");
|
||||
exit("File could not be consumed");
|
||||
} else if($file["size"] > $maxSize) {
|
||||
header("HTTP/1.0 507 Insufficient Storage");
|
||||
exit("File is too big");
|
||||
}
|
||||
|
||||
move_uploaded_file($file["tmp_name"], "$folder/$data[USER]_" . ($usrFiles + 1) . ".oct");
|
||||
header("HTTP/1.0 202 Accepted");
|
||||
|
||||
$photo = $data["USER"] . "|" . ($usrFiles + 1) . "|" . $data["GROUP"];
|
||||
exit(json_encode([
|
||||
"server" => "ephemeral",
|
||||
"photo" => $photo,
|
||||
"hash" => hash_hmac("sha3-224", $photo, $secret),
|
||||
]));
|
||||
}
|
||||
|
||||
$files = [];
|
||||
for($i = 1; $i <= 5; $i++) {
|
||||
$file = $_FILES[$data["FIELD"] . $i] ?? NULL;
|
||||
if (!$file || $file["error"] != UPLOAD_ERR_OK || $file["size"] > $maxSize) {
|
||||
continue;
|
||||
} else if((sizeof($files) + $usrFiles) > $maxFiles) {
|
||||
# Clear uploaded files since they can't be saved anyway
|
||||
foreach($files as $f)
|
||||
unlink($f);
|
||||
|
||||
header("HTTP/1.1 507 Insufficient Storage");
|
||||
exit("There are $maxFiles pending already. Please save them before uploading more :3");
|
||||
}
|
||||
|
||||
$files[++$usrFiles] = move_uploaded_file($file["tmp_name"], "$folder/$data[USER]_$usrFiles.oct");
|
||||
}
|
||||
|
||||
if(sizeof($files) === 0) {
|
||||
header("HTTP/1.0 400");
|
||||
exit("No file");
|
||||
}
|
||||
|
||||
$filesManifest = [];
|
||||
foreach($files as $id => $file)
|
||||
$filesManifest[] = ["keyholder" => $data["USER"], "resource" => $id, "club" => $data["GROUP"]];
|
||||
|
||||
$filesManifest = json_encode($filesManifest);
|
||||
$manifestHash = hash_hmac("sha3-224", $filesManifest, $secret);
|
||||
header("HTTP/1.0 202 Accepted");
|
||||
exit(json_encode([
|
||||
"server" => "ephemeral",
|
||||
"photos_list" => $filesManifest,
|
||||
"album_id" => "undefined",
|
||||
"hash" => $manifestHash,
|
||||
]));
|
||||
}
|
||||
|
||||
function renderRoute(string $object, string $method): void
|
||||
{
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<div n:if="isset($thisUser) ? (!$thisUser->isBanned() XOR !$thisUser->isActivated()) : true" class="header_navigation">
|
||||
{ifset $thisUser}
|
||||
<div class="link">
|
||||
<a href="/">{_header_home}</a>
|
||||
<a href="/" title="[Alt+Shift+,]" accesskey=",">{_header_home}</a>
|
||||
</div>
|
||||
<div class="link">
|
||||
<a href="/search?type=groups">{_header_groups}</a>
|
||||
|
@ -122,7 +122,7 @@
|
|||
</div>
|
||||
<div class="link">
|
||||
<form action="/search" method="get">
|
||||
<input type="search" name="query" placeholder="{_header_search}" style="height: 20px;background: url('/assets/packages/static/openvk/img/search_icon.png') no-repeat 3px 4px; background-color: #fff; padding-left: 18px;width: 120px;" />
|
||||
<input type="search" name="query" placeholder="{_header_search}" style="height: 20px;background: url('/assets/packages/static/openvk/img/search_icon.png') no-repeat 3px 4px; background-color: #fff; padding-left: 18px;width: 120px;" title="{_header_search} [Alt+Shift+F]" accesskey="f" />
|
||||
</form>
|
||||
</div>
|
||||
{else}
|
||||
|
@ -144,7 +144,7 @@
|
|||
{ifset $thisUser}
|
||||
{if !$thisUser->isBanned() XOR !$thisUser->isActivated()}
|
||||
<a href="/edit" class="link edit-button">{_edit_button}</a>
|
||||
<a href="{$thisUser->getURL()}" class="link">{_my_page}</a>
|
||||
<a href="{$thisUser->getURL()}" class="link" title="{_my_page} [Alt+Shift+.]" accesskey=".">{_my_page}</a>
|
||||
<a href="/friends{$thisUser->getId()}" class="link">{_my_friends}
|
||||
<object type="internal/link" n:if="$thisUser->getFollowersCount() > 0">
|
||||
<a href="/friends{$thisUser->getId()}?act=incoming">
|
||||
|
@ -161,8 +161,8 @@
|
|||
</a>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('notes')" href="/notes{$thisUser->getId()}" class="link">{_my_notes}</a>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('groups')" href="/groups{$thisUser->getId()}" class="link">{_my_groups}</a>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('news')" href="/feed" class="link">{_my_feed}</a>
|
||||
<a href="/notifications" class="link">{_my_feedback}
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('news')" href="/feed" class="link" title="{_my_feed} [Alt+Shift+W]" accesskey="w">{_my_feed}</a>
|
||||
<a href="/notifications" class="link" title="{_my_feedback} [Alt+Shift+N]" accesskey="n">{_my_feedback}
|
||||
{if $thisUser->getNotificationsCount() > 0}
|
||||
(<b>{$thisUser->getNotificationsCount()}</b>)
|
||||
{/if}
|
||||
|
@ -173,7 +173,7 @@
|
|||
{var canAccessHelpdesk = $thisUser->getChandlerUser()->can("write")->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)}
|
||||
{var menuLinksAvaiable = sizeof(OPENVK_ROOT_CONF['openvk']['preferences']['menu']['links']) > 0 && $thisUser->getLeftMenuItemStatus('links')}
|
||||
<div n:if="$canAccessAdminPanel || $canAccessHelpdesk || $menuLinksAvaiable" class="menu_divider"></div>
|
||||
<a href="/admin" class="link" n:if="$canAccessAdminPanel">Админ-панель</a>
|
||||
<a href="/admin" class="link" n:if="$canAccessAdminPanel" title="Админ-панель [Alt+Shift+A]" accesskey="a">Админ-панель</a>
|
||||
<a href="/support/tickets" class="link" n:if="$canAccessHelpdesk">Helpdesk
|
||||
{if $helpdeskTicketNotAnsweredCount > 0}
|
||||
(<b>{$helpdeskTicketNotAnsweredCount}</b>)
|
||||
|
@ -293,6 +293,37 @@
|
|||
{/if}
|
||||
|
||||
<script n:if="OPENVK_ROOT_CONF['openvk']['telemetry']['plausible']['enable']" async defer data-domain="{php echo OPENVK_ROOT_CONF['openvk']['telemetry']['plausible']['domain']}" src="{php echo OPENVK_ROOT_CONF['openvk']['telemetry']['plausible']['server']}js/plausible.js"></script>
|
||||
|
||||
<script n:if="OPENVK_ROOT_CONF['openvk']['telemetry']['piwik']['enable']">
|
||||
{var $piwik = (object) OPENVK_ROOT_CONF['openvk']['telemetry']['piwik']}
|
||||
|
||||
//<![CDATA[
|
||||
(function(window,document,dataLayerName,id){
|
||||
window[dataLayerName]=window[dataLayerName]||[],window[dataLayerName].push({ start:(new Date).getTime(),event:"stg.start" });var scripts=document.getElementsByTagName('script')[0],tags=document.createElement('script');
|
||||
function stgCreateCookie(a,b,c){ var d="";if(c){ var e=new Date;e.setTime(e.getTime()+24*c*60*60*1e3),d=";expires="+e.toUTCString() }document.cookie=a+"="+b+d+";path=/" }
|
||||
var isStgDebug=(window.location.href.match("stg_debug")||document.cookie.match("stg_debug"))&&!window.location.href.match("stg_disable_debug");stgCreateCookie("stg_debug",isStgDebug?1:"",isStgDebug?14:-1);
|
||||
var qP=[];dataLayerName!=="dataLayer"&&qP.push("data_layer_name="+dataLayerName),isStgDebug&&qP.push("stg_debug");var qPString=qP.length>0?("?"+qP.join("&")):"";
|
||||
tags.async=!0,tags.src={$piwik->container . "/"}+id+".js"+qPString,scripts.parentNode.insertBefore(tags,scripts);
|
||||
!function(a,n,i){ a[n]=a[n]||{ };for(var c=0;c<i.length;c++)!function(i){ a[n][i]=a[n][i]||{ },a[n][i].api=a[n][i].api||function(){ var a=[].slice.call(arguments,0);"string"==typeof a[0]&&window[dataLayerName].push({ event:n+"."+i+":"+a[0],parameters:[].slice.call(arguments,1) }) } }(i[c]) }(window,"ppms",["tm","cm"]);
|
||||
})(window,document,{$piwik->layer}, {$piwik->site});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<script n:if="OPENVK_ROOT_CONF['openvk']['telemetry']['matomo']['enable']">
|
||||
{var $matomo = (object) OPENVK_ROOT_CONF['openvk']['telemetry']['matomo']}
|
||||
//<![CDATA[
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//" + {$matomo->container} + "/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', {$matomo->site}]);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
{ifset bodyScripts}
|
||||
{include bodyScripts}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</label>
|
||||
<span id="avatar" class="aui-avatar aui-avatar-project aui-avatar-xlarge">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$club->getAvatarUrl()}" style="object-fit: cover;"></img>
|
||||
<img src="{$club->getAvatarUrl('tiny')}" style="object-fit: cover;"></img>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -155,7 +155,7 @@
|
|||
<td>
|
||||
<span class="aui-avatar aui-avatar-xsmall">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$follower->getAvatarUrl()}" alt="{$follower->getCanonicalName()}" role="presentation" />
|
||||
<img src="{$follower->getAvatarUrl('miniscule')}" alt="{$follower->getCanonicalName()}" role="presentation" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
@ -188,4 +188,4 @@
|
|||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
{/block}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<td>
|
||||
<span class="aui-avatar aui-avatar-xsmall">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$club->getAvatarUrl()}" alt="{$club->getCanonicalName()}" style="object-fit: cover;" role="presentation" />
|
||||
<img src="{$club->getAvatarUrl('miniscule')}" alt="{$club->getCanonicalName()}" style="object-fit: cover;" role="presentation" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
<span class="aui-avatar aui-avatar-xsmall">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$user->getAvatarUrl()}" alt="{$user->getCanonicalName()}" role="presentation" />
|
||||
<img src="{$user->getAvatarUrl('miniscule')}" alt="{$user->getCanonicalName()}" role="presentation" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</label>
|
||||
<span id="avatar" class="aui-avatar aui-avatar-project aui-avatar-xlarge">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$user->getAvatarUrl()}" style="object-fit: cover;"></img>
|
||||
<img src="{$user->getAvatarUrl('tiny')}" style="object-fit: cover;"></img>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<td>
|
||||
<span class="aui-avatar aui-avatar-xsmall">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$user->getAvatarUrl()}" alt="{$user->getCanonicalName()}" style="object-fit: cover;" role="presentation" />
|
||||
<img src="{$user->getAvatarUrl('miniscule')}" alt="{$user->getCanonicalName()}" style="object-fit: cover;" role="presentation" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<td>
|
||||
<span class="aui-avatar aui-avatar-xsmall">
|
||||
<span class="aui-avatar-inner">
|
||||
<img src="{$user->getAvatarUrl()}" alt="{$user->getCanonicalName()}" role="presentation" />
|
||||
<img src="{$user->getAvatarUrl('miniscule')}" alt="{$user->getCanonicalName()}" role="presentation" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<span>{_code}: </span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="code" required />
|
||||
<input type="text" name="code" autocomplete="off" required />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x instanceof $Manager ? $x->getUser()->getAvatarURL() : $x->getAvatarURL()}" alt="{$x instanceof $Manager ? $x->getUser()->getCanonicalName() : $x->getCanonicalName()}" width=75 />
|
||||
<img src="{$x instanceof $Manager ? $x->getUser()->getAvatarURL() : $x->getAvatarURL('miniscule')}" alt="{$x instanceof $Manager ? $x->getUser()->getCanonicalName() : $x->getCanonicalName()}" width=75 />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
|
@ -140,4 +140,4 @@
|
|||
</a>
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
||||
{/block}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<div class="cl_element" n:foreach="$club->getFollowers(1) as $follower">
|
||||
<div class="cl_avatar">
|
||||
<a href="{$follower->getURL()}">
|
||||
<img class="ava" src="{$follower->getAvatarUrl()}" />
|
||||
<img class="ava" src="{$follower->getAvatarUrl('miniscule')}" />
|
||||
</a>
|
||||
</div>
|
||||
<a href="{$follower->getURL()}" class="cl_name">
|
||||
|
@ -94,7 +94,7 @@
|
|||
{var avatarPhoto = $club->getAvatarPhoto()}
|
||||
{var avatarLink = ((is_null($avatarPhoto) ? FALSE : $avatarPhoto->isAnonymous()) ? "/photo" . ("s/" . base_convert((string) $avatarPhoto->getId(), 10, 32)) : $club->getAvatarLink())}
|
||||
<a href="{$avatarLink|nocheck}">
|
||||
<img src="{$club->getAvatarUrl()}" style="width: 100%; image-rendering: -webkit-optimize-contrast;" />
|
||||
<img src="{$club->getAvatarUrl('normal')}" style="width: 100%; image-rendering: -webkit-optimize-contrast;" />
|
||||
</a>
|
||||
<div n:ifset="$thisUser" id="profile_links">
|
||||
{if $club->canBeModifiedBy($thisUser)}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</div>
|
||||
<div class="messenger-app--input">
|
||||
{if $correspondent->getId() === $thisUser->getId() || $correspondent->getPrivacyPermission('messages.write', $thisUser)}
|
||||
<img class="ava" src="{$thisUser->getAvatarUrl()}" alt="{$thisUser->getCanonicalName()}" />
|
||||
<img class="ava" src="{$thisUser->getAvatarUrl('miniscule')}" alt="{$thisUser->getCanonicalName()}" />
|
||||
<div class="messenger-app--input---messagebox">
|
||||
<textarea
|
||||
data-bind="value: messageContent, event: { keydown: onTextareaKeyPress }"
|
||||
|
@ -52,7 +52,7 @@
|
|||
placeholder="Введите сообщение"></textarea>
|
||||
<button class="button" data-bind="click: sendMessage">Отправить</button>
|
||||
</div>
|
||||
<img class="ava" src="{$correspondent->getAvatarUrl()}" alt="{$correspondent->getCanonicalName()}" />
|
||||
<img class="ava" src="{$correspondent->getAvatarUrl('miniscule')}" alt="{$correspondent->getCanonicalName()}" />
|
||||
{else}
|
||||
<div class="blocked" data-localized-text="Вы не можете писать сообщения {$correspondent->getCanonicalName()} из-за его настроек приватности."></div>
|
||||
{/if}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
{var lastMsg = $coresp->getPreviewMessage()}
|
||||
|
||||
<div class="crp-entry--image">
|
||||
<img src="{$recipient->getAvatarURL()}"
|
||||
<img src="{$recipient->getAvatarURL('miniscule')}"
|
||||
alt="Фотография пользователя" />
|
||||
</div>
|
||||
<div class="crp-entry--info">
|
||||
|
@ -36,7 +36,7 @@
|
|||
{var _author = $lastMsg->getSender()}
|
||||
|
||||
<div class="crp-entry--message---av" n:if="$_author->getId() === $thisUser->getId()">
|
||||
<img src="{$_author->getAvatarURL()}"
|
||||
<img src="{$_author->getAvatarURL('miniscule')}"
|
||||
alt="Фотография пользователя" />
|
||||
</div>
|
||||
<div class="crp-entry--message---text">
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
<div n:foreach="$data as $dat">
|
||||
<div class="profile_thumb">
|
||||
<a href="{$owner->getURL()}">
|
||||
<img src="{$owner->getAvatarUrl()}" style="width: 50px;">
|
||||
<img src="{$owner->getAvatarUrl('miniscule')}" style="width: 50px;">
|
||||
</a>
|
||||
</div>
|
||||
<article class="note_body" id="userContent" style="width: 540px; display: inline-block; margin-bottom: 35px;">
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getModel(1)->getAvatarUrl()}" width=64 />
|
||||
<img src="{$x->getModel(1)->getAvatarUrl('miniscule')}" width=64 />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
|
|
|
@ -23,9 +23,11 @@
|
|||
{else}
|
||||
{tr("albums", $count)}
|
||||
{/if}
|
||||
<span n:if="isset($thisUser) && $thisUser->getId() == $owner->getId()">
|
||||
|
||||
<span n:if="$canEdit" style="float: right;">
|
||||
|
|
||||
<a href="/albums/create">{_create_album}</a>
|
||||
{var isClub = ($owner instanceof \openvk\Web\Models\Entities\Club)}
|
||||
<a href="/albums/create{$isClub ? '?gpid=' . $owner->getId() : ''}">{_create_album}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -43,7 +45,7 @@
|
|||
|
||||
{block preview}
|
||||
{var cover = $x->getCoverPhoto()}
|
||||
{var preview = is_null($cover) ? "/assets/packages/static/openvk/img/camera_200.png" : $cover->getURL()}
|
||||
{var preview = is_null($cover) ? "/assets/packages/static/openvk/img/camera_200.png" : $cover->getURLBySizeId("normal")}
|
||||
|
||||
<a href="/album{$x->getPrettyId()}">
|
||||
<img src="{$preview}" alt="{$x->getName()}" style="height: 130px; width: 170px; object-fit: cover" />
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
{block content}
|
||||
<center style="margin-bottom: 8pt;">
|
||||
<img src="{$photo->getURL()}" style="max-width: 80%; max-height: 60vh;" />
|
||||
<img src="{$photo->getURLBySizeId('large')}" style="max-width: 80%; max-height: 60vh;" />
|
||||
</center>
|
||||
|
||||
<hr/>
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getAvatarUrl()}" width="75" alt="{_"photo"}" />
|
||||
<img src="{$x->getAvatarUrl('miniscule')}" width="75" alt="{_"photo"}" />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<tr>
|
||||
{if $comment->getUType() === 0}
|
||||
<td width="54" valign="top">
|
||||
<img src="{$comment->getUser()->getAvatarUrl()}" width="50" />
|
||||
<img src="{$comment->getUser()->getAvatarUrl('miniscule')}" width="50" />
|
||||
</td>
|
||||
{else}
|
||||
<td width="54" valign="top">
|
||||
|
|
|
@ -26,16 +26,26 @@
|
|||
<br />
|
||||
|
||||
{if $isNew}
|
||||
<div class="new">
|
||||
<form action="/support" method="post" style="margin:0;">
|
||||
<center>
|
||||
<input name="name" style="width: 80%; resize: vertical;" placeholder="{_support_new_title}" /><br /><br />
|
||||
<textarea name="text" style="width: 80%; resize: vertical;" placeholder="{_support_new_content}"></textarea><br /><br />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" value="{_write}" class="button" style="margin-left: 70%;" /><br /><br />
|
||||
</center>
|
||||
</form>
|
||||
</div>
|
||||
{if !is_null($banReason)}
|
||||
<center>
|
||||
<img src="/assets/packages/static/openvk/img/oof.apng" alt="{_'banned_alt'}" style="width: 20%;" />
|
||||
</center>
|
||||
<p>
|
||||
{tr("banned_in_support_1", htmlentities($thisUser->getCanonicalName()))|noescape}<br/>
|
||||
{tr("banned_in_support_2", htmlentities($banReason))|noescape}
|
||||
</p>
|
||||
{else}
|
||||
<div class="new">
|
||||
<form action="/support" method="post" style="margin:0;">
|
||||
<center>
|
||||
<input name="name" style="width: 80%; resize: vertical;" placeholder="{_support_new_title}" /><br /><br />
|
||||
<textarea name="text" style="width: 80%; resize: vertical;" placeholder="{_support_new_content}"></textarea><br /><br />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" value="{_write}" class="button" style="margin-left: 70%;" /><br /><br />
|
||||
</center>
|
||||
</form>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
<tr>
|
||||
{if $comment->getUType() === 0}
|
||||
<td width="54" valign="top">
|
||||
<img src="{$comment->getUser()->getAvatarUrl()}" width="50" />
|
||||
<img src="{$comment->getUser()->getAvatarUrl('miniscule')}" width="50" />
|
||||
</td>
|
||||
{else}
|
||||
<td width="54" valign="top">
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getAvatarUrl()}" width="75" alt="Фотография группы" />
|
||||
<img src="{$x->getAvatarUrl('miniscule')}" width="75" alt="Фотография пользователя" />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
|
@ -145,4 +145,4 @@
|
|||
</form>
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
||||
{/block}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getAvatarUrl()}" width="75" alt="Фотография группы" />
|
||||
<img src="{$x->getAvatarUrl('miniscule')}" width="75" alt="Фотография группы" />
|
||||
{/block}
|
||||
|
||||
{block name}{/block}
|
||||
|
|
|
@ -347,16 +347,22 @@
|
|||
<center>{tr("also_you_can_transfer_points", $thisUser->getCoins(), rawurlencode($csrfToken))|noescape}</center>
|
||||
</div>
|
||||
<div style="width: 22%; float: right;">
|
||||
<p style="margin: 0; font-size: medium; text-align: center;">
|
||||
<b>
|
||||
{_on_your_account}<br/>
|
||||
<span style="font-size: 50px;">{$thisUser->getCoins()}</span><br/>
|
||||
{_points_count}<br/><br/>
|
||||
<small><a href="?act=finance.top-up">[{_have_voucher}?]</a></small>
|
||||
</b>
|
||||
<div style="margin: 0; font-size: medium; text-align: center; font-weight: 900;">
|
||||
{_on_your_account}
|
||||
<div style="width: 100%; height: 60px; font-weight: 100;" id="balance">{$thisUser->getCoins()}</div>
|
||||
{_points_count}<br/>
|
||||
<small><a href="?act=finance.top-up">[{_have_voucher}?]</a></small>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{script "js/node_modules/textfit/textFit.min.js"}
|
||||
<script>
|
||||
let balance = document.querySelector("#balance");
|
||||
|
||||
balance.style.width = Math.ceil(balance.parentNode.getBoundingClientRect().width) + "px";
|
||||
textFit(balance, { alignVert: true });
|
||||
</script>
|
||||
|
||||
{elseif $isFinanceTU}
|
||||
|
||||
<p>{_voucher_explanation} {_voucher_explanation_ex}</p>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<!-- openGraph -->
|
||||
<meta property="og:title" content="{$user->getCanonicalName()}" />
|
||||
<meta property="og:url" content="http://{$_SERVER['HTTP_HOST']}{$user->getURL()}" />
|
||||
<meta property="og:image" content="{$user->getAvatarUrl()}" />
|
||||
<meta property="og:image" content="{$user->getAvatarUrl('normal')}" />
|
||||
<meta property="og:type" content="profile" />
|
||||
<meta property="og:first_name" content="{$user->getFirstName()}" />
|
||||
<meta property="og:last_name" content="{$user->getLastName()}" />
|
||||
|
@ -62,7 +62,7 @@
|
|||
<div class="left_small_block">
|
||||
<div>
|
||||
<a href="{$user->getAvatarLink()|nocheck}">
|
||||
<img src="{$user->getAvatarUrl()}"
|
||||
<img src="{$user->getAvatarUrl('normal')}"
|
||||
alt="{$user->getCanonicalName()}"
|
||||
style="width: 100%; image-rendering: -webkit-optimize-contrast;" />
|
||||
</a>
|
||||
|
@ -72,7 +72,7 @@
|
|||
<div id="profile_link" style="width: 194px;">
|
||||
<a href="/edit" class="link">{_"edit_page"}</a>
|
||||
</div>
|
||||
<div n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce']" id="profile_link" style="width: 194px;">
|
||||
<div n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && !$thisUser->prefersNotToSeeRating()" id="profile_link" style="width: 194px;">
|
||||
<a onClick="showIncreaseRatingDialog({$thisUser->getCoins()}, {ltrim($thisUser->getUrl(), '/')}, {$csrfToken})" class="link">{_increase_rating}</a>
|
||||
</div>
|
||||
{else}
|
||||
|
@ -93,6 +93,16 @@
|
|||
{_warn_user_action}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
{if $thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)}
|
||||
<a href="javascript:toggleBanInSupport()" class="profile_link">
|
||||
{if $user->isBannedInSupport()}
|
||||
{_unban_in_support_user_action}
|
||||
{else}
|
||||
{_ban_in_support_user_action}
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
<a n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && $user->getGiftCount() == 0" href="/gifts?act=pick&user={$user->getId()}" class="profile_link">{_send_gift}</a>
|
||||
<a n:if="$user->getPrivacyPermission('messages.write', $thisUser)" href="/im?sel={$user->getId()}" class="profile_link">{_"send_message"}</a>
|
||||
|
@ -180,7 +190,7 @@
|
|||
<div class="cl_element" n:foreach="$user->getFriends(1) as $friend">
|
||||
<div class="cl_avatar">
|
||||
<a href="{$friend->getURL()}">
|
||||
<img class="ava" src="{$friend->getAvatarUrl()}" />
|
||||
<img class="ava" src="{$friend->getAvatarUrl('miniscule')}" />
|
||||
</a>
|
||||
</div>
|
||||
<a href="{$friend->getURL()}" class="cl_name">
|
||||
|
@ -208,7 +218,7 @@
|
|||
{var cover = $album->getCoverPhoto()}
|
||||
|
||||
<img
|
||||
src="{is_null($cover)?'/assets/packages/static/openvk/img/camera_200.png':$cover->getURL()}"
|
||||
src="{is_null($cover)?'/assets/packages/static/openvk/img/camera_200.png':$cover->getURLBySizeId('small')}"
|
||||
style="max-width: 80px; max-height: 54pt;" />
|
||||
</div>
|
||||
<div style="overflow: hidden; overflow-wrap: break-word;">
|
||||
|
@ -512,7 +522,7 @@
|
|||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/ban/" + {$user->getId()} + "?reason=" + res + "&hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("reason") === -1)
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось забанить пользователя...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь заблокирован", ["OK"], [Function.noop]);
|
||||
|
@ -526,7 +536,7 @@
|
|||
function warnUser() {
|
||||
uBanMsgTxt = "Вы собираетесь предупредить пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/>Мы отправим уведомление пользователю в личные сообщения от имени аккаунта администратора.";
|
||||
uBanMsgTxt += "<br/><br/><b>Текст предупреждения</b>: <input type='text' id='uWarnMsgInput' placeholder='придумайте что-нибудь крутое' />"
|
||||
uBanMsgTxt += "<br/><br/><b>Текст предупреждения</b>: <input type='text' id='uWarnMsgInput' placeholder='придумайте что-нибудь крутое' />";
|
||||
|
||||
MessageBox("Выдать предупреждение " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
|
@ -546,6 +556,51 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<script n:if="isset($thisUser) && $thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)">
|
||||
{if $user->isBannedInSupport()}
|
||||
function toggleBanInSupport() {
|
||||
uBanMsgTxt = "Вы собираетесь разблокировать в поддержке пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/>Сейчас он заблокирован по причине <strong>" + {$user->getBanInSupportReason()} + "</strong>.";
|
||||
|
||||
MessageBox("Разблокировать в поддержке " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/support/unban/" + {$user->getId()} + "?hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось разблокировать пользователя в поддержке...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь разблокирован в поддержке", ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
{else}
|
||||
function toggleBanInSupport() {
|
||||
uBanMsgTxt = "Вы собираетесь заблокировать в поддержке пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/><br/><b>Причина бана</b>: <input type='text' id='uBanMsgInput' placeholder='придумайте что-нибудь крутое' />";
|
||||
|
||||
MessageBox("Заблокировать в поддержке " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
res = document.querySelector("#uBanMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/support/ban/" + {$user->getId()} + "?reason=" + res + "&hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось заблокировать пользователя в поддержке...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь заблокирован в поддержке", ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
{/if}
|
||||
</script>
|
||||
|
||||
<script n:if="isset($thisUser) && $user->getId() == $thisUser->getId()" n:syntax="off">
|
||||
function setStatusEditorShown(shown) {
|
||||
document.getElementById("status_editor").style.display = shown ? "block" : "none";
|
||||
|
|
|
@ -4,4 +4,82 @@
|
|||
{tr("user_banned", htmlentities($user->getFirstName()))|noescape}<br/>
|
||||
{_"user_banned_comment"} <b>{$user->getBanReason()}</b>.
|
||||
</p>
|
||||
<p n:if="isset($thisUser) && $thisUser->getChandlerUser()->can('access')->model('admin')->whichBelongsTo(NULL) || $thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)">
|
||||
<br />
|
||||
<a n:if="$thisUser->getChandlerUser()->can('access')->model('admin')->whichBelongsTo(NULL)" href="javascript:unbanUser()" class="button">{_unban_user_action}</a>
|
||||
<a n:if="$thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)" href="javascript:toggleBanInSupport()" class="button">
|
||||
{if $user->isBannedInSupport()}
|
||||
{_unban_in_support_user_action}
|
||||
{else}
|
||||
{_ban_in_support_user_action}
|
||||
{/if}
|
||||
</a>
|
||||
</p>
|
||||
</center>
|
||||
|
||||
<script n:if="isset($thisUser) && $thisUser->getChandlerUser()->can('access')->model('admin')->whichBelongsTo(NULL)">
|
||||
function unbanUser() {
|
||||
uUnbanMsgTxt = "Вы собираетесь разбанить пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uUnbanMsgTxt += "<br/>Сейчас он заблокирован по причине: <strong>" + {$user->getBanReason()} + "</strong>.";
|
||||
|
||||
MessageBox("Разбанить " + {$user->getFirstName()}, uUnbanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/unban/" + {$user->getId()} + "?hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось разблокировать пользователя...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь разблокирован", ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script n:if="isset($thisUser) && $thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)">
|
||||
{if $user->isBannedInSupport()}
|
||||
function toggleBanInSupport() {
|
||||
uBanMsgTxt = "Вы собираетесь разблокировать в поддержке пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/>Сейчас он заблокирован по причине <strong>" + {$user->getBanInSupportReason()} + "</strong>.";
|
||||
|
||||
MessageBox("Разблокировать в поддержке " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/support/unban/" + {$user->getId()} + "?hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось разблокировать пользователя в поддержке...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь разблокирован в поддержке", ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
{else}
|
||||
function toggleBanInSupport() {
|
||||
uBanMsgTxt = "Вы собираетесь заблокировать в поддержке пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/><br/><b>Причина бана</b>: <input type='text' id='uBanMsgInput' placeholder='придумайте что-нибудь крутое' />";
|
||||
|
||||
MessageBox("Заблокировать в поддержке " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
res = document.querySelector("#uBanMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/support/ban/" + {$user->getId()} + "?reason=" + res + "&hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось заблокировать пользователя в поддержке...", ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox("Операция успешна", "Пользователь заблокирован в поддержке", ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
{/if}
|
||||
</script>
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
{if !$attachment->isDeleted()}
|
||||
{var link = "/photo" . ($attachment->isAnonymous() ? ("s/" . base_convert((string) $attachment->getId(), 10, 32)) : $attachment->getPrettyId())}
|
||||
<a href="{$link}">
|
||||
<img class="media" src="{$attachment->getURL()}" alt="{$attachment->getDescription()}" />
|
||||
<img class="media" src="{$attachment->getURLBySizeId('normal')}" alt="{$attachment->getDescription()}" />
|
||||
</a>
|
||||
{else}
|
||||
<a href="javascript:alert('{_"attach_no_longer_available"}');">
|
||||
<img class="media" src="/assets/packages/static/openvk/img/camera_200.png" alt="{_"attach_no_longer_available"}" />
|
||||
<a href="javascript:alert('{_attach_no_longer_available}');">
|
||||
<img class="media" src="/assets/packages/static/openvk/img/camera_200.png" alt="{_attach_no_longer_available}" />
|
||||
</a>
|
||||
{/if}
|
||||
{elseif $attachment instanceof \openvk\Web\Models\Entities\Video}
|
||||
|
@ -14,12 +14,12 @@
|
|||
{elseif $attachment instanceof \openvk\Web\Models\Entities\Post}
|
||||
{php $GLOBALS["_nesAttGloCou"] = (isset($GLOBALS["_nesAttGloCou"]) ? $GLOBALS["_nesAttGloCou"] : 0) + 1}
|
||||
{if $GLOBALS["_nesAttGloCou"] > 2}
|
||||
<a href="/wall{$attachment->getPrettyId()}">{_"open_post"}</a>
|
||||
<a href="/wall{$attachment->getPrettyId()}">{_open_post}</a>
|
||||
{else}
|
||||
{include "post.xml", post => $attachment, compact => true}
|
||||
{/if}
|
||||
{else}
|
||||
<span style="color:red;">{_"version_incompatibility"}</span>
|
||||
<span style="color:red;">{_version_incompatibility}</span>
|
||||
{/if}
|
||||
|
||||
{php $GLOBALS["_nesAttGloCou"] = NULL}
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
<tr>
|
||||
<td width="30" valign="top">
|
||||
<a href="{$author->getURL()}">
|
||||
<img
|
||||
src="{$author->getAvatarURL()}"
|
||||
width="30"
|
||||
class="cCompactAvatars" />
|
||||
<img src="{$author->getAvatarURL('miniscule')}" width="30" class="cCompactAvatars" />
|
||||
</a>
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
|
@ -19,7 +16,7 @@
|
|||
<a href="{$author->getURL()}"><b>
|
||||
{$author->getCanonicalName()}
|
||||
</b></a>
|
||||
{if $author->isVerified()}<img class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png">{/if}<br/>
|
||||
<img n:if="$author->isVerified()" class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png"><br/>
|
||||
</div>
|
||||
<div class="post-content" id="{$comment->getId()}">
|
||||
<div class="text" id="text{$comment->getId()}">
|
||||
|
@ -34,9 +31,9 @@
|
|||
<div n:if="isset($thisUser) &&! ($compact ?? false)" class="post-menu">
|
||||
<a href="#_comment{$comment->getId()}" class="date">{$comment->getPublicationTime()}</a> |
|
||||
{if $comment->canBeDeletedBy($thisUser)}
|
||||
<a href="/comment{$comment->getId()}/delete">{_"delete"}</a> |
|
||||
<a href="/comment{$comment->getId()}/delete">{_delete}</a> |
|
||||
{/if}
|
||||
<a class="comment-reply">{_"reply"}</a>
|
||||
<a class="comment-reply">{_reply}</a>
|
||||
<div style="float: right; font-size: .7rem;">
|
||||
<a class="post-like-button" href="/comment{$comment->getId()}/like?hash={rawurlencode($csrfToken)}">
|
||||
<div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div>
|
||||
|
@ -45,7 +42,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h4 n:if="$showTitle ?? true">{_"comments"} ({$count})</h4>
|
||||
<h4 n:if="$showTitle ?? true">{_comments} ({$count})</h4>
|
||||
|
||||
<div n:ifset="$thisUser">
|
||||
{var commentsURL = "/al_comments/create/$model/" . $parent->getId()}
|
||||
|
@ -27,7 +27,7 @@
|
|||
{else}
|
||||
<p>Будьте первым кто оставит комментарий к этой дичи!</p>
|
||||
{/if} -->
|
||||
{_"comments_tip"}
|
||||
{_comments_tip}
|
||||
{/if}
|
||||
|
||||
{script "js/al_comments.js"}
|
||||
|
|
|
@ -3,16 +3,10 @@
|
|||
|
||||
<div n:if="!($conf->page === 1 && $conf->count <= $conf->perPage)" style="padding: 8px;">
|
||||
<div n:class="paginator, ($conf->atBottom ?? false) ? paginator-at-bottom">
|
||||
{if $conf->page > $space}
|
||||
<a n:attr="class => ($conf->page === 1 ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => 1]), 'k', '&', PHP_QUERY_RFC3986)}">«</a>
|
||||
{/if}
|
||||
<a n:if="$conf->page > $space" n:attr="class => ($conf->page === 1 ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => 1]), 'k', '&', PHP_QUERY_RFC3986)}">«</a>
|
||||
{for $j = $conf->page - ($space-1); $j <= $conf->page + ($space-1); $j++}
|
||||
{if $j > 0 && $j <= $pageCount}
|
||||
<a n:attr="class => ($conf->page === $j ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => $j]), 'k', '&', PHP_QUERY_RFC3986)}">{$j}</a>
|
||||
{/if}
|
||||
<a n:if="$j > 0 && $j <= $pageCount" n:attr="class => ($conf->page === $j ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => $j]), 'k', '&', PHP_QUERY_RFC3986)}">{$j}</a>
|
||||
{/for}
|
||||
{if $conf->page <= $pageCount-$space}
|
||||
<a n:attr="class => ($conf->page === $pageCount ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => $pageCount]), 'k', '&', PHP_QUERY_RFC3986)}">»</a>
|
||||
{/if}
|
||||
<a n:if="$conf->page <= $pageCount-$space" n:attr="class => ($conf->page === $pageCount ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => $pageCount]), 'k', '&', PHP_QUERY_RFC3986)}">»</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{var microblogEnabled = isset($thisUser) ? $thisUser->hasMicroblogEnabled() : false}
|
||||
{if !$post->isPostedOnBehalfOfGroup()}
|
||||
{var then = date_create("@" . $post->getOwner()->getOnline()->timestamp())}
|
||||
{var now = date_create()}
|
||||
{var diff = date_diff($now, $then)}
|
||||
{/if}
|
||||
|
||||
{if $microblogEnabled}
|
||||
{include "post/microblogpost.xml", post => $post, diff => $diff, commentSection => $commentSection}
|
||||
|
|
|
@ -9,25 +9,14 @@
|
|||
<tr>
|
||||
<td width="54" valign="top">
|
||||
<a href="{$author->getURL()}">
|
||||
<img
|
||||
src="{$author->getAvatarURL()}"
|
||||
width="{ifset $compact}25{else}50{/ifset}"
|
||||
{ifset $compact}class="cCompactAvatars"{/ifset} />
|
||||
{if !$post->isPostedOnBehalfOfGroup() && !$compact}
|
||||
<span n:if="$author->isOnline()" class="post-online">
|
||||
{_online}
|
||||
</span>
|
||||
{/if}
|
||||
<img src="{$author->getAvatarURL('miniscule')}" width="{ifset $compact}25{else}50{/ifset}" {ifset $compact}class="cCompactAvatars"{/ifset} />
|
||||
<span n:if="!$post->isPostedOnBehalfOfGroup() && !$compact && $author->isOnline()" class="post-online">{_online}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
<div class="post-author">
|
||||
<a href="{$author->getURL()}">
|
||||
<b>
|
||||
{$author->getCanonicalName()}
|
||||
</b>
|
||||
</a>
|
||||
{if $author->isVerified()}<img class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png">{/if}
|
||||
<a href="{$author->getURL()}"><b>{$author->getCanonicalName()}</b></a>
|
||||
<img n:if="$author->isVerified()" class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png">
|
||||
{if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()}
|
||||
{var wallId = $post->getTargetWall()}
|
||||
{var wallURL = $wallId > -1 ? "/id$wallId" : "/club" . abs($wallId)}
|
||||
|
@ -44,18 +33,17 @@
|
|||
</b>
|
||||
</a>
|
||||
{/if}
|
||||
{ifset $compact}<br>
|
||||
<a href="/wall{$post->getPrettyId()}" class="date">
|
||||
{$post->getPublicationTime()}
|
||||
</a>
|
||||
|
||||
{ifset $compact}
|
||||
<br>
|
||||
<a href="/wall{$post->getPrettyId()}" class="date">
|
||||
{$post->getPublicationTime()}
|
||||
</a>
|
||||
{/ifset}
|
||||
{if $post->isPinned()}
|
||||
<span class="nobold">{_pinned}</span>
|
||||
{/if}
|
||||
{if $post->canBeDeletedBy($thisUser) && !($forceNoDeleteLink ?? false) && !isset($compact)}
|
||||
<a class="delete" href="/wall{$post->getPrettyId()}/delete"></a>
|
||||
{/if}
|
||||
|
||||
<span n:if="$post->isPinned()" class="nobold">{_pinned}</span>
|
||||
|
||||
<a n:if="$post->canBeDeletedBy($thisUser) && !($forceNoDeleteLink ?? false) && !isset($compact)" class="delete" href="/wall{$post->getPrettyId()}/delete"></a>
|
||||
|
||||
{if $post->canBePinnedBy($thisUser) && !($forceNoPinLink ?? false) && !isset($compact)}
|
||||
{if $post->isPinned()}
|
||||
|
@ -80,11 +68,11 @@
|
|||
! Этот пост был размещён за взятку.
|
||||
</div>
|
||||
<div n:if="$post->isSigned()" class="post-signature">
|
||||
{var acutalAuthor = $post->getOwner(false)}
|
||||
{var actualAuthor = $post->getOwner(false)}
|
||||
<span>
|
||||
Автор:
|
||||
<a href="{$acutalAuthor->getURL()}">
|
||||
{$acutalAuthor->getCanonicalName()}
|
||||
{_author}:
|
||||
<a href="{$actualAuthor->getURL()}">
|
||||
{$actualAuthor->getCanonicalName()}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -94,26 +82,17 @@
|
|||
{if isset($thisUser)}
|
||||
|
||||
|
||||
{if !($forceNoCommentsLink ?? false)}
|
||||
<a n:if="$commentsCount == 0" href="javascript:expand_comment_textarea({$commentTextAreaId})">
|
||||
{_"comment"}
|
||||
</a>
|
||||
{/if}
|
||||
<a n:if="!($forceNoCommentsLink ?? false) && $commentsCount == 0" href="javascript:expand_comment_textarea({$commentTextAreaId})">{_comment}</a>
|
||||
|
||||
<div class="like_wrap">
|
||||
{if !($forceNoShareLink ?? false)}
|
||||
<a class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
|
||||
<div class="repost-icon" style="opacity: 0.4;"></div>
|
||||
<span class="likeCnt">{if $post->getRepostCount() > 0}{$post->getRepostCount()}{/if}</span>
|
||||
</a>
|
||||
{/if}
|
||||
<a n:if="!($forceNoShareLink ?? false)" class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
|
||||
<div class="repost-icon" style="opacity: 0.4;"></div>
|
||||
<span class="likeCnt">{if $post->getRepostCount() > 0}{$post->getRepostCount()}{/if}</span>
|
||||
</a>
|
||||
|
||||
{if !($forceNoLike ?? false)}
|
||||
{var liked = $post->hasLikeFrom($thisUser)}
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}"
|
||||
class="post-like-button"
|
||||
data-liked="{(int) $liked}"
|
||||
data-likes="{$post->getLikesCount()}">
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$post->getLikesCount()}">
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $post->getLikesCount() > 0}{$post->getLikesCount()}{/if}</span>
|
||||
</a>
|
||||
|
@ -121,21 +100,17 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{if !($forceNoCommentsLink ?? false)}
|
||||
<div n:if="$commentSection == true && $compact == false" class="post-menu-s">
|
||||
{if $commentsCount > 3}
|
||||
<a href="/wall{$post->getPrettyId()}" class="expand_button">{_view_other_comments}</a>
|
||||
{/if}
|
||||
{foreach $comments as $comment}
|
||||
{include "../comment.xml", comment => $comment, $compact => true}
|
||||
{/foreach}
|
||||
<div n:ifset="$thisUser" id="commentTextArea{$commentTextAreaId}" n:attr="style => ($commentsCount == 0 ? 'display: none;')" class="commentsTextFieldWrap">
|
||||
{var commentsURL = "/al_comments/create/posts/" . $post->getId()}
|
||||
{var club = is_null($club) ? ($post->getTargetWall() < 0 ? (new openvk\Web\Models\Repositories\Clubs)->get(abs($post->getTargetWall())) : NULL) : $club}
|
||||
{include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club}
|
||||
</div>
|
||||
<div n:if="!($forceNoCommentsLink ?? false) && $commentSection == true && $compact == false" class="post-menu-s">
|
||||
<a n:if="$commentsCount > 3" href="/wall{$post->getPrettyId()}" class="expand_button">{_view_other_comments}</a>
|
||||
{foreach $comments as $comment}
|
||||
{include "../comment.xml", comment => $comment, $compact => true}
|
||||
{/foreach}
|
||||
<div n:ifset="$thisUser" id="commentTextArea{$commentTextAreaId}" n:attr="style => ($commentsCount == 0 ? 'display: none;')" class="commentsTextFieldWrap">
|
||||
{var commentsURL = "/al_comments/create/posts/" . $post->getId()}
|
||||
{var club = is_null($club) ? ($post->getTargetWall() < 0 ? (new openvk\Web\Models\Repositories\Clubs)->get(abs($post->getTargetWall())) : NULL) : $club}
|
||||
{include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -5,26 +5,15 @@
|
|||
<tr>
|
||||
<td width="54" valign="top">
|
||||
<a href="{$author->getURL()}">
|
||||
<img
|
||||
src="{$author->getAvatarURL()}"
|
||||
width="50" />
|
||||
<img src="{$author->getAvatarURL('miniscule')}" width="50" />
|
||||
<span n:if="!$post->isPostedOnBehalfOfGroup() && !($compact ?? false) && $author->isOnline()" class="post-online">{_online}</span>
|
||||
</a>
|
||||
{if !$post->isPostedOnBehalfOfGroup() && !($compact ?? false)}
|
||||
<span n:if="$author->isOnline()" class="post-online">
|
||||
{_online}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
<div class="post-author">
|
||||
<a href="{$author->getURL()}">
|
||||
<b>
|
||||
{$author->getCanonicalName()}
|
||||
</b>
|
||||
</a>
|
||||
{if $author->isVerified()}<img class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png">{/if}
|
||||
{$post->isPostedOnBehalfOfGroup() ? "опубликовали" : ($author->isFemale() ? tr("post_writes_f") : tr("post_writes_m"))}
|
||||
<a href="{$author->getURL()}"><b>{$author->getCanonicalName()}</b></a>
|
||||
<img n:if="$author->isVerified()" class="name-checkmark" src="/assets/packages/static/openvk/img/checkmark.png">
|
||||
{$post->isPostedOnBehalfOfGroup() ? tr("post_writes_g") : ($author->isFemale() ? tr("post_writes_f") : tr("post_writes_m"))}
|
||||
{if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()}
|
||||
{var wallId = $post->getTargetWall()}
|
||||
{var wallURL = $wallId > -1 ? "/id$wallId" : "/club" . abs($wallId)}
|
||||
|
@ -43,10 +32,7 @@
|
|||
{/if}
|
||||
<br/>
|
||||
<a href="/wall{$post->getPrettyId()}" class="date">
|
||||
{$post->getPublicationTime()}
|
||||
{if $post->isPinned()}
|
||||
, {_pinned}
|
||||
{/if}
|
||||
{$post->getPublicationTime()}{if $post->isPinned()}, {_pinned}{/if}
|
||||
</a>
|
||||
</div>
|
||||
<div class="post-content" id="{$post->getPrettyId()}">
|
||||
|
@ -64,68 +50,54 @@
|
|||
! Этот пост был размещён за взятку.
|
||||
</div>
|
||||
<div n:if="$post->isSigned()" class="post-signature">
|
||||
{var acutalAuthor = $post->getOwner(false)}
|
||||
{var actualAuthor = $post->getOwner(false)}
|
||||
<span>
|
||||
Автор:
|
||||
<a href="{$acutalAuthor->getURL()}">
|
||||
{$acutalAuthor->getCanonicalName()}
|
||||
{_author}:
|
||||
<a href="{$actualAuthor->getURL()}">
|
||||
{$actualAuthor->getCanonicalName()}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div n:if="isset($thisUser) &&! ($compact ?? false)" class="post-menu">
|
||||
{if $post->canBeDeletedBy($thisUser) && !($forceNoDeleteLink ?? false)}
|
||||
<a href="/wall{$post->getPrettyId()}/delete">{_"delete"}</a> |
|
||||
<a href="/wall{$post->getPrettyId()}/delete">{_delete}</a> |
|
||||
{/if}
|
||||
|
||||
{if $post->canBePinnedBy($thisUser) && !($forceNoPinLink ?? false)}
|
||||
{if $post->isPinned()}
|
||||
<a href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}">{_unpin}</a> |
|
||||
<a href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}">{_unpin}</a>
|
||||
{else}
|
||||
<a href="/wall{$post->getPrettyId()}/pin?act=pin&hash={rawurlencode($csrfToken)}">{_pin}</a> |
|
||||
<a href="/wall{$post->getPrettyId()}/pin?act=pin&hash={rawurlencode($csrfToken)}">{_pin}</a>
|
||||
{/if}
|
||||
|
|
||||
{/if}
|
||||
|
||||
{if !($forceNoCommentsLink ?? false)}
|
||||
<a href="/wall{$post->getPrettyId()}#comments">
|
||||
{if $post->getCommentsCount() > 0}
|
||||
{_"comments"} (<b>{$post->getCommentsCount()}</b>)
|
||||
{else}
|
||||
{_"comments"}
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
<a n:if="!($forceNoCommentsLink ?? false)" href="/wall{$post->getPrettyId()}#comments">
|
||||
{_comments}
|
||||
{if $post->getCommentsCount() > 0}
|
||||
(<b>{$post->getCommentsCount()}</b>)
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
{if !($forceNoCommentsLink ?? false) && !($forceNoShareLink ?? false)}
|
||||
|
|
||||
{/if}
|
||||
|
||||
{if !($forceNoShareLink ?? false)}
|
||||
<a class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
|
||||
{if $post->getRepostCount() > 0}
|
||||
{_"share"}
|
||||
(<b>{$post->getRepostCount()}</b>)
|
||||
{else}
|
||||
{_"share"}
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
<a n:if="!($forceNoShareLink ?? false)" class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
|
||||
{_share}
|
||||
{if $post->getRepostCount() > 0}
|
||||
(<b>{$post->getRepostCount()}</b>)
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
{if !($forceNoLike ?? false)}
|
||||
<div class="like_wrap">
|
||||
{var liked = $post->hasLikeFrom($thisUser)}
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}"
|
||||
class="post-like-button"
|
||||
data-liked="{(int) $liked}"
|
||||
data-likes="{$post->getLikesCount()}">
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $post->getLikesCount() > 0}{$post->getLikesCount()}{/if}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div n:if="isset($thisUser) &&! ($compact ?? false)" class="post-menu-s">
|
||||
<!-- kosfurler -->
|
||||
<div n:if="!($forceNoLike ?? false)" class="like_wrap">
|
||||
{var liked = $post->hasLikeFrom($thisUser)}
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$post->getLikesCount()}">
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $post->getLikesCount() > 0}{$post->getLikesCount()}{/if}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -27,25 +27,25 @@
|
|||
</script>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" name="as_group" onchange="onWallAsGroupClick(this)" /> {_"post_as_group"}
|
||||
<input type="checkbox" name="as_group" onchange="onWallAsGroupClick(this)" /> {_post_as_group}
|
||||
</label>
|
||||
<label id="forceSignOpt" style="display: none;">
|
||||
<input type="checkbox" name="force_sign" /> {_"add_signature"}
|
||||
<input type="checkbox" name="force_sign" /> {_add_signature}
|
||||
</label>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<label n:if="$anonEnabled" id="octoberAnonOpt">
|
||||
<input type="checkbox" name="anon" /> {_"as_anonymous"}
|
||||
<input type="checkbox" name="anon" /> {_as_anonymous}
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" name="nsfw" /> {_"contains_nsfw"}
|
||||
<input type="checkbox" name="nsfw" /> {_contains_nsfw}
|
||||
</label>
|
||||
</div>
|
||||
<div n:if="!($postOpts ?? true) && !is_null($thisUser) && !is_null($club ?? NULL) && $club->canBeModifiedBy($thisUser)" class="post-opts">
|
||||
<label>
|
||||
<input type="checkbox" name="as_group" /> {_"comment_as_group"}
|
||||
<input type="checkbox" name="as_group" /> {_comment_as_group}
|
||||
</label>
|
||||
</div>
|
||||
<input type="file" class="postFileSel" id="postFilePic" name="_pic_attachment" accept="image/*" style="display:none;" />
|
||||
|
@ -53,7 +53,7 @@
|
|||
<input type="hidden" name="type" value="1" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<br/>
|
||||
<input type="submit" value="{_'write'}" class="button" />
|
||||
<input type="submit" value="{_write}" class="button" />
|
||||
<div style="float: right; display: flex; flex-direction: column;">
|
||||
<a href="javascript:void(u('#post-buttons{$textAreaId} #wallAttachmentMenu').toggleClass('hidden'));">
|
||||
{_attach}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="content_divider">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this);">
|
||||
{_"wall"}
|
||||
{_wall}
|
||||
<nobold>
|
||||
{tr("wall", $count)}
|
||||
<a href="/wall{$owner}" class="float-right lowercase">{_all_title}</a>
|
||||
{tr("wall", $count)}
|
||||
<a href="/wall{$owner}" class="float-right lowercase">{_all_title}</a>
|
||||
</nobold>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -271,16 +271,24 @@ routes:
|
|||
handler: "Admin->gifts"
|
||||
- url: "/admin/ban/{num}"
|
||||
handler: "Admin->quickBan"
|
||||
- url: "/admin/unban/{num}"
|
||||
handler: "Admin->quickUnban"
|
||||
- url: "/admin/warn/{num}"
|
||||
handler: "Admin->quickWarn"
|
||||
- url: "/support/reports"
|
||||
- url: "/admin/support/ban/{num}"
|
||||
handler: "Support->quickBanInSupport"
|
||||
- url: "/admin/support/unban/{num}"
|
||||
handler: "Support->quickUnbanInSupport"
|
||||
- url: "/admin/support/reports"
|
||||
handler: "Report->list"
|
||||
- url: "/support/report{num}"
|
||||
- url: "/admin/support/report{num}"
|
||||
handler: "Report->view"
|
||||
- url: "/support/reportAction{num}"
|
||||
- url: "/admin/support/reportAction{num}"
|
||||
handler: "Report->action"
|
||||
- url: "/report/{num}"
|
||||
handler: "Report->create"
|
||||
- url: "/upload/photo/{text}"
|
||||
handler: "VKAPI->photoUpload"
|
||||
- url: "/method/{text}.{text}"
|
||||
handler: "VKAPI->route"
|
||||
- url: "/token"
|
||||
|
|
|
@ -360,7 +360,7 @@ p {
|
|||
}
|
||||
|
||||
.page_footer {
|
||||
margin-left: 95px;
|
||||
margin-left: 130px;
|
||||
padding-top: 5px;
|
||||
clear: both;
|
||||
text-align: center;
|
||||
|
@ -1334,6 +1334,15 @@ body.scrolled .toTop:hover {
|
|||
font-size: 15px;
|
||||
}
|
||||
|
||||
#test-label {
|
||||
padding: 8pt;
|
||||
margin: 4pt;
|
||||
border: 1px solid #9a205e;
|
||||
background-color: #f5e9ec;
|
||||
position: fixed;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.post-upload {
|
||||
margin-top: 11px;
|
||||
margin-left: 3px;
|
||||
|
@ -1912,6 +1921,7 @@ table td[width="120"] {
|
|||
width: 50px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mb_tabs {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"react-dom-factories": "^1.0.2",
|
||||
"requirejs": "^2.3.6",
|
||||
"soundjs": "^1.0.1",
|
||||
"textfit": "^2.4.0",
|
||||
"umbrellajs": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,6 +271,11 @@ soundjs@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/soundjs/-/soundjs-1.0.1.tgz#99970542d28d0df2a1ebd061ae75c961a98c8180"
|
||||
integrity sha512-MgFPvmKYfpcNiE3X5XybNvScie3DMQlZgmNzUn4puBcpw64f4LqjH/fhM8Sb/eTJ8hK57Crr7mWy0bfJOqPj6Q==
|
||||
|
||||
textfit@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/textfit/-/textfit-2.4.0.tgz#80cba8006bfb9c3d9d552739257957bdda95c79c"
|
||||
integrity sha512-/x4aoY5+/tJmu+iwpBH1yw75TFp86M6X15SvaaY/Eep7YySQYtqdOifEtfvVyMwzl7SZ+G4RQw00FD9g5R6i1Q==
|
||||
|
||||
trim-extra-html-whitespace@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/trim-extra-html-whitespace/-/trim-extra-html-whitespace-1.3.0.tgz#b47efb0d1a5f2a56a85cc45cea525651e93404cf"
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
"chillerlan/php-qrcode": "dev-main",
|
||||
"vearutop/php-obscene-censor-rus": "dev-master",
|
||||
"erusev/parsedown": "dev-master",
|
||||
"bhaktaraz/php-rss-generator": "dev-master"
|
||||
"bhaktaraz/php-rss-generator": "dev-master",
|
||||
"ext-simplexml": "*",
|
||||
"symfony/console": "5.4.x-dev"
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
804
composer.lock
generated
804
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2c94032cae911ca438bbcfc46c346961",
|
||||
"content-hash": "878bd996183ccbb15637a7399ba03ab9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "al/emoji-detector",
|
||||
|
@ -852,6 +852,54 @@
|
|||
},
|
||||
"time": "2016-08-06T20:24:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/container/issues",
|
||||
"source": "https://github.com/php-fig/container/tree/1.1.2"
|
||||
},
|
||||
"time": "2021-11-05T16:50:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "dev-master",
|
||||
|
@ -1085,6 +1133,336 @@
|
|||
},
|
||||
"time": "2022-01-06T19:41:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "5.4.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/900275254f0a1a2afff1ab0e11abd5587a10e1d6",
|
||||
"reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/service-contracts": "^1.1|^2|^3",
|
||||
"symfony/string": "^5.1|^6.0"
|
||||
},
|
||||
"conflict": {
|
||||
"psr/log": ">=3",
|
||||
"symfony/dependency-injection": "<4.4",
|
||||
"symfony/dotenv": "<5.1",
|
||||
"symfony/event-dispatcher": "<4.4",
|
||||
"symfony/lock": "<4.4",
|
||||
"symfony/process": "<4.4"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0|2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "^1|^2",
|
||||
"symfony/config": "^4.4|^5.0|^6.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.0|^6.0",
|
||||
"symfony/event-dispatcher": "^4.4|^5.0|^6.0",
|
||||
"symfony/lock": "^4.4|^5.0|^6.0",
|
||||
"symfony/process": "^4.4|^5.0|^6.0",
|
||||
"symfony/var-dumper": "^4.4|^5.0|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "For using the console logger",
|
||||
"symfony/event-dispatcher": "",
|
||||
"symfony/lock": "",
|
||||
"symfony/process": ""
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Console\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Eases the creation of beautiful and testable command line interfaces",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"command line",
|
||||
"console",
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-31T17:09:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "2.5.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:53:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-10-20T20:35:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-grapheme",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||
"reference": "81b86b50cf841a64252b439e738e97f4a34e2783"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783",
|
||||
"reference": "81b86b50cf841a64252b439e738e97f4a34e2783",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Intl\\Grapheme\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for intl's grapheme_* functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"grapheme",
|
||||
"intl",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-23T21:10:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.24.0",
|
||||
|
@ -1256,6 +1634,89 @@
|
|||
],
|
||||
"time": "2021-02-19T12:13:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-30T18:21:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.24.0",
|
||||
|
@ -1332,6 +1793,338 @@
|
|||
],
|
||||
"time": "2021-05-27T09:17:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php73",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||
"reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5",
|
||||
"reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php73\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-05T21:20:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
|
||||
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-04T08:16:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "2.5.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/24d9dc654b83e91aa59f9d167b131bc3b5bea24c",
|
||||
"reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/service-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-13T20:07:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "5.4.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "92043b7d8383e48104e411bc9434b260dbeb5a10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10",
|
||||
"reference": "92043b7d8383e48104e411bc9434b260dbeb5a10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-intl-grapheme": "~1.0",
|
||||
"symfony/polyfill-intl-normalizer": "~1.0",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php80": "~1.15"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/translation-contracts": ">=3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/error-handler": "^4.4|^5.0|^6.0",
|
||||
"symfony/http-client": "^4.4|^5.0|^6.0",
|
||||
"symfony/translation-contracts": "^1.1|^2",
|
||||
"symfony/var-exporter": "^4.4|^5.0|^6.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\String\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"grapheme",
|
||||
"i18n",
|
||||
"string",
|
||||
"unicode",
|
||||
"utf-8",
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v5.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:53:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vearutop/php-obscene-censor-rus",
|
||||
"version": "dev-master",
|
||||
|
@ -1562,11 +2355,14 @@
|
|||
"chillerlan/php-qrcode": 20,
|
||||
"vearutop/php-obscene-censor-rus": 20,
|
||||
"erusev/parsedown": 20,
|
||||
"bhaktaraz/php-rss-generator": 20
|
||||
"bhaktaraz/php-rss-generator": 20,
|
||||
"symfony/console": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform": {
|
||||
"ext-simplexml": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.0.0"
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
|
13
data/photosizes.xml
Normal file
13
data/photosizes.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PhotoSizes name="standard">
|
||||
<Size id="miniscule" vkId="s" maxSize="75" requireProp="none" />
|
||||
<Size id="tiny" vkId="m" maxSize="130" requireProp="none" />
|
||||
<Size id="tinier" vkId="o" maxSize="130" requireProp="3:2" />
|
||||
<Size id="xsmall" vkId="p" maxSize="200" requireProp="3:2" />
|
||||
<Size id="small" vkId="q" maxSize="320" requireProp="3:2" />
|
||||
<Size id="medium" vkId="r" maxSize="510" requireProp="3:2" />
|
||||
<Size id="normal" vkId="x" maxSize="604" requireProp="none" />
|
||||
<Size id="large" vkId="y" maxSize="807" requireProp="none" />
|
||||
<Size id="larger" vkId="z" maxResolution="1080x1024" requireProp="none" />
|
||||
<Size id="original" vkId="w" maxResolution="2560x2048" requireProp="none" />
|
||||
</PhotoSizes>
|
1
install/sqls/00019-block-in-support.sql
Normal file
1
install/sqls/00019-block-in-support.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `profiles` ADD COLUMN `block_in_support_reason` text COLLATE utf8mb4_unicode_520_ci DEFAULT NULL AFTER `block_reason`;
|
3
install/sqls/00020-image-sizes.sql
Normal file
3
install/sqls/00020-image-sizes.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE `photos` ROW_FORMAT=COMPRESSED;
|
||||
ALTER TABLE `photos` ADD COLUMN `sizes` VARBINARY(486) NULL DEFAULT NULL AFTER `hash`;
|
||||
ALTER TABLE `photos` ADD COLUMN `width` SMALLINT UNSIGNED NULL DEFAULT NULL AFTER `sizes`, ADD COLUMN `height` SMALLINT UNSIGNED NULL DEFAULT NULL AFTER `sizes`;
|
|
@ -693,6 +693,9 @@
|
|||
"ticket_changed" = "Ticket changed";
|
||||
"ticket_changed_comment" = "The changes will take effect in a few seconds.";
|
||||
|
||||
"banned_in_support_1" = "Sorry, <b>$1</b>, but now you can't create tickets.";
|
||||
"banned_in_support_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to take away this opportunity from you forever.";
|
||||
|
||||
/* Invite */
|
||||
|
||||
"invite" = "Invite";
|
||||
|
@ -836,7 +839,10 @@
|
|||
"manage_user_action" = "Manage user";
|
||||
"manage_group_action" = "Manage group";
|
||||
"ban_user_action" = "Ban user";
|
||||
"unban_user_action" = "Unban user";
|
||||
"warn_user_action" = "Warn user";
|
||||
"ban_in_support_user_action" = "Ban in support";
|
||||
"unban_in_support_user_action" = "Unban in support";
|
||||
|
||||
/* Paginator (deprecated) */
|
||||
|
||||
|
|
|
@ -398,7 +398,7 @@
|
|||
|
||||
"default" = "әдепкі";
|
||||
|
||||
"arbitrary_avatars" = "Ерікті"
|
||||
"arbitrary_avatars" = "Ерікті";
|
||||
"cut" = "Шаршы";
|
||||
"round_avatars" = "Дөңгелек";
|
||||
|
||||
|
|
|
@ -730,6 +730,9 @@
|
|||
"ticket_changed" = "Тикет изменён";
|
||||
"ticket_changed_comment" = "Изменения вступят силу через несколько секунд.";
|
||||
|
||||
"banned_in_support_1" = "Извините, <b>$1</b>, но теперь вам нельзя создавать обращения.";
|
||||
"banned_in_support_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось отобрать у вас эту возможность навсегда.";
|
||||
|
||||
/* Invite */
|
||||
|
||||
"invite" = "Пригласить";
|
||||
|
@ -879,7 +882,10 @@
|
|||
"manage_user_action" = "Управление пользователем";
|
||||
"manage_group_action" = "Управление группой";
|
||||
"ban_user_action" = "Заблокировать пользователя";
|
||||
"unban_user_action" = "Разблокировать пользователя";
|
||||
"warn_user_action" = "Предупредить пользователя";
|
||||
"ban_in_support_user_action" = "Заблокировать в поддержке";
|
||||
"unban_in_support_user_action" = "Разблокировать в поддержке";
|
||||
|
||||
/* Paginator (deprecated) */
|
||||
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
"hidden_yes" = "Скрыт: Да";
|
||||
"hidden_no" = "Скрыт: Нет";
|
||||
"group_allow_post_for_everyone" = "Разрешить публиковать записи всем";
|
||||
"group_hide_from_global_feed" = "Не отображать записи в публичной доске";
|
||||
"statistics" = "Статистика";
|
||||
"group_administrators_list" = "Список админов";
|
||||
"group_display_only_creator" = "Отображать только создателя группы";
|
||||
|
@ -430,7 +431,7 @@
|
|||
"ui_settings_rating_hide" = "Скрывать";
|
||||
|
||||
"additional_links" = "Дополнительные ссылки";
|
||||
|
||||
"ad_poster" = "Рекламный плакат";
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Двухфакторная аутентификация";
|
||||
|
@ -609,6 +610,21 @@
|
|||
|
||||
/* Support */
|
||||
|
||||
"increase_rating" = "Увеличить рейтинг";
|
||||
"increase_rating_button" = "Увеличить";
|
||||
"to_whom" = "Кому";
|
||||
"increase_by" = "Увеличить на";
|
||||
"price" = "Ценник";
|
||||
|
||||
"you_have_unused_votes" = "У Вас $1 неиспользованных рубля на кошельке.";
|
||||
"apply_voucher" = "Применить купон";
|
||||
|
||||
"failed_to_increase_rating" = "Не удалось увеличить рейтинг";
|
||||
"rating_increase_successful" = "Вы успешно увеличили рейтинг <b><a href=\"$1\">$2</a></b> на <b>$3%</b>.";
|
||||
"negative_rating_value" = "Орган не может украсть баллы рейтинга у другого гражданина, так не положено.";
|
||||
|
||||
"increased_your_rating_by" = "увеличил ваш рейтинг на";
|
||||
|
||||
"support_opened" = "Открытые";
|
||||
"support_answered" = "С ответом";
|
||||
"support_closed" = "Закрытые";
|
||||
|
@ -759,7 +775,7 @@
|
|||
"token_manipulation_error" = "Ошибка манипулирования токеном";
|
||||
"token_manipulation_error_comment" = "Токен недействителен или истёк";
|
||||
|
||||
"profile_changed" = "Досье изменёно";
|
||||
"profile_changed" = "Досье изменено";
|
||||
"profile_changed_comment" = "Товарищ, орган одобрил изменение вашего досье.";
|
||||
"profile_not_found" = "Гражданин не найден.";
|
||||
|
||||
|
@ -795,6 +811,36 @@
|
|||
/* About */
|
||||
|
||||
"about_openvk" = "Об органе OpenVK";
|
||||
"footer_about_instance" = "о стране";
|
||||
"about_this_instance" = "Об этой стране";
|
||||
"rules" = "Правила";
|
||||
"most_popular_groups" = "Самые популярные клубы";
|
||||
"on_this_instance_are" = "На этой стране";
|
||||
|
||||
"about_users_one" = "<b>1</b> гражданин";
|
||||
"about_users_few" = "<b>$1</b> гражданина";
|
||||
"about_users_many" = "<b>$1</b> гражданинов";
|
||||
"about_users_other" = "<b>$1</b> гражданинов";
|
||||
|
||||
"about_online_users_one" = "<b>1</b> пользователь в сети";
|
||||
"about_online_users_few" = "<b>$1</b> пользователя в сети";
|
||||
"about_online_users_many" = "<b>$1</b> гражданинов в сети";
|
||||
"about_online_users_other" = "<b>$1</b> гражданинов в сети";
|
||||
|
||||
"about_active_users_one" = "<b>1</b> активный пользователь";
|
||||
"about_active_users_few" = "<b>$1</b> активных пользователя";
|
||||
"about_active_users_many" = "<b>$1</b> активных гражданинов";
|
||||
"about_active_users_other" = "<b>$1</b> активных гражданинов";
|
||||
|
||||
"about_groups_one" = "<b>1</b> клуб";
|
||||
"about_groups_few" = "<b>$1</b> клубы";
|
||||
"about_groups_many" = "<b>$1</b> клубов";
|
||||
"about_groups_other" = "<b>$1</b> клубов";
|
||||
|
||||
"about_wall_posts_one" = "<b>1</b> заметка на досках";
|
||||
"about_wall_posts_few" = "<b>$1</b> заметки на досках";
|
||||
"about_wall_posts_many" = "<b>$1</b> заметки на досках";
|
||||
"about_wall_posts_other" = "<b>$1</b> заметки на досках";
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
|
@ -810,5 +856,20 @@
|
|||
"question_confirm" = "Товарищ, будьте внимательны с выбором. Вы согласны с вашим выбором? Отменить не представляется возможным.";
|
||||
|
||||
/* User alerts */
|
||||
"apply_style_for_this_device" = "Применить стиль только для этой ЭВМ";
|
||||
|
||||
"user_alert_scam" = "Органу управления было дозволено, что данный гражданин обманывает товарищей на денежные средства. Будьте осторожны при разговоре с ним.";
|
||||
|
||||
|
||||
"ec_header" = "Подтверждение регистрации прописки";
|
||||
"ec_title" = "Спасибо!";
|
||||
"ec_1" = "<b>$1</b>, на ваш почтовый ящик должно придти письмо с подтверждением регистрации.";
|
||||
"ec_2" = "Если по каким-то причинам вам не пришло письмо, то проверьте мусорный бак. Если письма не окажется и там, то вы можете переотправить письмо.";
|
||||
"ec_resend" = "Переотправить письмо";
|
||||
|
||||
"email_sent" = "Письмо было успешно отправлено.";
|
||||
"email_sent_desc" = "Если ваш почтовый ящик существует, вы получите письмо.";
|
||||
"email_error" = "Непредвиденная ошибка при отправке письма.";
|
||||
"email_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
||||
|
||||
"email_verify_success" = "Ваша регистрация была подтверждена. Приятного времяпрепровождения!";
|
|
@ -6,13 +6,19 @@ openvk:
|
|||
|
||||
preferences:
|
||||
femaleGenderPriority: true
|
||||
nginxCacheTime: null
|
||||
uploads:
|
||||
disableLargeUploads: false
|
||||
mode: "basic"
|
||||
api:
|
||||
maxFilesPerDomain: 10
|
||||
maxFileSize: 25000000
|
||||
shortcodes:
|
||||
minLength: 3 # won't affect existing short urls or the ones set via admin panel
|
||||
forbiddenNames:
|
||||
- "index.php"
|
||||
photos:
|
||||
upgradeStructure: true
|
||||
security:
|
||||
requireEmail: false
|
||||
requirePhone: false
|
||||
|
@ -66,6 +72,15 @@ openvk:
|
|||
enable: false
|
||||
domain: ""
|
||||
server: ""
|
||||
piwik:
|
||||
enable: false
|
||||
container: ""
|
||||
site: ""
|
||||
layer: "dataLayer"
|
||||
matomo:
|
||||
enable: false
|
||||
container: ""
|
||||
site: ""
|
||||
|
||||
credentials:
|
||||
smsc:
|
||||
|
|
13
openvkctl
Executable file
13
openvkctl
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env php
|
||||
<?php declare(strict_types=1);
|
||||
namespace openvk;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = false;
|
||||
$bootstrap = require(__DIR__ . "/../../../chandler/Bootstrap.php");
|
||||
$bootstrap->ignite(true);
|
||||
|
||||
$application = new Application();
|
||||
$application->add(new CLI\RebuildImagesCommand);
|
||||
|
||||
$application->run();
|
0
tmp/api-storage/photos/.gitkeep
Normal file
0
tmp/api-storage/photos/.gitkeep
Normal file
0
tmp/api-storage/videos/.gitkeep
Normal file
0
tmp/api-storage/videos/.gitkeep
Normal file
Loading…
Reference in a new issue